diff --git a/modules/juce_events/messages/juce_ApplicationBase.h b/modules/juce_events/messages/juce_ApplicationBase.h index efb639d27b17..d346634cd438 100644 --- a/modules/juce_events/messages/juce_ApplicationBase.h +++ b/modules/juce_events/messages/juce_ApplicationBase.h @@ -295,6 +295,8 @@ class JUCE_API JUCEApplicationBase bool sendCommandLineToPreexistingInstance(); #endif + virtual bool urlOpened(URL& url) { return false; } + private: //============================================================================== static JUCEApplicationBase* appInstance; diff --git a/modules/juce_gui_basics/native/juce_ios_Windowing.mm b/modules/juce_gui_basics/native/juce_ios_Windowing.mm index bedbfc4319d6..7da5d198b888 100644 --- a/modules/juce_gui_basics/native/juce_ios_Windowing.mm +++ b/modules/juce_gui_basics/native/juce_ios_Windowing.mm @@ -79,6 +79,7 @@ - (void) userNotificationCenter: (UNUserNotificationCenter*) center willPresentN withCompletionHandler: (void (^)(UNNotificationPresentationOptions options)) completionHandler; - (void) userNotificationCenter: (UNUserNotificationCenter*) center didReceiveNotificationResponse: (UNNotificationResponse*) response withCompletionHandler: (void(^)())completionHandler; +- (BOOL) application: (UIApplication *) app openURL: (NSURL *) url options: (NSDictionary *) options; #endif #endif @@ -172,6 +173,66 @@ - (void) applicationWillResignActive: (UIApplication*) application appBecomingInactiveCallbacks.getReference(i)->appBecomingInactive(); } +- (BOOL)application:(UIApplication *)application + openURL:(NSURL *)url + options:(NSDictionary *)options { + + if(!JUCEApplicationBase::getInstance()) + { + [self applicationDidFinishLaunching:application]; + } + + NSUInteger accessOptions = NSFileCoordinatorReadingWithoutChanges; + + auto *fileAccessIntent = [NSFileAccessIntent readingIntentWithURL:url options:accessOptions]; + + NSArray *intents = @[fileAccessIntent]; + + auto *fileCoordinator = [[NSFileCoordinator alloc] initWithFilePresenter:nil]; + + [fileCoordinator coordinateAccessWithIntents:intents queue:[NSOperationQueue mainQueue] byAccessor:^(NSError *err) { + if (err == nil) { + [url startAccessingSecurityScopedResource]; + + NSError *error = nil; + + NSData *bookmark = [url bookmarkDataWithOptions:0 + includingResourceValuesForKeys:nil + relativeToURL:nil + error:&error]; + + [bookmark retain]; + + [url stopAccessingSecurityScopedResource]; + + URL juceUrl(nsStringToJuce([url absoluteString])); + + if (error == nil) { + setURLBookmark(juceUrl, (void *) bookmark); + } else { + auto *desc = [error localizedDescription]; + ignoreUnused(desc); + jassertfalse; + } + + if (auto *app = JUCEApplicationBase::getInstance()) + { + app->urlOpened(juceUrl); + } + else + { + jassertfalse; + } + } else { + auto *desc = [err localizedDescription]; + ignoreUnused(desc); + jassertfalse; + } + }]; + + return YES; +} + - (void) application: (UIApplication*) application handleEventsForBackgroundURLSession: (NSString*)identifier completionHandler: (void (^)(void))completionHandler {