前言
通常來說它褪,手機APP相當于是一座座信息孤島茫打,APP之間不能相互通信老赤;但有些場景的確需要源葫,讓別的APP來喚醒自己息堂,例如支付寶為別的APP提供支付荣堰,又或者需要在一個營銷網(wǎng)頁中打開APP的指定頁面, 這時就可以利用定義自己的URL Schemes頁面跳轉(zhuǎn)協(xié)議
來實現(xiàn)。
一.什么是URL Schemes
1.URL Schemes單詞理解
- URL, 我們都很清楚振坚,
https://www.apple.com
就是一個URL薇搁,我們叫它鏈接或者網(wǎng)址。 - Schemes, 表示的是一個 URL 中的一個位置——最初始的位置渡八,即 ://之前的那段字符啃洋。比如
https://www.apple.com
這個網(wǎng)址的 Schemes 是 https。
2.簡單理解
例如微信打開掃一掃的功能的Schemes是:weixin://dl/scan
屎鳍;我們可以理解宏娄,在以本地應(yīng)用為主的 iOS 上,我們可以像定位一個網(wǎng)頁一樣逮壁,用一種特殊的 URL 來定位一個應(yīng)用甚至應(yīng)用里某個具體的功能孵坚。而定位這個應(yīng)用的窥淆,就是這個應(yīng)用URL 的 Schemes 部分卖宠。
3.APP和網(wǎng)頁的對比
你可以完全按照理解一個網(wǎng)頁的 URL (也就是它的網(wǎng)址)的方式來理解一個 iOS 應(yīng)用的 URL,拿蘋果的網(wǎng)站和 iOS 上的微信來做個簡單對比:
網(wǎng)頁(蘋果) | iOS 應(yīng)用(微信) | |
---|---|---|
網(wǎng)站首頁/打開應(yīng)用 | https://www.apple.com |
weixin:// |
子頁面/具體功能 |
https://www.apple.com/mac (Mac頁面) |
weixin://dl/moments (朋友圈) |
在這里忧饭,https://www.apple.com
和 weixin://
都聲明了這是誰的地盤扛伍。然后在 https://www.apple.com
后面加上 /mac
就跳轉(zhuǎn)到從屬于 https://www.apple.com
的一個網(wǎng)頁(Mac 頁)上;同樣词裤,在 weixin://
后面加上 dl/moments
就進入了微信的一個具體的功能——朋友圈蜒秤。
二.iOS中如何使用URL Schemes
1.注冊URL Schemes
為自己的項目Bank注冊一個URL Schemes汁咏,支持被喚醒。
Identifier
是自定義的 URL schemes 的名字作媚,一般采用反轉(zhuǎn)域名的方法保證該名字的唯一性攘滩,比如 com.lwin.www,不過在iOS中打開一個應(yīng)用程序只需要拿到這個應(yīng)用程序的協(xié)議頭URL Schemes
即可,所以我們只需配置應(yīng)用程序的協(xié)議頭即可纸泡。一個應(yīng)用是可以有多個URL Schemes的漂问。
2.使用
a.喚醒應(yīng)用
在另外一個APP喚起B(yǎng)ank
- (IBAction)open:(id)sender {
if(![[UIApplication sharedApplication] canOpenURL:[NSURL URLWithString:@"LBSAPP://"]]) {
return;
}
//不帶參數(shù)
NSString * wslUrlScheme = @"LBSAPP://product";
//如果參數(shù)含有特殊字符或漢字,需要轉(zhuǎn)碼女揭,否則這個URL不合法蚤假,就會喚起失敗吧兔;參數(shù)字符串的格式可以自定義磷仰,只要便于自己到時候解析就行;
NSString * parameterStr = [@"?name=手機&id=1" stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
//LBSAPP://product?name=手機&id=1
NSURL * url = [NSURL URLWithString:[wslUrlScheme stringByAppendingString:parameterStr]];
//iOS 10以下
// [[UIApplication sharedApplication] openURL:url];
//iOS 10以上
[[UIApplication sharedApplication] openURL:url options:nil completionHandler:^(BOOL success) {
}];
}
如果點擊調(diào)用時控制臺報錯:
-canOpenURL: failed for URL: "LBSAPP://" - error: "This app is not allowed to query for scheme lbsapp"
這是因為在iOS9以后境蔼,如果使用 canOpenURL:方法灶平,該方法所涉及到的URL Schemes必須在"Info.plist"中將它們列為白名單,否則不能使用箍土。
b.被喚醒之后的處理
- 在AppDelegate里面的UIApplicationDelegate代理方法做監(jiān)聽逢享。
#import "AppDelegate.h"
#import "ViewController.h"
#import "SchemesManager.h"
@interface AppDelegate ()
@end
@implementation AppDelegate
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
self.window.backgroundColor = [UIColor whiteColor];
self.window.rootViewController = [[ViewController alloc] init];;
[self.window makeKeyAndVisible];
//第三方應(yīng)用打開本應(yīng)用啟動
if(launchOptions[UIApplicationLaunchOptionsURLKey] != nil){
[self application:application handleOpenURL:launchOptions[UIApplicationLaunchOptionsURLKey]];
}
// Override point for customization after application launch.
return YES;
}
/**
iOS 9.0 以下 程序運行過程中調(diào)用
*/
- (BOOL)application:(UIApplication *)application handleOpenURL:(NSURL *)url{
return [SchemesManager handleOpenURL:url];
}
/**
iOS 9.0 以下 程序運行過程中調(diào)用
*/
- (BOOL)application:(UIApplication *)application openURL:(NSURL *)url sourceApplication:(nullable NSString *)sourceApplication annotation:(id)annotation{
return [SchemesManager handleOpenURL:url];
}
/**
iOS 9.0 之后
三方喚起本程序后執(zhí)行的方法
return YES 表示允許喚起本程序 程序運行過程中調(diào)用
*/
- (BOOL)application:(UIApplication *)app openURL:(NSURL *)url options:(NSDictionary<UIApplicationOpenURLOptionsKey, id> *)options{
return [SchemesManager handleOpenURL:url];
}
@end
2.可以單獨寫一個工具類來處理URL Schemes。
#import "SchemesManager.h"
#import <UIKit/UIKit.h>
@implementation SchemesManager
+ (BOOL)handleOpenURL:(NSURL *)url {
NSMutableString *str = [NSMutableString string];
[str appendFormat:@"URL scheme:%@ \n\n", [url scheme]];
[str appendFormat:@"URL host:%@ \n\n", [url host]];
[str appendFormat:@"URL absoluteString:%@ \n\n", [url absoluteString]];
NSURLComponents *comp = [NSURLComponents componentsWithURL:url resolvingAgainstBaseURL:YES];
if(comp) {
[str appendString:@"queryItems:\n"];
NSArray<NSURLQueryItem *> *queryItems = [comp queryItems];
for (int i=0; i<queryItems.count; i++) {
NSURLQueryItem *item = queryItems[i];
[str appendFormat:@"%@=%@ ", item.name, item.value];
if(i<queryItems.count-1) {
[str appendString:@","];
}
}
}
UIAlertView *alertView=[[UIAlertView alloc] initWithTitle:@"分享" message:str delegate:self cancelButtonTitle:nil otherButtonTitles:@"分享完成", nil];
[alertView show];
return YES;
}
+ (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex{
//返回URL scheme = bank234280的主應(yīng)用
NSURL * url = [NSURL URLWithString:@"bank234280://success"];
[[UIApplication sharedApplication] openURL:url options:nil completionHandler:^(BOOL success) {
}];
}
@end
3.注意
如果使用了Scene吴藻,需要在SceneDelegate的代理方法
- (void)scene:(UIScene *)scene openURLContexts:(NSSet<UIOpenURLContext *> *)URLContexts
去處理URL Schemes :
@implementation SceneDelegate
- (void)scene:(UIScene *)scene openURLContexts:(NSSet<UIOpenURLContext *> *)URLContexts {
UIOpenURLContext *urlCtx = [URLContexts allObjects].firstObject;
[SchemesManager handleOpenURL:urlCtx.URL];
}
@end