應用間跳轉

1、應用間跳轉介紹git

1.一、什麼是應用間跳轉,有什麼做用? 以下api

<1>、使用第三方用戶登陸,須要用戶受權,還須要"返回到調用的程序,同時返回受權的用戶名"數組

<2>、應用程序推廣,設置-推薦應用-有不少應用程序圖標若是本機已經安裝過,會直接跳轉到另一個應用程序, 軟件的廣告,咱們在抖音或者進入頭條均可以看到不少的點擊事件進去其餘的app或者去下載appstore下載app瀏覽器

<3>、平時 支付寶,微信支付 等等微信

1.二、如何實現應用程序間跳轉 ?app

<1>、跳轉appstore進入本身的app: 在咱們本身的app裏面有時候咱們會有更新提醒,其實也就是打開咱們本身 app 的 url,以 itms-apps://或https://開頭的應用詳情頁連接,跳轉到AppStore,以下,其中url要進行轉碼,下面我就再也不轉碼了測試

OC 版本:微信支付

1url

2spa

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

NSURL *url = [NSURL URLWithString:@"itms-apps://itunes.apple.com/app/id1129144823"];

 

// 注意: 跳轉以前, 可使用 canOpenURL: 判斷是否能夠跳轉

if (![[UIApplication sharedApplication]canOpenURL:url]) {

        // 不能跳轉就不要往下執行了

        return;

}

 

if (@available(iOS 10.0, *)){

 

      [[UIApplication sharedApplication]openURL:url options:@{UIApplicationOpenURLOptionsSourceApplicationKey:@YES} completionHandler:^(BOOL success) {

   

            if (success) {

                 NSLog(@"10之後能夠跳轉url");

            }else{

                NSLog(@"10之後不能夠跳轉url");

            }

      }];

 }else{

  

     BOOL success = [[UIApplication sharedApplication]openURL:url];

     if (success) {

         NSLog(@"10之前能夠跳轉url");

     }else{

         NSLog(@"10之前不能夠跳轉url");

     }

}

Swift 版本:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

let url = URL(string: "itms-apps://itunes.apple.com/app/id1129144823")

 

// 注意: 跳轉以前, 可使用 canOpenURL: 判斷是否能夠跳轉

if !UIApplication.shared.canOpenURL(url!) {

     // 不能跳轉就不要往下執行了

     return

}

 

if #available(iOS 10.0, *) {

   

      UIApplication.shared.open(url!, options: [:]) { (success) in

           if (success) {

                print("10之後能夠跳轉url")

           }else{

                print("10之後不能完成跳轉")

           }

       }

else {

       // Fallback on earlier versions

       let success = UIApplication.shared.openURL(url!)

       if (success) {

             print("10如下能夠跳轉")

       }else{

             print("10如下不能完成跳轉")

       }

 }

<2>、打電話:tel://電話號碼,代碼和上面的同樣

<3>、發短信:sms://電話號碼,代碼和上面的同樣

<4>、發郵件:mailTo://郵箱號,代碼和上面的同樣

提示:itms-apps、https、tel、sms、mailTo 都是協議,app之間跳轉的協議是:Scheme,若是想要跳轉到不一樣app,就要打開對應的 URL(協議是:scheme), scheme是一個具體的字符串,並非scheme這幾個字母,在下面會詳細的介紹

1.三、URL : 統一資源定位符

<1>、咱們以淘寶網的一個連接爲例:https://www.taobao.com/markets/bao/xiangbao?spm=a21bo.2017.201867-main.5.5af911d9blzLlJ

Swift版本

1

2

let url = URL(string: "https://www.taobao.com/markets/bao/xiangbao?spm=a21bo.2017.201867-main.5.5af911d9blzLlJ")

print("協議=",url!.scheme ?? "","IP或者是域名=",url!.host ?? "","路徑=",url!.path ,"參數=",url!.query ?? "")

打印結果:協議= https IP或者是域名= www.taobao.com 路徑= /markets/bao/xiangbao 參數= spm=a21bo.2017.201867-main.5.5af911d9blzLlJ

OC版本

1

2

NSURL *url = [NSURL URLWithString:@"https://www.taobao.com/markets/bao/xiangbao?spm=a21bo.2017.201867-main.5.5af911d9blzLlJ"];

NSLog(@"協議=%@ IP或者是域名=%@ 路徑=%@ 參數=%@",url.scheme,url.host,url.path,url.query);

打印結果和上面的同樣

<2>、一個 url 分爲如下部分

1

2

3

4

協議:https

IP或者是域名:www.taobao.com

路徑:/markets/bao/xiangbao

參數:spm=a21bo.2017.201867-main.5.5af911d9blzLlJ

2、應用間跳轉實現

2.一、咱們先以本身建立的app實現來回的跳轉:Test1 與 Test2 兩個項目

2.二、給Test2項目設置一個 URL Scheme,用來其餘的app跳轉到 Test2

image.png

給Test2項目設置一個 `URL Scheme`,用來其餘的app跳轉到 `Test2`

提示:設置 URL Scheme時, 不要加 ://,好比上面直接設置:test2 一個字符串就好

  • 再說一下不必定根據 URL Scheme進入不一樣的界面的,也能夠在Scheme後拼接參數,好比:test2://1234

  • URL scheme 的做用:咱們能夠將應用「綁定」到一個自定義 URL scheme 上,該 scheme 用於從瀏覽器或其餘應用中啓動本應用,同時跳轉時也能夠傳遞參數。好比,能夠在網頁上添加一個連接,點擊這個連接後會自動打開對應的APP上。或者從一個 APP 跳轉到另外一個 APP,用的也是 URL scheme。好比微博或者微信的登陸或者分享之類的。在選擇登陸時就會跳到微信或者微博裏,等登陸了之後就能夠跳轉回去。

2.三、在Test1項目裏面設置白名單

<1>、解釋一下什麼是白名單:其實白名單是在 iOS9.0 之後提出的,它就是一個數組,裏面放的是其餘app的URL Scheme名字,在iOS9之前是不須要設置的,能夠直接用canOpenURL判斷是否能夠跳轉,可是在iOS9.0以後若是不添加白名單, openURL 是沒法判斷判斷是否能夠跳轉的。

提示:不想添加白名單是能夠的,其餘的app分享到微信,它確信你的app存在,就不須要在白名單添其餘app的URL Scheme,也就是不須要使用 canOpenURL判斷是否能夠跳轉 是否能夠跳轉

<2>、設置白名單,若是你要跳轉其餘的app,就要在本身的app的 info.plist 設置白名單,添加其餘app的URL Scheme,白名單的字段是:LSApplicationQueriesSchemes,下面咱們在 Test1添加白名單

image.png

白名單的設置

2.四、在Test1項目跳轉到Test2項目測試,代碼以下

咱們把上面 1.2中的<1>裏面的url換爲下面,在同一個手機上運行 Test1 和 Test2 兩個項目

1728484-64c6a9b23abfc7c2.gif

跳轉效果

OC 版本:後面的代碼都是  1.2中的<1>裏面的代碼

1

2

3

4

5

6

7

NSURL *url = [NSURL URLWithString:@"test2://"];

// 注意: 跳轉以前, 可使用 canOpenURL: 判斷是否能夠跳轉

if (![[UIApplication sharedApplication]canOpenURL:url]) {

     // 不能跳轉就不要往下執行了

     return;

}

------後面的代碼都是  1.2中的裏面的代碼

Swift 版本:後面的代碼都是  1.2中的<1>裏面的代碼

1

2

3

4

5

6

7

let url = URL(string: "test2://")

// 注意: 跳轉以前, 可使用 canOpenURL: 判斷是否能夠

if !UIApplication.shared.canOpenURL(url!) {

    // 不能跳轉就不要往下執行了

    return

}

-----後面的代碼都是  1.2中的裏面的代碼

拓展:看到上面效果,咱們就簡單的完成了app之間的跳轉,這也是一些三方在分享的時候要求咱們app設置白名單,你要分享到哪些平臺,你就要添加其餘平臺的 URL Scheme,這個不是隨便填寫的,其餘平臺設置的URL Scheme是什麼,就在白名單就要添加什麼,可不是本身隨意寫的

2.五、若是你想在Test2app再返回到Test1app,其實也就是反過來,在 Test2 的白名單裏面添加Test1的URL Scheme,在跳轉Test1的使用根據Test1的schmem用openURL返回,記得先用 canOpenURL判斷一下

 

提示:在作分享的時候咱們會檢測微信是否是安裝了,跳到微信後把微信給的URL Scheme也帶了過去,在從微信返回的時候不用再判斷 本身的app是否安裝了,直接用OpenURL返回便可,添加白名單的目的是爲了檢測其餘的app是否安裝,可不能夠跳轉;在本身的app跳轉其餘的app的必定要用canOpenURL檢測一下,微信不在白名單添加其餘app的URL Scheme的緣由是它確信你的app存在,不須要用canOpenURL判斷

