本文是Intermediate iOS 11 Programming with Swift 4系列?的 第 十七 篇.
AirDrop是蘋果對文件和數據共享的回應。在iOS 7之前,用戶必須依靠第三方應用程序(如Bump)在iOS設備之間共享文件。自iOS 7發布以來,iOS用戶可以使用名為AirDrop的功能與附近的iOS設備共享數據。簡而言之,該功能允許你分享照片、視頻、聯系人、url、存折、應用商店的應用列表、iTunes商店的媒體列表、地圖中的位置等等.
如果你能把AirDrop整合到你的應用程序中,豈不是很棒?”您的用戶可以輕松地與附近的設備共享照片、文本文件或任何其他類型的文檔。iOS SDK中綁定的UIActivityViewController類使您可以輕松地將AirDrop嵌入到應用程序中。該類保護您不受文件共享的底層細節的影響。您所需要做的就是告訴類您想要共享的對象,控制器處理其余的對象。在這一章中,我們將演示UIActivityViewController的使用,以及如何使用它通過空投來共享圖像和文檔.
要激活AirDrop,只需打開控制中心并點擊AirDrop。根據您希望與誰共享數據,您可以選擇Contact Only或Everyone。如果您選擇了聯系人唯一選項,您的設備將只會被列出在聯系人中的人發現。如果選擇了Everyone選項,您的設備可以從任何其他設備中發現。
AirDrop使用藍牙掃描附近的設備。當通過藍牙建立連接時,它將創建一個特殊的Wi-Fi網絡,將兩個設備連接在一起,從而實現更快的數據傳輸。這并不意味著你需要將設備連接到Wi-Fi網絡才能使用AirDrop;你的WiFi只要打開就可以進行數據傳輸。
例如,假設你想將照片應用程序中的一張照片從一個iPhone傳到另一個iPhone。假設您已經在兩個設備上啟用了AirDrop,那么您可以通過點擊屏幕左下角的share按鈕(帶有向上箭頭的按鈕)與另一個設備共享照片。
在AirDrop區,您應該看到有資格共享的設備的名稱。當屏幕關閉時,AirDrop是不可用的,所以請確保接收端設備打開。然后,您可以選擇要與之共享照片的設備。在接收設備上,您應該看到照片的預覽和確認請求。接收方可以接受或拒絕接收圖像。如果他們選擇了accept選項,照片就會被傳送并自動保存在相機膠卷中.
AirDrop不僅適用于照片應用程序,你還可以在聯系人、iTunes、應用商店和Safari瀏覽器中分享物品,舉幾個例子。如果你是AirDrop新手,你現在應該對AirDrop的工作原理有了更好的了解。
讓我們看看如何將AirDrop集成到一個應用程序中,以共享各種類型的數據.
UIActivityViewController 概述
你可能會認為實現AirDrop功能需要很多行代碼。相反,只需要幾行代碼就可以嵌入AirDrop。UIKit框架提供的UIActivityViewController類簡化了集成過程。
UIActivityViewController類是一個標準的視圖控制器,它提供了一些標準的服務,例如將項目復制到剪貼板、將內容共享到社交媒體站點、通過消息發送項目等。在iOS 8或更高版本中,activity view controller進一步增加了對app擴展的支持.
這個類很容易使用。假設您有一個使用AirDrop共享的對象數組。你需要做的就是用對象數組創建UIActivityViewController的一個實例,然后在屏幕上顯示控制器.
```
let ?objectsToShare = [fileURL]
let activityController = UIActivityController(activityItems: objectsToShare, applicationActivities: nil)?present(activityController, animated: true, completion: nil)
```
如您所見,只需幾行代碼,您就可以使用AirDrop選項打開一個活動視圖。當檢測到附近的設備時,如果選擇共享數據,活動控制器將自動顯示該設備并處理數據傳輸。默認情況下,活動控制器包括消息、Flickr和新浪微博等共享選項。或者,您可以通過設置控制器的exclude activitytypes屬性來排除這些類型的活動.?
下面是簡單的代碼示例:
```
let excludedActivities = [UIActivityType.postToWeibo, UIActivityType.message, ?UIActivityType.postToTencentWeibo]
activityController.excludeActiviTypes = ?excludedActivities
```
您可以使用UIActivityViewController來共享不同類型的數據,包括字符串、UIImage和URL。您不僅可以使用URL共享鏈接,而且還允許開發人員通過使用文件URL傳輸任何類型的文件。當另一臺設備接收到數據時,它會根據數據類型自動打開app。所以,如果一個UIImage對象被傳輸,接收到的圖像會顯示在Photos app中。當你傳輸一個PDF文件時,另一個設備會在Safari中打開它。如果你只是共享一個字符串對象,數據就會顯示在Notes應用程序中.
當另一臺設備接收到數據時,它會根據數據類型自動打開app。所以,如果一個UIImage對象被傳輸,接收到的圖像會顯示在Photos app中。當你傳輸一個PDF文件時,另一個設備會在Safari中打開它。如果你只是共享一個字符串對象,數據就會顯示在Notes應用程序中.?
Demo App
為了讓你更好地理解UIActivityViewController和AirDrop,我們將像往常一樣構建一個演示應用。同樣,這個應用程序非常簡單。啟動后,您將看到一個表視圖,其中列出了一些文件,包括圖像文件、PDF文件、文檔和Powerpoint。您可以單擊文件并在detail視圖中查看其內容。在content視圖中,在屏幕底部有一個工具欄。點擊工具欄上的分享操作按鈕,會彈出AirDrop選項,可以與附近的設備分享文件.
在這里下載簡單的代碼.
項目模板已經包含storyboard和自定義類。表視圖控制器與AirDropTableViewController關聯,而細節視圖控制器與DetailViewController關聯。DetailViewController對象簡單地使用WKWebView來顯示文件內容。我們要做的是在細節視圖中添加一個共享按鈕來激活AirDrop.
添加Share Button
首先,讓我們去storyBoard。將工具欄從對象庫拖動到詳細視圖控制器,并將其放置在控制器的底部。選擇默認的bar按鈕項,并在屬性檢查器中將其標識符更改為Action.
接下來. 給toolBar 添加約束 .否則,它將無法在某些設備上正常顯示。現在,選擇工具欄。在自動布局欄中,單擊Add new constraints按鈕來添加一些間距約束。設置左、右和底部的間距值為0。單擊Add 3 Constraints來添加空間約束。
新添加的約束確保工具欄始終顯示在視圖控制器的底部。回到DetailViewController。為共享操作添加一個動作方法:
@IBAction func share (sender: AnyObject) {
? }
回到 Main.storyboard 連接 Share Button 方法
?AirDrop?實現文件共享
現在已經完成了UI 方面的準備, 接著要完成代碼部分. 在DetailController類里面補全 Share 方法.
@IBAction func share(sender: AnyObject) {
? ? if let fileURL = fileToURL(file: filename) {
? ? ? ? let objectsToShare = [fileURL]
? ? ? ? let activityController = UIActivityViewController(activityItems: objectsToShare, applicationActivities: nil)
? ? ? ? let excludedActivities = [UIActivityType.postToFlickr, UIActivityType.postToWeibo, UIActivityType.message, UIActivityType.mail, UIActivityType.print, UIActivityType.copyToPasteboard, UIActivityType.assignToContact, UIActivityType.saveToCameraRoll, UIActivityType.addToReadingList, UIActivityType.postToFlickr, UIActivityType.postToVimeo, UIActivityType.postToTencentWeibo]
? ? ? ? activityController.excludedActivityTypes = excludedActivities
?? ? ? ?present(activityController, animated: true, completion: nil)
?? }
}
代碼都很簡單, 這里不翻譯了.
DetailViewController的filename屬性包含要共享的文件名。在將文件傳遞給活動視圖控制器之前,我們需要首先找到文件的完整路徑。在項目模板中,我已經為此目的包含了一個helper方法
?func fileToURL(file: String) -> URL? {
? ? // Get the full path of the file
? ? let fileComponents = file.components(separatedBy: ".")
? ? if let filePath = Bundle.main.path(forResource: fileComponents[0], ofType: fileComponents[1]) {
? ? ? ? return URL(fileURLWithPath: filePath)
? ? }
? ? return nil
}
這個代碼也很簡單, 例如, 這個image 文件 glico.jpg , 得到的完整路徑如下:?
file:///Users/simon/Library/Developer/CoreSimulator/Devices/7DC35502-54FD-447B-B10F-2B7B0FD5BDDF/data/Containers/Bundle/Application/01827504-4247-4C81-9DE5-02BEAE94C7E5/AirDropDemo.app/glico.jpg
文件URL根據您正在運行的設備而異。但是URL應該以文件:// protocol開始。通過文件URL對象,我們創建了相應的數組并將其傳遞給UIActivityViewController進行AirDrop共享.
創建一個 AirDrop Demo
這就是實現AirDrop所需要的全部。現在可以測試應用程序了。編譯并在真機上運行它。當然,你需要一個真正的設備來測試AirDrop ?共享特性在模擬器中無法工作
此外,你需要至少兩臺iOS設備或一臺Mac電腦來測試共享功能
第一次運行, 選擇文件, 確保兩臺設備都支持AirDrop
iPad?
如果你在iPad 上運行 會報錯: ?
2017-11-14 12:26:32.284152+0800 AirDropDemo[28474:5821534] *** Terminating app due to uncaught exception 'NSGenericException', reason: 'Your application has presented a UIActivityViewController (<UIActivityViewController: 0x7f9d4985d400>). In its current trait environment, the modalPresentationStyle of a UIActivityViewController with this style is UIModalPresentationPopover. You must provide location information for this popover through the view controller's popoverPresentationController. You must provide either a sourceView and sourceRect or a barButtonItem. If this information is not known when you present the view controller, you may provide it in the UIPopoverPresentationControllerDelegate method -prepareForPopoverPresentation.
在iPad上,UIActivityViewController顯示為彈窗而不是動作表單。在這種情況下,您必須為彈出式表示控制器指定源視圖或源欄按鈕項。對于我們的演示應用程序,當用戶單擊Share按鈕時,我們希望從按鈕中顯示彈出窗口。為此,在DetailViewController中為Share按鈕創建一個outlet變量。在接口生成器中快速建立連接:
@IBOutlet ?var actionButton : UIBarButtonItem !
接下來, ?回到 DetailViewController.swift ,?在調用share(sender:)方法的present(activityController, animated: true, completion: nil)之前插入以下代碼 :
if let popOverController = activityController.popoverPresentationController {
? ? popOverController.barButtonItem = actionButtonItem
}
當一個設備(例如iPad)使用彈窗來顯示UIActivityViewController時,popoverPresentationController屬性有一個值。因此,我們測試屬性是否包含值,然后將其barButtonItem屬性設置為Share按鈕。?如果你在iPad上運行這個演示程序,你會得到這樣的結果:
類型標識符
當你與另一個iOS設備分享圖片時,接收端會自動打開圖片應用并保存圖片。如果您傳輸PDF或文檔文件,接收設備可能會提示您選擇一個應用程序打開該文件,或者直接在iBooks中打開它。iOS如何知道特定數據類型使用哪個應用程序?
UTIs(統一類型標識符的縮寫)是蘋果在系統中標識數據的答案。簡而言之,統一類型標識符是特定類型數據或文件的唯一標識符。例如,com.adobe。pdf表示pdf文檔和公共文檔。png表示一個png圖像。詳細文檔點擊 --->?蘋果 UTIs. ??一個能夠打開特定類型文件的應用程序將被注冊到iOS中處理該UTI。因此,每當打開這類文件時,iOS就會將該文件交給特定的應用程序.?
該系統允許多個應用程序注冊同一個UTI。在這種情況下,iOS會提示用戶打開文件所需的應用程序列表。例如,當您共享一個文檔時,接收設備將提示一個菜單供用戶選擇.
總結
AirDrop是一個非常方便的功能,它提供了一種在設備之間共享數據的好方法。最棒的是,內置的UIActivityViewController讓開發者很容易在他們的應用程序中添加AirDrop支持。正如用Demo看到的,您只需要幾行代碼就可以實現該特性.?