2017-10-21 144 views
0

我已經得到了我今天的擴展兩個按鈕。一個專門打開MainViewController,第二個需要導航到第二個ViewController。打開特定視圖控制器從今天擴展

所以我做了一個appURL:

let appURL = NSURL(string: "StarterApplication://") 

,然後在第一個按鈕,我呼籲:

 self.extensionContext?.open(appURL! as URL, completionHandler:nil) 

其中關於MainViewController打開的應用程序。

當點擊Today Widget上的第二個按鈕時,如何打開MainViewController並執行Segue到我的SecondViewController?

我爲那個特定的ViewController做了第二個URL方案。我在其他simmilar話題看到,這可以通過調用來完成:

func application(_ app: UIApplication, open url: URL, options: [UIApplicationOpenURLOptionsKey : Any] = [:]) -> Bool { 
} 
中的AppDelegate

,但沒有任何想法如何使用它。

回答

-1

是的,你去好ü需要是在AppDelegate中返回到像這樣的網址:

func application(_ app: UIApplication, open url: URL, options: 
[UIApplicationOpenURLOptionsKey : Any] = [:]) -> Bool { 

if _ = url { 

return true 
} 
return false 
} 

編輯:

你要配合捆綁標識的URL方案(應用程序的你的開放)在你的試圖打開應用程序的plist中。

+0

你能提供更多的細節嗎?在這個if語句中需要指定什麼? – Maxxer

+0

我想說如果明確的應用程序試圖打開應用程序。我正在檢查url是否爲零。而已。 –

+0

檢查編輯。 –

0

使用一個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; 
} 

正如你所看到的,我首先檢查一下,如果是url方案。如果這是我期望的,我檢查路徑。通過使用不同的路徑,我能夠實現不同的命令今天的擴展能夠執行。每個命令可能有不同的參數。在「open_item」命令的情況下,我期望參數「itemID」。

通過返回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

我找到了解決方案。答案是深層鏈接。下面是我在的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。