Skip to content

Instantly share code, notes, and snippets.

@blach
Created August 13, 2018 16:37
Show Gist options
  • Save blach/4b4b779695eba78539ef2f8d1d62c339 to your computer and use it in GitHub Desktop.
Save blach/4b4b779695eba78539ef2f8d1d62c339 to your computer and use it in GitHub Desktop.
XDocumentSource File Provider Service
//
// XDocumentSource.h
// Textastic Universal
//
// Created by Alexander Blach on 01.05.18.
//
#import <Foundation/Foundation.h>
@protocol XDocumentSourceProtocol
- (void)writeExtendedAttribute;
- (void)writeExtendedAttributeWithCompletionHandler:(void (^)(BOOL didWrite))completionHandler;
@end
@interface NSURL (XDocumentSource)
- (void)requestXDocumentSourceServiceWithCompletionHandler:(void (^)(NSURL *url))completionHandler;
@end
//
// XDocumentSource.m
// Textastic Universal
//
// Created by Alexander Blach on 01.05.18.
//
#import "XDocumentSource.h"
@implementation NSURL (XDocumentSource)
// the completion handler is always called on the main queue
// you need to call -[NSURL startAccessingSecurityScopedResource] on the url before calling this method
- (void)requestXDocumentSourceServiceWithCompletionHandler:(void (^)(NSURL *url))completionHandler {
NSURL *url = self;
if (@available(iOS 11, *)) {
[[NSFileManager defaultManager] getFileProviderServicesForItemAtURL:url completionHandler:^(NSDictionary<NSFileProviderServiceName,NSFileProviderService *> * _Nullable services, NSError * _Nullable error) {
BOOL didFindService = NO;
for (NSFileProviderServiceName serviceName in services.allKeys) {
if ([serviceName hasSuffix:@"x-document-source"]) {
// found a service ending in "x-document-source"!
didFindService = YES;
NSFileProviderService *service = services[serviceName];
// try to connect to service
[service getFileProviderConnectionWithCompletionHandler:^(NSXPCConnection * _Nullable connection, NSError * _Nullable error) {
if (error != nil) {
NSLog(@"requestXDocumentSourceServiceForURL: failed to get file provider connection for x-documents-source service: %@", error);
dispatch_async(dispatch_get_main_queue(), ^{
completionHandler(url);
});
} else if (connection) {
connection.remoteObjectInterface = [NSXPCInterface interfaceWithProtocol:@protocol(XDocumentSourceProtocol)];
[connection resume];
[[connection remoteObjectProxyWithErrorHandler:^(NSError * _Nonnull error) {
NSLog(@"requestXDocumentSourceServiceForURL: error calling remote object: %@", error);
dispatch_async(dispatch_get_main_queue(), ^{
completionHandler(url);
});
[connection invalidate];
}] writeExtendedAttributeWithCompletionHandler:^(BOOL didWrite) {
NSLog(@"writeExtendedAttributeWithCompletionHandler didWrite:%d", didWrite);
dispatch_async(dispatch_get_main_queue(), ^{
completionHandler(url);
});
[connection invalidate];
}];
}
}];
break;
}
}
if (!didFindService) {
// service not found -> call completion handler
dispatch_async(dispatch_get_main_queue(), ^{
completionHandler(url);
});
}
}];
} else {
dispatch_async(dispatch_get_main_queue(), ^{
completionHandler(url);
});
}
}
@end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment