iOS scheme跳起色制

簡介

蘋果手機中的APP都有一個沙盒,APP就是一個單獨個體,信息獨立,相互是不能夠進行通訊的.可是iOS的APP能夠註冊本身的URL Scheme,URL Scheme是爲方便App之間相互調用而設計的.咱們能夠經過系統的openURL來打開該APP,並能夠傳遞一些參數,URL Scheme必須能惟一表示一個APP,若是你設置的URL Scheme和逼得APP的URL Scheme衝突時,你的APP不必定會被啓動起來.由於當你的APP在安裝的時候,系統裏面已經註冊了你的URL Scheme.通常狀況下,是會調用先安裝的APP.可是iOS的系統APP的URL Scheme確定是最高的,因此咱們定義URL Scheme的時候,儘可能避開系統APP已經定義過的URL Scheme數組

URL Scheme的命名應該是隻能純英文字符,而不能含有下劃線或者數字瀏覽器

註冊URL Scheme

方法一

在 TARGETS -> Info -> URL Types 點擊添加 bash

在這裏插入圖片描述

方法二

在info.plist中右擊,選中 微信

在這裏插入圖片描述
Add Row選項,而後輸入URL types,類型爲 Array

URL Identifier是自定義的 URL scheme 的名字,通常採用反轉域名的方法保證該名字的惟一性,好比 com.DemoB.www,不過在iOS中打開一個應用程序只須要拿到這個應用程序的協議頭(URL Scheme)便可,因此咱們只需配置應用程序的協議頭便可。一個應用是能夠有多個URL Schemes的app

使用

1. 應用A跳轉到應用B

這裏建立了兩個應用:DemoA 和DemoB,DemoB註冊了Scheme爲"DemoBScheme",下面來實現DemoA→DemoB的跳轉ui

#pragma mark - DemoA -> DemoB
- (IBAction)jumpToDemoB:(id)sender {
    NSString *urlString = @"DemoBScheme://";//沒有參數
    NSURL *url = [NSURL URLWithString:urlString];
    if ([[UIApplication sharedApplication] canOpenURL:url]) {
        [[UIApplication sharedApplication] openURL:url options:@{} completionHandler:^(BOOL success) {
        }];
    }
    else {
        [self showMessage:@"沒有該應用"];
    }
}
複製代碼

分別運行兩個應用,而後在DemoA中點擊相應的按鈕跳轉到DemoB,會發現並不能跳轉,由於在iOS9之後,若是使用canOpenURL:方法,改方法所涉及的URL Scheme必須在Info.plist中將它們列爲白名單,不然不能使用url

在info.plist中添加LSApplicationQueriesSchemes字段,該字段對應的是數組類型,而後添加鍵值DemoBScheme(DemoB的Scheme) spa

在這裏插入圖片描述
而後運行,點擊按鈕就能夠跳轉到demoB

2. 跳轉到指定界面

有的時候咱們須要跳轉到某個應用的特定頁面,好比分享的時候須要分享到朋友圈頁面設計

  1. 首先在DemoB中建立PageOne和PageTwo頁面 . 在 DemoA中的點擊事件中,咱們能夠修改urlString爲 DemoBScheme://page1,其中DemoBScheme:// 是DemoB應用的scheme ,page1是與DemoB約定好的跳轉到PageOne頁面的標識符
#pragma mark - 跳轉到pageOne頁面
- (IBAction)jumpToPageOne:(id)sender {
// DemoBScheme:是DemoB應用的scheme page1是與DemoB約定好的跳轉到PageOne頁面的標識符 ?是分割符(固然也能夠用其餘符號做分割),在DemoB中經過分隔符來截取DemoA的scheme, DemoAScheme是本身的scheme,用來從DemoB跳轉回來
   NSString *urlString = @"DemoBScheme://page1?DemoAScheme";
   NSURL *url = [NSURL URLWithString:urlString];
   if ([[UIApplication sharedApplication] canOpenURL:url]) {
       [[UIApplication sharedApplication] openURL:url options:@{} completionHandler:^(BOOL success) {
           
       }];
   }
   else {
       [self showMessage:@"沒有該應用"];
   }
}
複製代碼
  1. 在 DemoB的appdelegatete中實現application:(UIApplication *)app openURL:(NSURL *)url options:(NSDictionary<UIApplicationOpenURLOptionsKey,id> *)options方法