2.六、經常使用白名單字段(更多的白名單字段在mob平臺iOS開發文檔查看)

新浪

1

2

3

4

5

6

sinaweibo,

sinaweibohd,

sinaweibosso,

sinaweibohdsso,

weibosdk,

weibosdk2.5

微信

1

2

wechat,

weixin

支付寶

1

2

alipay,

alipayshare

QQ

1

2

3

4

5

6

7

mqqOpensdkSSoLogin,

mqqopensdkapiV2,

mqqopensdkapiV3,

wtloginmqq2,

mqq,

mqqapi

timapi

提示:微信,新浪,QQ它們設置不少的Scheme的緣由是要根據這些不一樣的Scheme作什麼操做,好比根據Scheme跳轉到不一樣的界面等等

3、怎樣跳轉到不一樣界面?

3.一、再創建一個項目 Test3 ,給它添加一個 URL Scheme,再給Test3添加兩個控制器 ViewController2與ViewController3

image.png

再創建一個項目Test3,給它添加一個Url Scheme

提示: 一個項目能夠添加多個 URL Scheme,舉個例子,你在用支付寶支付,支付寶會給你一個 URL Scheme字符串,讓你添加到本身URL Types 裏面,到時候你在調用支付寶支付,在支付寶界面返回的時候用這個支付寶給你的 URL Scheme 返回;一樣,微信也會給你一個URL Scheme字符串,當你跳轉到微信裏面,微信裏面根據微信給你的URL Scheme返回到你的app;

  • 再解釋一下:爲何微信或者支付寶會給一個惟一的URL Scheme字符串,其目的是爲了防止,從他們的應用返回到本身的應用時出錯,根據URL Scheme字符串返回到本身的app的,若是手機裏面有兩個程序都有相同的一個 URL Scheme字符串,那麼就出問題了,它就不知道返回哪一個app了,其實若是遇到相同的URL Scheme,誰的app先安裝的,就返回到誰的app,這個我測試了

3.二、在Test3處理其餘Test1(或者其餘的app經過openURL)進來的判斷

OC 版本

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

// 即將過時,不建議使用(建議把這3個方法同時實現)

- (BOOL)application:(UIApplication *)application openURL:(NSURL *)url sourceApplication:(NSString *)sourceApplication annotation:(id)annotation

{

    [self dealopenURL:url];

    return YES;

}

 

-(BOOL)application:(UIApplication *)app openURL:(NSURL *)url options:(NSDictionary *)options{

    [self dealopenURL:url];

    return YES;

}

 

-(void)dealopenURL:(NSURL *)url{

     

    NSLog(@"協議=%@ IP或者是域名=%@ 路徑=%@ 參數=%@",url.scheme,url.host,url.path,url.query);

     

    // 1.獲取主控制器

    UINavigationController *rootNav = (UINavigationController *)self.window.rootViewController;

    // 拿到棧底的控制器

    ViewController *mainVc = [rootNav.childViewControllers firstObject];

    // 返回主控制器,防止屢次進入錯亂

    [rootNav popToRootViewControllerAnimated:NO];

     

    // 利用 URL : 統一資源定位符來判斷

    if ([url.path isEqualToString:@"/vc2"]) {

     

         ViewController2 *vc2 = [ViewController2 new];

         vc2.urlString = url.host;

         [mainVc.navigationController pushViewController:vc2 animated:YES];

     else if ([url.path isEqualToString:@"/vc3"]) {

   

         ViewController3 *vc3 = [ViewController3 new];

         vc3.urlString = url.host;

         [mainVc.navigationController pushViewController:vc3 animated:YES];

     }

}

Swift 版本

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

// 最新的

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

  

      dealopenURL(url: url as NSURL)

      return true

}

 

// 被遺棄的(最好兩個都用)

func application(_ application: UIApplication, open url: URL, sourceApplication: String?, annotation: Any) -> Bool {

  

      dealopenURL(url: url as NSURL)

      return true

}

 

// MARK:跳轉的處理

func dealopenURL(url:NSURL){

  

      let nav: UINavigationController! = window?.rootViewController as? UINavigationController

  

      nav.popToRootViewController(animated: false)

  

      let rootVC = nav.children[0]

  

      if url.path == "/vc2" {

      

           let vc2 = ViewController2()

           vc2.urlString = url.host

           rootVC.navigationController?.pushViewController(vc2, animated: true)

      

       }else if url.path == "/vc3"{

      

           let vc3 = ViewController3()

           vc3.urlString = url.host

           rootVC.navigationController?.pushViewController(vc3, animated: true)

       }

  

}

