Question

Is there any reason why writing and saving a PDF file to the Documents directory in an iOS application would only be intermittently successful? In my app I am created a PDF from an array of UIViews, accessing the Documents folder and storing the file in there.

I would estimate that this works 80% of the time. The other 20% of the time the PDF gets created (I also email it to myself which works) but it never actually get written to the Documents folder.

In the case of failure, I can email myself the PDF so I know it gets created. When I inspect the Documents folder in a file explorer it's empty. When I log out the contents of it it is also empty. I'm using the following code to create the PDF and export to Documents.

- (NSURL *)applicationDocumentsDirectory
{
    return [[[NSFileManager defaultManager] URLsForDirectory:NSDocumentDirectory inDomains:NSUserDomainMask] lastObject];
}

-(void)createPDFfromUIViews:(NSArray *)views saveToDocumentsWithFileName:(NSString*)aFilename andTag:(NSInteger)tag
{
    // Creates a mutable data object for updating with binary data, like a byte array
    NSMutableData *pdfData = [NSMutableData data];

    // Points the pdf converter to the mutable data object and to the UIView to be converted
    UIView *view1 = [views objectAtIndex:0];
    UIGraphicsBeginPDFContextToData(pdfData, view1.bounds, nil);
    CGContextRef pdfContext = UIGraphicsGetCurrentContext();

    // draws rect to the view and thus this is captured by UIGraphicsBeginPDFContextToData
    for (UIView *view in views)
    {
        UIGraphicsBeginPDFPage();
        [view.layer renderInContext:pdfContext];
    }

    // remove PDF rendering context
    UIGraphicsEndPDFContext();

    // Get the path to the documents directory and append the filename of the PDF
    NSString *path = [[self applicationDocumentsDirectory].path stringByAppendingPathComponent:aFilename];

    NSLog (@"DOCUMENTS DIRECTORY : %@", [self applicationDocumentsDirectory].path);
    NSLog (@"DOCUMENTS DIRECTORY WITH FILE PATH : %@", path);

    NSError *error = nil;
    BOOL success = [pdfData writeToFile:path options:NSDataWritingWithoutOverwriting error:&error];

    if (!success)
    {
        NSLog(@"Error writing PDF: %@", [error localizedDescription]);
    }
    else
    {
        if (tag == 1)
        {
            NSLog(@"PDF Saved With Name %@", aFilename);
            [self.navigationController popViewControllerAnimated:YES];
        }
        else if (tag == 2)
        {
            [self checkAccountAndComposeEmailWithAttachmentData:pdfData andSubject:aFilename];
        }
    }

}

UPDATE: Code amended to include NSError. The error given is "The operation couldnt be completed. (Cocoa Error 4.)

UPDATE 2: Amended the code to include Apple's recommended method of grabbing the Documents directory. Also added in a number of logs to show that I am getting correct Directory / File Path - both are showing the Documents folder or the Documents/File Name as expected. Still returns NSFileNoSuchFileError as an error every time.

Était-ce utile?

La solution

You probably should be writing with the API that allows you to pass an error pointer in

- (BOOL)writeToFile:(NSString *)path options:(NSDataWritingOptions)mask error:(NSError **)errorPtr

Then, you can inspect the NSError if it does not write properly, and act intelligently with this info.

NSError *error = nil;
BOOL success = [pdfData writeToFile:documentDirectoryFilename options:NSDataWritingAtomic error:&error];
if (!success) {
    NSLog(@"Error writing: %@", [error localizedDescription]);
}

The specific error you have is a NSFileNoSuchFileError, a clue that perhaps there are spaces or some other non-supported character in the file path, amongst other reasons.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top