danest
danest

Reputation: 11

How to read the content of a text file in an iOS tweak

inside an iOS tweak, I have a long text and store it in a text file at the same folder level with .xm file. Let's say I have a tweak project with a Tweak.xm file at the top level of the project, and another file called myFile.txt placed at the same folder level as Tweak.xm. How do I read the content of this txt file in the xm code?

I tried this Objective-C code but an error came up as the file path may not be correct.

NSString *filePath = [[NSBundle mainBundle] pathForResource:@"myFile" ofType:@"txt"];
NSError *error = nil;
NSString *fileContent = [NSString stringWithContentsOfFile:filePath
                                                  encoding:NSUTF8StringEncoding
                                                     error:&error];

if (error) {
    NSLog(@"Error reading file: %@", error);
    NSLog(@"File Path: %@", filePath);
    // the log error is `Error reading file: Error Domain=NSCocoaErrorDomain Code=258 "The file name is invalid."`
} else {
    NSLog(@"File Content:\n%@", fileContent);

    
}

Upvotes: 0

Views: 155

Answers (1)

Cryptic
Cryptic

Reputation: 1

I did a little redesign but it should work correctly for your purposes.

Example Code:

NSError *error = nil;

// Open the file and create it if it doesn't exist
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths firstObject];
NSString *filePath = [NSString stringWithFormat:@"%@/myFile.txt", documentsDirectory];
NSFileHandle *fileHandle = [NSFileHandle fileHandleForWritingAtPath:filePath];

if (fileHandle == nil) {
    [[NSFileManager defaultManager] createFileAtPath:filePath contents:nil attributes:nil];
}

// Open the output stream
NSOutputStream *outputStream = [NSOutputStream outputStreamToFileAtPath:filePath append:YES];
[outputStream open];

// Open the input stream
NSInputStream *inputStream = [NSInputStream inputStreamWithFileAtPath:filePath];
[inputStream open];

// What you are writing
NSString *printString = [NSString stringWithFormat:@"Hello Logos\n"];

// Write to file
[fileHandle seekToEndOfFile];
NSData *contentData = [printString dataUsingEncoding:NSUTF8StringEncoding];
[outputStream write:contentData.bytes maxLength:contentData.length];

// Read from file
size_t fileSize = [[[NSFileManager defaultManager] attributesOfItemAtPath:filePath error:&error] fileSize];
if(error) {
    NSLog(@"Error reading file: %@", error);
    return;
}
NSMutableData* data = [NSMutableData dataWithLength:fileSize];
size_t result = [inputStream read:(uint8_t *)data.bytes maxLength:fileSize];
if(result != fileSize) {
    NSLog(@"Failed to read %zu bytes, only read %zu!", fileSize, result);
}
NSLog(@"%@: contains:\n%@", filePath, [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding]);

Test run:

❯ xcrun clang -arch x86_64 -isysroot $(xcrun --sdk macosx --show-sdk-path) -O3 -DNDEBUG test.m -o test -framework Foundation

/var/folders/x2/gjkg0qk92j92svxfk1x1cn100000gn/T
❯ rm ~/Documents/myFile.txt
rm: cannot remove '/Users/cryptic/Documents/myFile.txt': No such file or directory

/var/folders/x2/gjkg0qk92j92svxfk1x1cn100000gn/T
❯ ./test
2023-08-27 19:48:23.654 test[2318:1592365] /Users/cryptic/Documents/myFile.txt: contains:
Hello Logos

/var/folders/x2/gjkg0qk92j92svxfk1x1cn100000gn/T
❯ ./test
2023-08-27 19:48:24.381 test[2361:1592410] /Users/cryptic/Documents/myFile.txt: contains:
Hello Logos
Hello Logos

/var/folders/x2/gjkg0qk92j92svxfk1x1cn100000gn/T
❯ ./test
2023-08-27 19:48:25.304 test[2387:1592456] /Users/cryptic/Documents/myFile.txt: contains:
Hello Logos
Hello Logos
Hello Logos

/var/folders/x2/gjkg0qk92j92svxfk1x1cn100000gn/T
❯

Upvotes: 0

Related Questions