- (BOOL)application:(UIApplication *)app openURL:(NSURL *)url options:(NSDictionary<UIApplicationOpenURLOptionsKey,id> *)options {
    
    // 1.獲取導航欄控制器
    UINavigationController *rootNav = (UINavigationController *)self.window.rootViewController;
    // 2.得到主控制器
    UIViewController *mainVc = [rootNav.childViewControllers firstObject];
    
    // 3.每次跳轉前必須是在跟控制器(細節)
    [rootNav popToRootViewControllerAnimated:NO];
    
    if ([url.absoluteString containsString:@"page1"]) {//與DemoA約定好的字符
        PageOneViewController *page = [[PageOneViewController alloc] init];
        page.urlString = url.absoluteString;
        
        [mainVc.navigationController pushViewController:page animated:YES];
    }
    else if ([url.absoluteString containsString:@"page2"]) {
        PageOneViewController *page = [[PageOneViewController alloc] init];
        page.urlString = url.absoluteString;
        [mainVc.navigationController pushViewController:page animated:YES];
    }
    else {
        UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:@"打開啦"
                                                            message:[NSString stringWithFormat:@"scheme - %@,\n host -- %@,\n query -- %@",url.scheme,url.host,url.query]
                                                           delegate:nil
                                                  cancelButtonTitle:@"OK"
                                                  otherButtonTitles:nil];
        NSLog(@"query -- %@", url.query);
        [alertView show];
    }
    return YES;
}
複製代碼

這樣就實現了DemoA跳轉到DemoB中某個特定頁面3d

iOS 9.0以前應在- (BOOL)application:(UIApplication *)application openURL:(NSURL *)url sourceApplication:(NSString *)sourceApplication annotation:(id)annotation 方法中設置

3. 從DemoB返回到DemoA

上面講了從DemoA跳轉到DemoB,有的時候在跳轉完以後須要再跳回到本來的app,好比分享完成以後會讓選擇返回到原來的app仍是留在微信

  1. 從某個應用跳轉到另外一個應用上面已經講過了,如今要從DemoB回到DemoA的話首先也是爲DemoA註冊URL Scheme,而後再DemoB的info.plist中設置白名單,把DemoA的Scheme添加進去
  2. 在咱們從DemoA跳轉到DemoB的時候,咱們應該順便把DemoA的Scheme傳遞過去
#pragma mark - 跳轉到pageOne頁面
- (IBAction)jumpToPageOne:(id)sender {
    //咱們想要從應用B再跳轉回應用A,那麼在跳轉到應用B的時候,還應將應用A的URL Schemes傳遞過來。這樣咱們才能判斷應該跳轉回哪一個應用程序。
//    這樣咱們指定一個傳遞URL的規則:協議頭://應用B的URL Schemes?應用A的URL Schemes。即:AppB://Page1?AppA。
//是DemoB應用的scheme page1是與DemoB約定好的跳轉到PageOne頁面的標識符 ?是分割符(固然也能夠用其餘符號做分割),在DemoB中經過分隔符來截取DemoA的scheme, DemoAScheme是本身的scheme,用來從DemoB跳轉回來
    NSString *urlString = @"DemoBScheme://page1?DemoAScheme";// DemoBScheme:
    NSURL *url = [NSURL URLWithString:urlString];
    if ([[UIApplication sharedApplication] canOpenURL:url]) {
        [[UIApplication sharedApplication] openURL:url options:@{} completionHandler:^(BOOL success) {
            
        }];
    }
    else {
        [self showMessage:@"沒有該應用"];
    }
}
複製代碼
  1. 在 DemoB中的- (BOOL)application:(UIApplication *)app openURL:(NSURL *)url options:(NSDictionary<UIApplicationOpenURLOptionsKey,id> *)options 方法中咱們把收到的url傳遞給PageOne頁面