提示:上面跳轉是利用 URL的path(統一資源定位符)來判斷,我是把 帶過來的 URL Scheme 放到了 IP或者是域名 的位置

3.三、在Test1裏面的跳轉代碼

OC 版本

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

// 跳轉Test3的ViewController2

[self jumpUrl:@"test3://test1/vc2"];

// 跳轉Test3的ViewController3

[self jumpUrl:@"test3://test1/vc3"];

 

-(void)jumpUrl:(NSString *)urlStr{

 

      NSURL *url = [NSURL URLWithString:urlStr];

       

      // 注意: 跳轉以前, 可使用 canOpenURL: 判斷是否能夠跳轉

      if (![[UIApplication sharedApplication]canOpenURL:url]) {

            return;

      }

       

      if (@available(iOS 10.0, *)){

   

            [[UIApplication sharedApplication]openURL:url options:@{UIApplicationOpenURLOptionsSourceApplicationKey:@YES} completionHandler:^(BOOL success) {

       

                if (success) {

                        NSLog(@"10之後能夠跳轉url");

                }else{

                        NSLog(@"10之後不能夠跳轉url");

                }

            }];

       }else{

   

            BOOL success = [[UIApplication sharedApplication]openURL:url];

   

             if (success) {

                 NSLog(@"10之前能夠跳轉url");

             }else{

                NSLog(@"10之前不能夠跳轉url");

             }

        }

}

Swift 版本

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

jumpUrl(url: NSURL(string: "test3://test1/vc2")!)

jumpUrl(url: NSURL(string: "test3://test1/vc3")!)

 

func jumpUrl(url:NSURL){

  

     if !UIApplication.shared.canOpenURL(url as URL) {

          return

     }

  

     if #available(iOS 10.0, *) {

      

          UIApplication.shared.open(url as URL, options: [:]) { (success) in

          

              if (success) {

                   print("10之後能夠跳轉url")

              }else{

                   print("10之後不能完成跳轉")

              }

          }

     else {

     // Fallback on earlier versions

          let success = UIApplication.shared.openURL(url as URL)

          if (success) {

               print("10如下能夠跳轉")

          }else{

               print("10如下不能完成跳轉")

          }

     }

}

4、總結

4.一、實現兩個app之間跳轉的步驟

<1>、在各自的app裏面設置 URL scheme

<2>、在各自app的info.plist裏面添加字段LSApplicationQueriesSchemes,類型爲數組,數組中添加對方的 scheme 字符串(白名單的做用僅僅是iOS9.0方法canOpenURL要求的,由於咱們在跳轉前須要檢查下設備有沒有安裝將要跳轉的應用)

<3>、經過openURL 跳轉對方的 URL Scheme 便可

4.二、在最後我重複一下不少app跳轉到微信、支付寶、微博等等後,它們是怎麼作到再回到咱們的app的,首先咱們知道這些app裏面的白名單確定是沒有咱們的 URL Scheme

答:首選咱們在其餘平臺註冊本身的應用的時候,都會給咱們一個 URL Scheme 字符串,這個字符串咱們須要添加到咱們的 URL Scheme裏面,想必你們也知道了,咱們須要添加多個URL Scheme,由於微博,微信,支付寶都會給咱們一個惟一的 URL Scheme 字符串,惟一是爲了防止咱們跳轉到他們的app後再返回的時候出錯,還有其餘設備的 URL Scheme與咱們的同樣就會形成返回錯亂的狀況;再說支付寶微信在返回咱們的app的時候他們不去白名單裏面添加咱們的 URL Scheme,那是由於他們知道咱們的設備確定有咱們的app,否則怎麼會進入到微信和支付寶的?又有人說了我先進到微信,在彈出返回本身app和留在微信的界面彈出,我進入後臺去把本身的app卸載,再去微信點擊返回本身的app,其實我也是這麼測試的,可是隻要離開微信,返回本身app和留在微信的按鈕就會消失,因此微信返回其餘的app是不須要在白名單添加其餘app的 URL Scheme。

測試的demo

到此結束這篇文章,但願你可以經過這篇博客完全知道 URL Scheme做用和白名單是什麼以及如何跳轉在app之間跳轉。有不理解的地方寫下你的評論,看到後我會第一時間回答。

相關文章
相關標籤/搜索