From ed54ddf2cc6e2b746a406e15e99f549846cd171b Mon Sep 17 00:00:00 2001 From: Shazron Abdullah Date: Tue, 10 Feb 2015 16:51:54 -0800 Subject: [PATCH] CB-7606 - handleOpenURL not working correctly on cold start (handler not evaluated yet) and warm start --- CordovaLib/Classes/CDVHandleOpenURL.h | 28 +++++++ CordovaLib/Classes/CDVHandleOpenURL.m | 74 +++++++++++++++++++ CordovaLib/Classes/CDVViewController.m | 5 +- .../CordovaLib.xcodeproj/project.pbxproj | 8 ++ .../__PROJECT_NAME__/Classes/AppDelegate.m | 2 - 5 files changed, 114 insertions(+), 3 deletions(-) create mode 100644 CordovaLib/Classes/CDVHandleOpenURL.h create mode 100644 CordovaLib/Classes/CDVHandleOpenURL.m diff --git a/CordovaLib/Classes/CDVHandleOpenURL.h b/CordovaLib/Classes/CDVHandleOpenURL.h new file mode 100644 index 000000000..24f461f3a --- /dev/null +++ b/CordovaLib/Classes/CDVHandleOpenURL.h @@ -0,0 +1,28 @@ +/* + Licensed to the Apache Software Foundation (ASF) under one + or more contributor license agreements. See the NOTICE file + distributed with this work for additional information + regarding copyright ownership. The ASF licenses this file + to you under the Apache License, Version 2.0 (the + "License"); you may not use this file except in compliance + with the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, + software distributed under the License is distributed on an + "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + KIND, either express or implied. See the License for the + specific language governing permissions and limitations + under the License. + */ + +#import "CDVPlugin.h" + +@interface CDVHandleOpenURL : CDVPlugin + +@property (nonatomic, strong) NSURL* url; +@property (nonatomic, assign) BOOL pageLoaded; + +@end + diff --git a/CordovaLib/Classes/CDVHandleOpenURL.m b/CordovaLib/Classes/CDVHandleOpenURL.m new file mode 100644 index 000000000..e5dcdd5a1 --- /dev/null +++ b/CordovaLib/Classes/CDVHandleOpenURL.m @@ -0,0 +1,74 @@ +/* + Licensed to the Apache Software Foundation (ASF) under one + or more contributor license agreements. See the NOTICE file + distributed with this work for additional information + regarding copyright ownership. The ASF licenses this file + to you under the Apache License, Version 2.0 (the + "License"); you may not use this file except in compliance + with the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, + software distributed under the License is distributed on an + "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + KIND, either express or implied. See the License for the + specific language governing permissions and limitations + under the License. + */ + +#import "CDVHandleOpenURL.h" +#import "CDV.h" + +@implementation CDVHandleOpenURL + +- (void)pluginInitialize +{ + [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(applicationLaunchedWithUrl:) name:CDVPluginHandleOpenURLNotification object:nil]; + [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(applicationPageDidLoad:) name:CDVPageDidLoadNotification object:nil]; +} + +- (void)applicationLaunchedWithUrl:(NSNotification*)notification +{ + NSURL *url = [notification object]; + self.url = url; + + // warm-start handler + if (self.pageLoaded) { + [self processOpenUrl:self.url pageLoaded:YES]; + self.url = nil; + } +} + +- (void)applicationPageDidLoad:(NSNotification*)notification +{ + // cold-start handler + + self.pageLoaded = YES; + + if (self.url) { + [self processOpenUrl:self.url pageLoaded:YES]; + self.url = nil; + } +} + +- (void)processOpenUrl:(NSURL*)url pageLoaded:(BOOL)pageLoaded +{ + if (!pageLoaded) { + // query the webview for readystate + NSString* readyState = [self.webView stringByEvaluatingJavaScriptFromString:@"document.readyState"]; + pageLoaded = [readyState isEqualToString:@"loaded"] || [readyState isEqualToString:@"complete"]; + } + + if (pageLoaded) { + // calls into javascript global function 'handleOpenURL' + NSString* jsString = [NSString stringWithFormat:@"document.addEventListener('deviceready',function(){if (typeof handleOpenURL === 'function') { handleOpenURL(\"%@\");}});", url]; + [self.webView stringByEvaluatingJavaScriptFromString:jsString]; + } else { + // save for when page has loaded + self.url = url; + } +} + + +@end diff --git a/CordovaLib/Classes/CDVViewController.m b/CordovaLib/Classes/CDVViewController.m index eb056ce4f..6d81e8d98 100644 --- a/CordovaLib/Classes/CDVViewController.m +++ b/CordovaLib/Classes/CDVViewController.m @@ -24,6 +24,7 @@ Licensed to the Apache Software Foundation (ASF) under one #import "CDVUserAgentUtil.h" #import "CDVWebViewDelegate.h" #import +#import "CDVHandleOpenURL.h" #define degreesToRadian(x) (M_PI * (x) / 180.0) @@ -459,7 +460,9 @@ - (void)viewDidLoad [CDVTimer stop:@"TotalPluginStartup"]; } - + + [self registerPlugin:[[CDVHandleOpenURL alloc] initWithWebView:self.webView] withClassName:NSStringFromClass([CDVHandleOpenURL class])]; + // ///////////////// NSURL* appURL = [self appUrl]; diff --git a/CordovaLib/CordovaLib.xcodeproj/project.pbxproj b/CordovaLib/CordovaLib.xcodeproj/project.pbxproj index f3ef82a90..c6b0f234a 100644 --- a/CordovaLib/CordovaLib.xcodeproj/project.pbxproj +++ b/CordovaLib/CordovaLib.xcodeproj/project.pbxproj @@ -26,6 +26,8 @@ 30E33AF313A7E24B00594D64 /* CDVPlugin.m in Sources */ = {isa = PBXBuildFile; fileRef = 30E33AF113A7E24B00594D64 /* CDVPlugin.m */; }; 30E563CF13E217EC00C949AA /* NSMutableArray+QueueAdditions.h in Headers */ = {isa = PBXBuildFile; fileRef = 30E563CD13E217EC00C949AA /* NSMutableArray+QueueAdditions.h */; settings = {ATTRIBUTES = (Public, ); }; }; 30E563D013E217EC00C949AA /* NSMutableArray+QueueAdditions.m in Sources */ = {isa = PBXBuildFile; fileRef = 30E563CE13E217EC00C949AA /* NSMutableArray+QueueAdditions.m */; }; + 30E6B8CD1A8ADD900025B9EE /* CDVHandleOpenURL.h in Headers */ = {isa = PBXBuildFile; fileRef = 30E6B8CB1A8ADD900025B9EE /* CDVHandleOpenURL.h */; }; + 30E6B8CE1A8ADD900025B9EE /* CDVHandleOpenURL.m in Sources */ = {isa = PBXBuildFile; fileRef = 30E6B8CC1A8ADD900025B9EE /* CDVHandleOpenURL.m */; }; 30F3930B169F839700B22307 /* CDVJSON.h in Headers */ = {isa = PBXBuildFile; fileRef = 30F39309169F839700B22307 /* CDVJSON.h */; settings = {ATTRIBUTES = (Public, ); }; }; 30F3930C169F839700B22307 /* CDVJSON.m in Sources */ = {isa = PBXBuildFile; fileRef = 30F3930A169F839700B22307 /* CDVJSON.m */; }; 30F5EBAB14CA26E700987760 /* CDVCommandDelegate.h in Headers */ = {isa = PBXBuildFile; fileRef = 30F5EBA914CA26E700987760 /* CDVCommandDelegate.h */; settings = {ATTRIBUTES = (Public, ); }; }; @@ -76,6 +78,8 @@ 30E33AF113A7E24B00594D64 /* CDVPlugin.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = CDVPlugin.m; path = Classes/CDVPlugin.m; sourceTree = ""; }; 30E563CD13E217EC00C949AA /* NSMutableArray+QueueAdditions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = "NSMutableArray+QueueAdditions.h"; path = "Classes/NSMutableArray+QueueAdditions.h"; sourceTree = ""; }; 30E563CE13E217EC00C949AA /* NSMutableArray+QueueAdditions.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = "NSMutableArray+QueueAdditions.m"; path = "Classes/NSMutableArray+QueueAdditions.m"; sourceTree = ""; }; + 30E6B8CB1A8ADD900025B9EE /* CDVHandleOpenURL.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = CDVHandleOpenURL.h; path = Classes/CDVHandleOpenURL.h; sourceTree = ""; }; + 30E6B8CC1A8ADD900025B9EE /* CDVHandleOpenURL.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = CDVHandleOpenURL.m; path = Classes/CDVHandleOpenURL.m; sourceTree = ""; }; 30F39309169F839700B22307 /* CDVJSON.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = CDVJSON.h; path = Classes/CDVJSON.h; sourceTree = ""; }; 30F3930A169F839700B22307 /* CDVJSON.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = CDVJSON.m; path = Classes/CDVJSON.m; sourceTree = ""; }; 30F5EBA914CA26E700987760 /* CDVCommandDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = CDVCommandDelegate.h; path = Classes/CDVCommandDelegate.h; sourceTree = ""; }; @@ -194,6 +198,8 @@ 888700D710922F56009987E8 /* Commands */ = { isa = PBXGroup; children = ( + 30E6B8CB1A8ADD900025B9EE /* CDVHandleOpenURL.h */, + 30E6B8CC1A8ADD900025B9EE /* CDVHandleOpenURL.m */, 7E22B88419E4C0210026F95E /* CDVAvailabilityDeprecated.h */, EBFF4DBA16D3FE2E008F452B /* CDVWebViewDelegate.m */, EBFF4DBB16D3FE2E008F452B /* CDVWebViewDelegate.h */, @@ -268,6 +274,7 @@ 8887FD8F1090FBE7009987E8 /* NSData+Base64.h in Headers */, 1F92F4A01314023E0046367C /* CDVPluginResult.h in Headers */, 30E33AF213A7E24B00594D64 /* CDVPlugin.h in Headers */, + 30E6B8CD1A8ADD900025B9EE /* CDVHandleOpenURL.h in Headers */, 302965BC13A94E9D007046C5 /* CDVDebug.h in Headers */, 30E563CF13E217EC00C949AA /* NSMutableArray+QueueAdditions.h in Headers */, 30C684801406CB38004C1A8E /* CDVWhitelist.h in Headers */, @@ -364,6 +371,7 @@ F858FBC7166009A8007DA594 /* CDVConfigParser.m in Sources */, 30F3930C169F839700B22307 /* CDVJSON.m in Sources */, EB96673C16A8970A00D86CDF /* CDVUserAgentUtil.m in Sources */, + 30E6B8CE1A8ADD900025B9EE /* CDVHandleOpenURL.m in Sources */, EBFF4DBC16D3FE2E008F452B /* CDVWebViewDelegate.m in Sources */, 7E14B5A91705050A0032169E /* CDVTimer.m in Sources */, ); diff --git a/bin/templates/project/__PROJECT_NAME__/Classes/AppDelegate.m b/bin/templates/project/__PROJECT_NAME__/Classes/AppDelegate.m index fe4a7a079..c52a83863 100644 --- a/bin/templates/project/__PROJECT_NAME__/Classes/AppDelegate.m +++ b/bin/templates/project/__PROJECT_NAME__/Classes/AppDelegate.m @@ -99,8 +99,6 @@ - (BOOL)application:(UIApplication*)application openURL:(NSURL*)url sourceApplic return NO; } - [self.viewController processOpenUrl:url]; - // all plugins will get the notification, and their handlers will be called [[NSNotificationCenter defaultCenter] postNotification:[NSNotification notificationWithName:CDVPluginHandleOpenURLNotification object:url]];