Skip to content

palmin/x-document-source

Repository files navigation

x-document-source

Motivation

iOS apps usually only have access to files in their own sandbox container. The document picker which was introduced in iOS 8 lets users import or open files from iCloud Drive and third-party apps. Apps can add document provider extensions to make them appear in the list of locations of the document picker.

When the user picks a file or folder, the app that invoked the document picker only gets a security-scoped url, but no additional information about the app that provided it.

For iCloud Drive documents, apps can use the NSURLUbiquitousItemContainerDisplayNameKey to get the name of the item's iCloud Drive container.

Unfortunately, no such information is available for third-party document providers. The app accessing external files has no immediate way to know which app provides these files.

We describe a way to share such information using an extended file attribute in a way that has minimal consequences for apps unaware of this mechanism.

Writing the Extended File Attribute

When files or directories are picked, the app extension should use the setxattr function to write an extended file attribute named x-document-source containing a property list in binary format. As an example, here is how such a property list might look:

NSDictionary *plist = @{
    @"identifier": @"com.appliedphasor.working-copy",
    @"name": @"Working Copy",
    @"path": @"directory/filename.ext",
    @"appInfoURL": @"https://raw.githubusercontent.com/palmin/x-document-source/master/appInfo.json"
};

App Icons

Icon files are not included in the extended file attribute to keep it small.

Instead, app icons can be retrieved by accessing the JSON file pointed to by appInfoURL. This file will itself reference icons at different resolutions and the src value can be either a fully qualified URL or relative to the JSON file itself.

You should serve the files from a secure website (https) to comply with App Transport Security.

{"icons":
[{"width": 29, "height": 29, "src": "img/icon.png"},
 {"width": 58, "height": 58, "src": "img/[email protected]"},
 {"width": 87, "height": 87, "src": "img/[email protected]"},
 {"width": 1024, "height": 1024, "src": "img/icon-1024.png"}
]}

It is the responsibility of the app reading these images to mask the image to the rounded rectangle expected for app icons. This repository contains code for this.

Adoption

So far, x-document-source has been implemented by Working Copy, Textastic v6.2 and GoCoEdit v9.1.

If you have an app that is either a document provider or uses the iOS document picker: please have a look at the XDSDocumentSourceAttribute class in this repository and add it to your app!

A document provider might write this extended attribute as part of dismissGrantingAccessToURL in UIDocumentPickerExtensionViewController:

- (void)dismissGrantingAccessToURL:(NSURL *)url {
    // determine documentPath relative to rootStorageURL
    NSString* rootPath = self.documentStorageURL.path;
    NSRange range = [url.path rangeOfString: rootPath.lastPathComponent];
    NSString* documentPath = [url.path substringFromIndex:range.location + range.length];

    NSString* appId = @"com.appliedphasor.working-copy";
    NSURL* appInfoURL = [NSURL URLWithString:@"https://workingcopyapp.com/appInfo.json"];
    XDSDocumentSourceAttribute* attribute;
    attribute = [XDSDocumentSourceAttribute documentSourceAttributeWithBundleIdentifier:appId
                                                                        applicationName:@"Working Copy"
                                                                           documentPath:documentPath
                                                                             appInfoURL:appInfoURL];
    [attribute writeToURL:url];

    [super dismissGrantingAccessToURL:url];
}

About

No description, website, or topics provided.

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published