- (BOOL)application:(UIApplication *)app openURL:(NSURL *)url options:(NSDictionary<UIApplicationOpenURLOptionsKey,id> *)options {
    
    // 1.獲取導航欄控制器
    UINavigationController *rootNav = (UINavigationController *)self.window.rootViewController;
    // 2.得到主控制器
    UIViewController *mainVc = [rootNav.childViewControllers firstObject];
    
    // 3.每次跳轉前必須是在跟控制器(細節)
    [rootNav popToRootViewControllerAnimated:NO];

    if ([url.absoluteString containsString:@"page1"]) {//與DemoA約定好的字符
        PageOneViewController *page = [[PageOneViewController alloc] init];
        page.urlString = url.absoluteString;
        
        [mainVc.navigationController pushViewController:page animated:YES];
    }
    else if ([url.absoluteString containsString:@"page2"]) {
        PageOneViewController *page = [[PageOneViewController alloc] init];
        page.urlString = url.absoluteString;
        [mainVc.navigationController pushViewController:page animated:YES];
    }
    else {
        UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:@"打開啦"
                                                            message:[NSString stringWithFormat:@"scheme - %@,\n host -- %@,\n query -- %@",url.scheme,url.host,url.query]
                                                           delegate:nil
                                                  cancelButtonTitle:@"OK"
                                                  otherButtonTitles:nil];
        NSLog(@"query -- %@", url.query);
        [alertView show];
    }
    return YES;
}
複製代碼
  1. 在DemoB的pageOne頁面的點擊事件中經過約定好的切割符號截取DemoA的Scheme
#pragma mark - 返回DemoA
- (IBAction)backDemoA:(id)sender {
    // 1.拿到對應應用程序的URL Scheme 經過約定好的分割符?切割
    NSString *urlSchemeString = [[self.urlString componentsSeparatedByString:@"?"] lastObject];
    NSString *urlString = [urlSchemeString stringByAppendingString:@"://"];
    
    // 2.獲取對應應用程序的URL
    NSURL *url = [NSURL URLWithString:urlString];
    
    // 3.判斷是否能夠打開
    if ([[UIApplication sharedApplication] canOpenURL:url]) {
        [[UIApplication sharedApplication] openURL:url options:@{} completionHandler:nil];
    }
}
複製代碼

4. 經過URL傳參

. 有時候咱們跳轉另外一個APP的時候須要傳遞一些參數,讓另外一個APP根據咱們傳遞的參數作出相應的行爲

傳參格式:

"DemoBScheme://?name=lwy&phone=110" 和平時的get請求傳參是同樣的

  1. 跳轉的時候傳參
#pragma mark - DemoA -> DemoB
- (IBAction)jumpToDemoB:(id)sender {
//    NSString *urlString = @"DemoBScheme://";//沒有參數
    NSString *urlString = @"DemoBScheme://?name=lwy&phone=110";//後面拼接參數
    NSURL *url = [NSURL URLWithString:urlString];
    if ([[UIApplication sharedApplication] canOpenURL:url]) {
        [[UIApplication sharedApplication] openURL:url options:@{} completionHandler:^(BOOL success) {
            
        }];
    }
    else {
        [self showMessage:@"沒有該應用"];
    }
}
複製代碼
  1. 在demoB中的- (BOOL)application:(UIApplication *)app openURL:(NSURL *)url options:(NSDictionary<UIApplicationOpenURLOptionsKey,id> *)options方法能夠獲取到參數
NSString *query = url.query;
複製代碼

5. 經過網址打開APP

網頁打開app也是根據app的協議頭(URL scheme)來區分打開的是哪個app的,咱們直接在瀏覽器上覆制粘貼咱們的url scheme ,系統會自動彈框提醒是否打開本應用,跟DemoA跳轉到DemoB的跳轉是同樣的, 固然網頁傳參跟app跳轉傳參都是同樣的格式

相關文章
相關標籤/搜索