1

I have an RTF file that I am reading in using a command line application in Objective-C. I'm using Dave DeLong's code from this question: How to read data from NSFileHandle line by line?

My problem is that my output is coming out like this:

    2014-06-21 20:03:45.578 AjrumTest[5663:303] {\rtf1\ansi\ansicpg1252\cocoartf1265\cocoasubrtf200
    2014-06-21 20:03:45.579 AjrumTest[5663:303] {\fonttbl\f0\fnil\fcharset0 LucidaGrande;\f1\fnil\fcharset178 AlBayan;\f2\froman\fcharset0 TimesNewRomanPSMT;
    2014-06-21 20:03:45.580 AjrumTest[5663:303] \f3\fnil\fcharset178 GeezaPro;}
    2014-06-21 20:03:45.580 AjrumTest[5663:303] {\colortbl;\red255\green255\blue255;}
    2014-06-21 20:03:45.581 AjrumTest[5663:303] \margl1440\margr1440\vieww10800\viewh8400\viewkind0
    2014-06-21 20:03:45.581 AjrumTest[5663:303] \deftab720
    2014-06-21 20:03:45.581 AjrumTest[5663:303] \pard\pardeftab720
    2014-06-21 20:03:45.582 AjrumTest[5663:303] 
    2014-06-21 20:03:45.582 AjrumTest[5663:303] \f0\fs46 \cf0 1
    2014-06-21 20:03:45.582 AjrumTest[5663:303] \f1 - \'de\'f3\'dc\'c7\'e1\'f3 \'c7\'c8\'fa\'dc\'e4\'f5 \'c2\'c8\'f3\'f8 \'e6\'f3\'c7\'d3\'fa\'e3\'f5\'dc\'e5\'f5 \'e3\'f5\'cd\'f3\'e3\'f3\'f8\'dc\'cf\'f5
...

I realize that because the document I am reading in is an RTF file, that I need to attach the necessary attributes to it. I pass in my file from the main method like this:

        NSString *pathToMyFile = [[NSBundle mainBundle] pathForResource:@"MyRTFDocument" ofType:@"rtf"];
        DDFileReader * reader = [[DDFileReader alloc] initWithFilePath:pathToMyFile];
        [reader enumerateLinesUsingBlock:^(NSString *line, BOOL *stop) {
            NSLog(@"%@", line);
        }];

Here is how the document is then parsed:

- (NSString *) readLine {
    if (currentOffset >= totalFileLength) {
        return nil;
    }
    NSData *newLineData = [lineDelimiter dataUsingEncoding:NSUTF8StringEncoding];
    [fileHandle seekToFileOffset:currentOffset];
    NSMutableData * currentData = [[NSMutableData alloc] init];
    BOOL shouldReadMore = YES;

    @autoreleasepool {

        while (shouldReadMore) {
            if (currentOffset >= totalFileLength) {
                break;
            }
            NSData *chunk = [fileHandle readDataOfLength:chunkSize];
            NSRange newLineRange = [chunk rangeOfData_dd:newLineData];
            if (newLineRange.location != NSNotFound) {

                //include the length so we can include the delimiter in the string
                chunk = [chunk subdataWithRange:NSMakeRange(0, newLineRange.location+[newLineData length])];
                shouldReadMore = NO;
            }
            [currentData appendData:chunk];
            currentOffset += [chunk length];
        }
    }

    NSDictionary *attrs = @{NSDocumentTypeDocumentAttribute: NSRTFTextDocumentType, NSWritingDirectionAttributeName:@[@(NSWritingDirectionRightToLeft | NSTextWritingDirectionOverride)]};

    NSAttributedString *attrString = [[NSAttributedString alloc] initWithData:currentData options:attrs documentAttributes:nil error:nil];

    //NSLog(@"What does this give me? %@", [attrString string]);
    //The above line outputs (null) for [attrString string]
    NSString *line = [[NSString alloc] initWithData:currentData encoding:NSUTF8StringEncoding];
    return line;

}

- (NSString *) readTrimmedLine {
    return [[self readLine] stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]];
}

#if NS_BLOCKS_AVAILABLE
- (void) enumerateLinesUsingBlock:(void(^)(NSString*, BOOL*))block {
    NSString *line = nil;
    BOOL stop = NO;
    while (stop == NO && (line = [self readLine])) {
        block(line, &stop);
    }
}
#endif

When I attach the correct document attributes to the NSData object before creating an NSAttributedString, I get an object that is null:

NSDictionary *attrs = @{NSDocumentTypeDocumentAttribute: NSRTFTextDocumentType, NSWritingDirectionAttributeName:@[@(NSWritingDirectionRightToLeft | NSTextWritingDirectionOverride)]};
NSAttributedString *attrString = [[NSAttributedString alloc] initWithData:currentData options:attrs documentAttributes:nil error:nil];
NSLog(@"%@", [attrString string]);

In another iOS application, I have the following code which works exactly as I want:

NSString *path = [[NSBundle mainBundle] pathForResource:@"AjrumiyyahPoemRawTextRTF" ofType:@"rtf"];
NSData *testData = [NSData dataWithContentsOfFile:path];
NSDictionary *attrs = @{NSDocumentTypeDocumentAttribute: NSRTFTextDocumentType, NSWritingDirectionAttributeName:@[@(NSWritingDirectionRightToLeft | NSTextWritingDirectionOverride)]};
NSAttributedString *attrString = [[NSAttributedString alloc] initWithData:testData options:attrs documentAttributes:nil error:nil];
NSLog(@"The text of the document is: %@", [attrString string]);

What it is that I need to do to the command line application to attach the document attributes to the NSAttributedString object correctly so that the output is correct?

halfer
  • 19,824
  • 17
  • 99
  • 186
syedfa
  • 2,801
  • 1
  • 41
  • 74

1 Answers1

0

I don't have an immediate answer, but with regards to this line of code:

NSAttributedString *attrString = [[NSAttributedString alloc] initWithData:currentData options:attrs documentAttributes:nil error:nil];

You should use the error variable to figure out why the result is null / nil. So instead write something like the following:

NSError *error = nil;
NSAttributedString *attrString = [[NSAttributedString alloc] initWithData:currentData options:attrs documentAttributes:nil error:&error];

If (attrString == nil) // parsing failed, so read out error
{
    NSLog(@"%@", error);
}

Perhaps this will help you figure out what goes wrong.

Wolfgang Schreurs
  • 11,779
  • 7
  • 51
  • 92
  • Thanks so much for your suggestion. The error message I am getting is: Error Domain=NSCocoaErrorDomain Code=256 "The file couldn’t be opened." – syedfa Jun 22 '14 at 00:59
  • You should make sure the path is correct. Perhaps the file could not be opened because the path is wrong. – Wolfgang Schreurs Jun 22 '14 at 01:22
  • The document is not coming from a url but is included in the application as a separate file. The fact that I am getting formatting data via the NSLog tells me that it is reading the file in question. – syedfa Jun 22 '14 at 01:24
  • Perhaps you could put the RTF file you try to read on some public location so I can try for myself? – Wolfgang Schreurs Jun 22 '14 at 08:37
  • Thanks so much for your help. Here it is: https://www.dropbox.com/s/y7konbnkcj6ha6q/AjrumiyyahPoemRawTextRTF.rtf – syedfa Jun 22 '14 at 16:39