我今天的扩展程序上有两个按钮。一个专用于打开MainViewController,第二个需要导航到第二个ViewController。
所以我做了一个appURL:
let appURL = NSURL(string: "StarterApplication://")
然后在我打电话的第一个按钮上:
self.extensionContext?.open(appURL! as URL, completionHandler:nil)
在MainViewController上打开应用程序。
当点击Today Widget上的第二个按钮时,如何打开MainViewController并对我的SecondViewController执行Severn?
我为该特定的ViewController制作了第二个URL方案。我在其他类似的主题中看到,可以通过调用:
来完成func application(_ app: UIApplication, open url: URL, options: [UIApplicationOpenURLOptionsKey : Any] = [:]) -> Bool {
}
在AppDelegate中,但不知道如何使用它。
答案 0 :(得分:1)
使用一个URL方案。您可以为不同的任务添加不同的路径或参数。
例如,我的应用在今天的扩展程序中显示多个项目。如果您点按某个项目,该应用就会被打开。
- (void)_openItem:(SPItem *)item
{
NSURL* url = [NSURL URLWithString:[NSString stringWithFormat:@"myapp://localhost/open_item?itemID=%@", item.itemID]];
if (url != nil)
{
[self.extensionContext openURL:url completionHandler:nil];
}
}
正如您在问题中已经提到的那样,您需要实施- (BOOL)application:(UIApplication *)app openURL:(NSURL *)url options:(NSDictionary<NSString *,id> *)options
就我而言,它或多或少看起来像这样:
- (BOOL)application:(UIApplication *)app openURL:(NSURL *)url options:(NSDictionary<NSString *,id> *)options
{
BOOL ret;
if ([url.scheme isEqualToString:@"myapp"])
{
if ([url.path isEqual:@"open_item"])
{
@try
{
NSDictionary *query = [url.query queryDictionary];
NSString* itemID = query[@"itemID"];
[self _gotoItemWithID:itemID completionHandler:nil];
}
@catch (NSException *exception) {
}
ret = YES;
}
}
else
{
ret = NO;
}
return ret;
}
如您所见,我首先检查一下,如果网址方案。如果它是我期望的那个,我检查路径。通过使用不同的路径,我能够实现不同的命令,今天的扩展能够执行。每个命令可能有不同的参数。如果是&#34; open_item&#34;命令,我希望参数&#34; itemID&#34;。
通过返回YES,您告诉iOS您能够处理调用应用程序的URL。
在我的应用[self _gotoItemWithID:itemID completionHandler:nil]
中执行显示项目的所有需要任务。在您的情况下,您需要一个功能来显示第二个视图控制器。
修改强>
我忘了提到queryDictionary
是NSString扩展中的方法。它需要一个字符串(self
)并尝试提取URL参数并将它们作为字典返回。
- (NSDictionary*)queryDictionary
{
NSCharacterSet* delimiterSet = [NSCharacterSet characterSetWithCharactersInString:@"&;"];
NSMutableDictionary* pairs = [NSMutableDictionary dictionary];
NSScanner* scanner = [[NSScanner alloc] initWithString:self];
while (![scanner isAtEnd])
{
NSString* pairString;
[scanner scanUpToCharactersFromSet:delimiterSet
intoString:&pairString] ;
[scanner scanCharactersFromSet:delimiterSet intoString:NULL];
NSArray* kvPair = [pairString componentsSeparatedByString:@"="];
if ([kvPair count] == 2)
{
NSString* key = [[kvPair objectAtIndex:0] stringByRemovingPercentEncoding];
NSString* value = [[kvPair objectAtIndex:1] stringByRemovingPercentEncoding];
[pairs setObject:value forKey:key] ;
}
}
return [NSDictionary dictionaryWithDictionary:pairs];
}
答案 1 :(得分:1)
我找到了解决方案。答案是深层次的联系。这是我在appDelegate中的方法:
func application(_ app: UIApplication, open url: URL, options: [UIApplicationOpenURLOptionsKey : Any] = [:]) -> Bool {
let urlPath : String = url.path as String!
let mainStoryboard: UIStoryboard = UIStoryboard(name: "Main", bundle: nil)
if(urlPath == "/Action"){
let ActionView: ActionViewController = mainStoryboard.instantiateViewController(withIdentifier: "ActionViewController") as! ActionViewController
self.window?.rootViewController = ActionView
} else if(urlPath == "/VoiceCommandView") {
let VoiceCommandView: ViewController = mainStoryboard.instantiateViewController(withIdentifier: "ViewController") as! ViewController
self.window?.rootViewController = VoiceCommandView
}
self.window?.makeKeyAndVisible()
return true
在TodayExtensionViewController中,我定义了两个具有相同主机但URL路径不同的URL方案。并且做了一个简单的:
self.extensionContext?.open(startAppURL! as URL, completionHandler:nil)
表示第一个按钮,但更改了第二个按钮的urlPath。