Search code examples
iosswiftnsfilemanagertoday-extension

Load file in Today extension when device is locked


In my today extension with my device unlocked, this line of code works as expected, returning the data from the image path:

let imageData = NSData(contentsOfFile: path)

However when my device is locked with a passcode, it returns nil. Is there any way to access images in the file system when the device is locked? I can access UserDefaults just fine, but not files in the directory for my shared group. Here is how I am creating the path, calling imagePath, which is correctly populated with the path I expect in both cases:

func rootFilePath() -> String? {
    let manager = NSFileManager()
    let containerURL = manager.containerURLForSecurityApplicationGroupIdentifier(GROUP_ID)
    if let unwrappedURL = containerURL {
        return unwrappedURL.path
    }
    else {
        return nil
    }
}

func imagePath() -> String? {
    let rootPath = rootFilePath()
    if let uPath = rootPath {
        return "\(uPath)/\(imageId).png"
    }
    else {
        return nil
    }
}

Solution

  • I just figured it out! You need to set the file permissions accordingly:

    NSFileManager *fm = [[NSFileManager alloc] init];
    NSDictionary *attribs = @{NSFileProtectionKey : NSFileProtectionNone};
    NSError *unprotectError = nil;
    
    BOOL unprotectSuccess = [fm setAttributes:attribs
                                 ofItemAtPath:[containerURL path]
                                        error:&unprotectError];
    if (!unprotectSuccess) {
        NSLog(@"Unable to remove protection from file! %@", unprotectError);
    }
    

    In many cases you wouldn't normally want to do this, but because the information is intended to be viewed from the lock screen, I'm OK with removing file protection.