和配件進行通訊
在iPhone OS 3.0及之後的系統上,External Accessory架構(ExternalAccessory.framework)提供了一種管道機制,使應用程式可以和iPhone或iPod touch裝置的配件進行通訊。通過這種管道,應用程式開發人員可以將配件層級的功能整合到自己的程式中。
請注意:下面部分將向您展示iPhone應用程式如何串連配件。如果您有興趣成為iPhone或iPod touch配件的開發人員,可以在http://developer.apple.com網站上找到相應的資訊。
為了使用External Accessory架構的介面,您必須將ExternalAccessory.framework加入到Xcode工程,並串連到相應的目標中。此外,還需要在相應的原始碼檔案的頂部包含一個#import <ExternalAccessory/ExternalAccessory.h>語句,才能訪問該架構的類和標頭檔。有關如何為工程添加架構的更多資訊,請參見Xcode工程管理指南中的工程中的檔案部分;有關External Accessory架構中類的一般資訊,請參見External Accessory架構參考。 配件的基礎
在和配件進行通訊之前,需要與配件的製造商緊密合作,理解配件提供的服務。製造商必須在配件的硬體中加入顯式的支援,才能和iPhone OS進行通訊。作為這種支援的一部分,配件必須支援至少一種命令協議,也就是支援一種定製的通訊模式,使配件和應用程式之間可以進行資料轉送。蘋果並不維護一個協議的註冊表,支援何種協議及是否使用其他製造商支援的定製或標準協議是由製造商自行決定的。
作為和配件製造商通訊的一部分,您必須找出給定的配件支援什麼協議。為了避免名字空間發生衝突,協議的名稱由反向的DNS字串來指定,形式是com.apple.myProtocol。這使得每個配件製造商都可以根據自己的需要定義協議,以支援不同的配件產品線。
應用程式通過開啟一個使用指定協議的會話來和配件進行通訊。開啟會話的方法是建立一個EASession類的執行個體,該類中包含NSInputStream和NSOutputStream對象,可以和配件進行通訊。通過這些流對象,應用程式可以向配件發送未經加工的資料包,以及接收來自配件的類似資料包。因此,您必須按照期望的協議來理解每個資料包的格式。 聲明應用程式支援的協議
能夠和配件通訊的應用程式應該在其Info.plist檔案中聲明支援的協議,使系統知道在相應的配件接入時,該應用程式可以被啟動。如果當前沒有應用程式可以支援接入的配件,系統可以選擇啟動App Store並指向支援該裝置的應用程式。
為了聲明支援的協議,您必須在應用程式的Info.plist檔案中包含UISupportedExternalAccessoryProtocols鍵。該鍵包含一個字串數組,用於標識應用程式支援的通訊協議。您的應用程式可以在這個列表中以任意順序包含任意數量的協議。系統並不使用這個列表來確定應用程式應該選擇哪個協議,而只是用它來確定應用程式是否能夠和相應的配件進行通訊。您的代碼需要在開始和配件進行對話時選擇適當的通訊協議。 在運行時串連配件
在配件接入系統並做好通訊準備之前,通過External Accessory架構無法看到配件。當配件變為可見時,您的應用程式就可以擷取相應的配件對象,然後用其支援的一或多個協議開啟會話。
共用的EAAccessoryManager對象為應用程式尋找與之通訊的配件提供主進入點。該類包含一個已經接入的配件對象的數組,您可以對其進行枚舉,看看是否存在應用程式支援的配件。EAAccessory對象中的絕大多數資訊(比如名稱、製造商、和型號資訊)都只是用於顯示。如果您要確定應用程式是否可以串連一個配件,必須看配件的協議,確認應用程式是否支援其中的某個協議。
請注意:多個配件對象支援同一協議是可能的。如果發生這種情況,您的代碼必須負責選擇使用哪個配件對象。
對於給定的配件對象,每次只能有一個指定協議的會話。EAAccessory對象的protocolStrings屬性包含一個字典,字典的鍵是配件支援的協議。如果您試圖用一個已經在使用的協議建立會話,External Accessory架構就會產生錯誤。
程式清單8-1展示了如何檢查接入配件的列表並從中取得應用程式支援的第一個配件。它為指定的協議建立一個會話,並對會話的輸入和輸出資料流進行配置。在這個方法返回會話對象時,已經完成和配件的串連,並可以開始發送和接收資料了。
程式清單8-1 建立和配件的通訊會話
在配置好輸入輸出資料流之後,最好一步就是處理和流相關的資料了。程式清單8-2展示了在委託方法中處理流事件的基本代碼結構。清單中的方法可以響應來自配件輸入輸出資料流的事件。當配件嚮應用程式發送資料時,事件發生表示有資料可供讀取;類似地,當配件準備好接收應用程式資料時,也通過事件來表示(當然,您並不一定要等到這個事件發生才向流寫出資料,應用程式也可以調用流的hasBytesAvailable方法來確認配件是否還能夠接收資料)。有關流及如何處理流事件的更多資訊,請參見Cocoa流編程指南。
程式清單8-2 處理流事件