本文由 Migrant 翻譯自 The Complete Tutorial on iOS/iPhone Custom URL Schemes,轉(zhuǎn)載請注明出處。
注意: 自從自定義 URL 的引入,本文始終是我博客中瀏覽量最大的文章。雖然大多數(shù)都相同,但依然有1些細(xì)微差別的變化。本文是原帖的重寫版,更新為最新的 iOS 和 Xcode 版本。
iPhone / iOS SDK 最酷的特性之1就是利用將其本身”綁定”到1個自定義 URL scheme 上,該 scheme 用于從閱讀器或其他利用中啟動本利用。
注冊自定義 URL Scheme
注冊自定義 URL Scheme 的第1步是創(chuàng)建 URL Scheme — 在 Xcode Project Navigator 中找到并點(diǎn)擊工程 info.plist 文件。當(dāng)該文件顯示在右側(cè)窗口,在列表上點(diǎn)擊鼠標(biāo)右鍵,選擇 Add Row:
向下轉(zhuǎn)動彈出的列表并選擇 URL types。
iOS Custom URL Scheme
點(diǎn)擊左側(cè)剪頭打開列表,可以看到 Item 0,1個字典實(shí)體。展開 Item 0,可以看到 URL Identifier,1個字符串對象。該字符串是你自定義的 URL scheme 的名字。建議采取反轉(zhuǎn)域名的方法保證該名字的唯1性,比如 com.yourCompany.yourApp。
urlScheme2a
點(diǎn)擊 Item 0 新增1行,從下拉列表當(dāng)選擇 URL Schemes,敲擊鍵盤回車鍵完成插入。
iOS Custom URL Scheme
注意 URL Schemes 是1個數(shù)組,允許利用定義多個 URL schemes。
iOS Custom URL Scheme
展開該數(shù)據(jù)并點(diǎn)擊 Item 0。你將在這里定義自定義 URL scheme 的名字。只需要名字,不要在后面追加 :// — 比如,如果你輸入 iOSDevApp,你的自定義 url 就是 iOSDevApp://
iOS Custom URL Scheme
此時,全部定義以下圖:
iOS Custom URL Scheme
雖然我贊同 Xcode 使用描寫性的名字的目的,不過看到創(chuàng)建的實(shí)際的 key 也是非常有用的。這里有1個方便的技能,右鍵點(diǎn)擊 plist 并選擇 Show Raw Keys/Values,就可以看到以下效果:
iOS Custom URL Scheme
還有另外一種有用的輸出格式,XML,由于可以非常容易的看到字典和原始數(shù)組及其包括的實(shí)體的結(jié)構(gòu)。點(diǎn)擊 plist 并選擇 Open As – Source Code:
iPhone Custom URL Scheme
從 Safari 中調(diào)用自定義 URL Scheme
定義了 URL scheme,我們可以運(yùn)行1個快速測試來驗(yàn)證利用是不是如我們所期望的被調(diào)用。在這之前,我創(chuàng)建了1個準(zhǔn) UI 以辨別帶有自定義 URL 的利用。該利用只有1個 UILabel,帶有文本 “App With Custom URL”。下載源代碼
iOS App with Custom URL
使用摹擬器調(diào)用利用的步驟:
- 在 Xcode 中運(yùn)行利用
- 1旦利用被安裝,自定義 URL scheme 就會被注冊
- 通過摹擬器的硬件菜單當(dāng)選擇 Home 來關(guān)閉利用
- 啟動 Safari
- 在閱讀器地址欄輸入之前定義的 URL scheme(以下)
Call Custom URL Scheme from Safari
此時 Safari 將會關(guān)閉,利用會被帶回到前臺。慶祝你剛剛使用自定義 URL scheme 調(diào)用了1個 iPhone 利用。
從另外一個 iPhone 利用中調(diào)用自定義 URL Scheme
讓我們看看如何從另外一個利用中調(diào)用自定義 URL scheme。我又創(chuàng)建了1個非常簡單的 iPhone 利用,它只有1個 UILabel 和1個 UIButton — 前者顯示了1段信息,告知你這個利用將要通過自定義 URL scheme 來調(diào)用另外一個利用,按鈕則開始這個行動。下載源代碼
iPhone app that call Custom URL Scheme
buttonPressed 方法中的代碼處理 URL 調(diào)用:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
| - (void)buttonPressed:(UIButton *)button
{
NSString *customURL = @"iOSDevTips://";
if ([[UIApplication sharedApplication]
canOpenURL:[NSURL URLWithString:customURL]])
{
[[UIApplication sharedApplication] openURL:[NSURL URLWithString:customURL]];
}
else
{
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"URL error"
message:[NSString stringWithFormat:
@"No custom URL defined for %@", customURL]
delegate:self cancelButtonTitle:@"Ok"
otherButtonTitles:nil];
[alert show];
}
}
|
第 5 行代碼檢查自定義 URL 是不是被定義,如果定義了,則使用 shared application 實(shí)例來打開 URL (第 8 行)。openURL: 方法啟動利用并將 URL 傳入利用。在此進(jìn)程中,當(dāng)前的利用被退出。
通過自定義 URL Scheme 向利用傳遞參數(shù)
有時你需要通過自定義 URL 向利用中傳遞參數(shù)。讓我們看看該如何完成這個工作。
NSURL 作為從1個利用調(diào)用另外一個的基礎(chǔ),遵守 RFC 1808 (Relative Uniform Resource Locators) 標(biāo)準(zhǔn)。 因此你所熟習(xí)的基于網(wǎng)頁內(nèi)容的 URL 格式在這里也適用。
在自定義了 URL scheme 的利用中,app delegate 必須實(shí)現(xiàn)以下方法:
1
2
3
4
| - (BOOL)application:(UIApplication *)application
openURL:(NSURL *)url
sourceApplication:(NSString *)sourceApplication
annotation:(id)annotation
|
從1個利用傳遞參數(shù)到另外一個的竅門是通過 URL。例如,假定我們使用以下的 URL scheme,想傳遞1個名為 “token”的參數(shù)和1個標(biāo)識注冊狀態(tài)的標(biāo)志,我們可以像這樣創(chuàng)建1個 URL:
1
| NSString *customURL = @"iOSDevTips://?token=123abct®istered=1";
|
在 web 開發(fā)中,字符串 ?token=123abct®istered=1 被稱作查詢詢串(query string).
在被調(diào)用(設(shè)置了自定義 URL)的利用的 app delegate 中,獲得參數(shù)的代碼以下:
1
2
3
4
5
6
7
8
9
| - (BOOL)application:(UIApplication *)application openURL:(NSURL *)url
sourceApplication:(NSString *)sourceApplication annotation:(id)annotation
{
NSLog(@"Calling Application Bundle ID: %@", sourceApplication);
NSLog(@"URL scheme:%@", [url scheme]);
NSLog(@"URL query: %@", [url query]);
return YES;
}
|
以上代碼在利用被調(diào)用時的輸出為:
1
2
3
| Calling Application Bundle ID: com.3Sixty.CallCustomURL
URL scheme:iOSDevTips
URL query: token=123abct®istered=1
|
注意 “Calling Application Bundle ID”,你可以用這個來確保只有你定義的利用可以與你的利用直接交互。
讓我們改變1下代碼,來驗(yàn)證發(fā)起調(diào)用的利用的 Bundle ID 是不是合法:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
| - (BOOL)application:(UIApplication *)application openURL:(NSURL *)url
sourceApplication:(NSString *)sourceApplication annotation:(id)annotation
{
// Check the calling application Bundle ID
if ([sourceApplication isEqualToString:@"com.3Sixty.CallCustomURL"])
{
NSLog(@"Calling Application Bundle ID: %@", sourceApplication);
NSLog(@"URL scheme:%@", [url scheme]);
NSLog(@"URL query: %@", [url query]);
return YES;
}
else
return NO;
}
|
有1點(diǎn)要特別注意,你不能禁止其他利用通過自定義 URL scheme 調(diào)用你的利用,但是你可以跳過后續(xù)的操作并返回 NO,就像上面的代碼那樣。也就是說,如果你想禁止其它利用調(diào)用你的利用,創(chuàng)建1個與眾不同的 URL scheme。雖然這不能保證你的利用不會被調(diào)用,但最少大大下降了這類可能性。
自定義 URL Scheme 示例工程
我意想到依照本文的每步做下來還是有1點(diǎn)復(fù)雜的。我做好了兩個非常基礎(chǔ)的 iOS 利用,1個自定義了 URL scheme,另外一個則去調(diào)用它,并傳遞了1個比較短的參數(shù)列表(query string)。這些是體驗(yàn)自定義 URL 的很好的入門點(diǎn)。
- Download Xcode project for app with Custom URL scheme
- Download Xcode project for app to call custom URL scheme
其它資源
How to Properly Validate URL Parameters URL Scheme Reference Docs