為保存而標(biāo)記視圖控制器
UIKit只保存那些restorationIdentifier屬性包含有有效字符串的視圖控制器對象。在初始化這些視圖控制器的時候,就對此屬性進行賦值。如果是從storyboard或nib文件上加載的視圖控制器,可以直接在這兩處設(shè)置恢復(fù)標(biāo)識符。
為恢復(fù)標(biāo)識符選擇恰當(dāng)?shù)闹凳呛苤匾脑钏啤T诨謴?fù)過程期間,代碼使用恢復(fù)標(biāo)識符來決定視圖控制器是取回還是創(chuàng)建瑞你。如果每個視圖控制器都基于不同的類酪惭,那你可以使用類名來作為恢復(fù)標(biāo)識符。但是者甲,如果你的視圖控制器層級結(jié)構(gòu)包含多個實例來自同一個類春感,你就需要根據(jù)每個視圖的用途來選擇不同的名字。
當(dāng)UIKit要求你提供一個視圖控制器的時候虏缸,它會提供視圖控制器對象的恢復(fù)路徑給你鲫懒。恢復(fù)路徑是視圖控制器層次結(jié)構(gòu)中從根視圖控制器到當(dāng)前對象的一系列恢復(fù)標(biāo)識符刽辙。例如窥岩,想象你有一個恢復(fù)標(biāo)識符為TabBarControllerID的選項欄控制器,它的第一個選項卡包含一個標(biāo)識符為NavControllerID導(dǎo)航控制器宰缤,該導(dǎo)航控制器的根視圖控制器的標(biāo)識符為MyViewController颂翼。那么該根視圖控制器的完整恢復(fù)路徑是TabBarControllerID/NavControllerID/MyViewController。
恢復(fù)路徑對于每個對象必須是獨一無二的慨灭。如果視圖控制器擁有兩個子視圖控制器朦乏,那么這兩個子視圖控制器必定有不同的恢復(fù)標(biāo)識符。但是兩個有著不同父對象的視圖控制器可以有一個相同的恢復(fù)標(biāo)識符氧骤,這時因為路徑是不同的呻疹。一些UIKit視圖控制器,例如導(dǎo)航控制器筹陵,自動消除子視圖控制器的歧義刽锤,允許你為每個子視圖控制器使用相同的恢復(fù)標(biāo)識符镊尺。更多關(guān)于給定視圖控制器的行為,參見相關(guān)的類參考姑蓝。
在恢復(fù)的時候鹅心,你使用提供的恢復(fù)路徑來決定哪個視圖控制器返回給UIKit吕粗。更多關(guān)于使用恢復(fù)標(biāo)識符以及恢復(fù)路徑來恢復(fù)視圖控制器的信息纺荧,參見Restoring Your View Controllers at Launch Time。
在啟動時恢復(fù)視圖控制器
在恢復(fù)過程期間颅筋,UIKit要求應(yīng)用創(chuàng)建(或定位)視圖控制器的對象宙暇,這些對象構(gòu)成了你保存的用戶界面。UIKit在視圖定位視圖控制器的時候會遵循如下過程:
- 如果視圖控制器有一個恢復(fù)類议泵,UIKit要求這個類提供視圖控制器占贫。UIKit調(diào)用相應(yīng)恢復(fù)類的viewControllerWithRestorationIdentifierPath:coder:方法來取回視圖控制器。如果該方法返回nil先口,則假定應(yīng)用程序不想重新創(chuàng)建該視圖控制器型奥,UIKit停止搜尋它。
- 如果視圖控制器沒有恢復(fù)類碉京,UIKit要求應(yīng)用委托來提供視圖控制器厢汹。UIKit調(diào)用應(yīng)用委托的application:viewControllerWithRestorationIdentifierPath:coder:方法來查找沒有恢復(fù)類的視圖控制器。如果該方法返回nil谐宙,UIKit會嘗試隱式的繼續(xù)查找該視圖控制器烫葬。
- 如果具有正確的恢復(fù)路徑視圖控制器已存在,UIKit將使用該對象凡蜻。如果應(yīng)用在啟動時創(chuàng)建視圖控制器(無論是編碼方式還是從資源文件加載)并將恢復(fù)標(biāo)識符分配給它們搭综,UIKit可以通過恢復(fù)路徑隱式的找到它們。
- 如果視圖控制器最初是從storyboard文件加載的划栓,UIKit使用保存的storyboard信息來定位和創(chuàng)建它兑巾。UIKit把關(guān)于視圖控制器的storyboard的信息保存到恢復(fù)存檔中。在恢復(fù)的時候忠荞,如果沒有通過其他方式找到視圖控制器蒋歌,它將使用這些信息來定位相同的storyboard文件,并實例化相應(yīng)的視圖控制器钻洒。
值得注意的是奋姿,如果你給視圖控制器指定了恢復(fù)類,UIKit就不會嘗試隱式的查找視圖控制器了素标。如果恢復(fù)類的viewControllerWithRestorationIdentifierPath:coder:方法返回nil称诗,UIKit停止嘗試定位視圖控制器。這可以讓你控制是否真創(chuàng)建視圖控制器头遭。如果你沒有指定恢復(fù)類寓免,UIKit會盡可能的查找視圖控制器癣诱,并根據(jù)需要從應(yīng)用的storyboard文件創(chuàng)建它。
如果你選擇使用恢復(fù)類袜香,就要實現(xiàn)viewControllerWithRestorationIdentifierPath:coder:類來創(chuàng)建該類的新實例撕予,執(zhí)行最小化的初始化,并返回生成的對象蜈首。代碼清單5-1展示了一個如何使用該方法從storyboard加載視圖控制器的例子实抡。因為這個視圖控制器最初是從storyboard加載的,所以這個方法使用UIStateRestorationViewControllerStoryboardKey鍵來從歸檔中獲取storyboard欢策。注意這個方法不會嘗試配置這個視圖控制器的數(shù)據(jù)字段吆寨。當(dāng)視圖控制器的狀態(tài)被解碼的時候才發(fā)生此步驟。
代碼清單5-1 在恢復(fù)期間創(chuàng)建一個新的視圖控制器
+ (UIViewController*) viewControllerWithRestorationIdentifierPath:(NSArray *)identifierComponents
coder:(NSCoder *)coder {
MyViewController* vc;
UIStoryboard* sb = [coder decodeObjectForKey:UIStateRestorationViewControllerStoryboardKey];
if (sb) {
vc = (PushViewController*)[sb instantiateViewControllerWithIdentifier:@"MyViewController"];
vc.restorationIdentifier = [identifierComponents lastObject];
vc.restorationClass = [MyViewController class];
}
return vc;
}
當(dāng)創(chuàng)建新視圖控制器的時候踩寇,重新分配恢復(fù)標(biāo)識符和恢復(fù)類啄清,如上例所示,是一個很好的習(xí)慣俺孙。取得恢復(fù)標(biāo)識符的最簡單方法是取出identifierComponents數(shù)組的最后一個元素辣卒,并把它分配給你的視圖控制器。
對于在啟動的時候已經(jīng)從應(yīng)用的主storyboard文件加載的對象,不用創(chuàng)建每個對象的新實例。相反胚想,應(yīng)該實現(xiàn)應(yīng)用委托的application:viewControllerWithRestorationIdentifierPath:coder:方法喷市,并使用它來返回合適的對象或讓UIKit隱式的找到這些對象。
視圖控制器狀態(tài)的編碼與解碼
對于每個要保存的對象的狀態(tài),UIKit調(diào)用對象的encodeRestorableStateWithCoder:方法,給對象一個保存狀態(tài)的機會。在解碼過程期間票罐,調(diào)用decodeRestorableStateWithCoder:方法,把狀態(tài)匹配給對象泞边。實現(xiàn)這些方法對于視圖控制器不是必須的该押,但是推薦使用。你可以對以下信息類型使用它們進行保存和恢復(fù)阵谚。
- 任何被用于顯示的數(shù)據(jù)的引用(而不是數(shù)據(jù)本身)
- 對于容器視圖控制器蚕礼,它的子視圖控制器的引用
- 關(guān)于當(dāng)前選擇的信息
- 對于具有用戶配置視圖的視圖控制器,關(guān)于視圖當(dāng)前配置的信息
在你的編碼和解碼方法中梢什,你可以對編碼器支持的所有值進行編碼奠蹬,包括其他對象。對于初了視圖和視圖控制器以外的所有對象嗡午,必須采用NSCoding協(xié)議囤躁,并使用這個協(xié)議的方法來寫入狀態(tài),對于視圖和視圖控制器,編碼器不使用NSCoding協(xié)議方法來保存對象狀態(tài)狸演。相反言蛇,編碼器保存對象的恢復(fù)標(biāo)識符,并把它添加到可保存對象的列表中宵距,這導(dǎo)致對象的encodeRestorableStateWithCoder:方法被調(diào)用腊尚。
視圖控制器的encodeRestorableStateWithCoder: 和 decodeRestorableStateWithCoder:方法在實現(xiàn)的時候應(yīng)該總是調(diào)用super。調(diào)用super可以讓父類又機會保存和恢復(fù)任何額外的信息满哪。代碼清單5-2展示了使用這些方法來對視圖控制器數(shù)值的簡單編解碼婿斥。
Listing 5-2 Encoding and decoding a view controller’s state.
- (void)encodeRestorableStateWithCoder:(NSCoder *)coder {
[super encodeRestorableStateWithCoder:coder];
[coder encodeInt:self.number forKey:MyViewControllerNumber];
}
- (void)decodeRestorableStateWithCoder:(NSCoder *)coder {
[super decodeRestorableStateWithCoder:coder];
self.number = [coder decodeIntForKey:MyViewControllerNumber];
}
編碼器對象在編解碼的過程中不會進行共享。每個帶有保存狀態(tài)的對象都接受它們自己的編碼器翩瓜,它可以用來讀寫數(shù)據(jù)受扳。使用獨一無二的編碼器意味著你不需要擔(dān)心命名空間問題。但是你必須仍然要避免使用一些UIKit提供的特定的鍵名兔跌。具體來說,每個編碼器包含UIApplicationStateRestorationBundleVersionKey 和 UIApplicationStateRestorationUserInterfaceIdiomKey 鍵峡蟋,它們提供關(guān)于束版本和當(dāng)前用戶界面風(fēng)格的信息坟桅。與視圖控制相關(guān)的編碼器也還包含UIStateRestorationViewControllerStoryboardKey鍵,它識別視圖控制器起源的storyboard蕊蝗。
更多關(guān)于為視圖控制器實現(xiàn)編解碼方法的信息仅乓,參見UIViewController Class Reference。
保存視圖的狀態(tài)
如果視圖有值的保存的狀態(tài)信息蓬戚,你可以將該狀態(tài)和應(yīng)用的其他視圖控制器保存在一起夸楣。因為它們通常被它們自己的視圖控制器配置,大多數(shù)視圖不必保存狀態(tài)信息子漩。只有當(dāng)視圖自身能被用戶通過某種方式改變的時候豫喧,你才需要保存視圖的狀態(tài)。這種改變的基礎(chǔ)是視圖擁有獨立的數(shù)據(jù)和或視圖控制器幢泼。例如紧显,滾動視圖保存當(dāng)前的滾動位置,這個位置的信息不足以引起視圖控制器的興趣缕棵,但是它卻影響了滾動視圖自身的外觀孵班。
為了指定應(yīng)該保存的視圖狀態(tài),你需要做以下操作:
- 分配你一個有效的字符串給視圖的restorationIdentifier屬性招驴。
- 使用該視圖的視圖控制器也要有有效的恢復(fù)標(biāo)識符篙程。
- 對于表視圖和集合視圖,分配一個采用UIDataSourceModelAssociation協(xié)議的數(shù)據(jù)源别厘。
與視圖控制器一樣虱饿,分配一個恢復(fù)標(biāo)識符給視圖,告訴系統(tǒng)該視圖對象有應(yīng)用想要保存的狀態(tài)。該恢復(fù)標(biāo)識符也能被用于視圖的定位郭厌。
就像視圖控制器袋倔,視圖定義方法來編解碼它們的自定義狀態(tài)。如果你創(chuàng)建值的保存狀態(tài)的視圖折柠,你可以使用這些方法來讀寫相關(guān)的數(shù)據(jù)宾娜。
保存狀態(tài)的UIKit視圖
為了要保存狀態(tài)的任何視圖,包括自定和標(biāo)準(zhǔn)的系統(tǒng)視圖扇售,你必須給視圖分配恢復(fù)標(biāo)識符前塔。沒有恢復(fù)標(biāo)識符的視圖,不能被UIKit添加到保存對象列表中承冰。
下面的UIKit視圖有可以被保存的狀態(tài)信息:
- UICollectionView
- UIImageView
- UIScrollView
- UITableView
- UITextField
- UITextView
- UIWebView
其他框架或許還有具有可保存狀態(tài)的視圖华弓,關(guān)于一個視圖是否保存狀態(tài)信息,以及保存什么信息困乒,參見相應(yīng)類的參考寂屏。
保存自定義視圖的狀態(tài)
如果你正在實現(xiàn)一個帶有可存儲狀態(tài)的自定義視圖,那就實現(xiàn) encodeRestorableStateWithCoder: 和 decodeRestorableStateWithCoder:方法娜搂,并使用它們編迁霎、解碼這個狀態(tài)。使用這些方法來保存那些不能通過其他方式輕松重配置的數(shù)據(jù)百宇。例如考廉,使用這些方法來保存那些用戶和視圖交互產(chǎn)生的修改的數(shù)據(jù)。不要使用這些方法來保存通過視圖或視圖控制器可以輕松配置的任何數(shù)據(jù)携御。
代碼清單5-3展示了一個如何保存和恢復(fù)包含有可編輯文本的自定義視圖選擇的例子昌粤。在這個例子中,可以使用 selectionRange 和 setSelectionRange:方法來訪問范圍啄刹,這些是視圖自定義的用于管理選擇的方法涮坐。編碼這些數(shù)據(jù)僅需要將其寫入編碼器對象中⊥腋啵恢復(fù)數(shù)據(jù)要求讀取它并把它應(yīng)用于視圖膊升。
代碼清單5-3 保存自定義視圖的選擇
// Preserve the text selection
- (void) encodeRestorableStateWithCoder:(NSCoder *)coder {
[super encodeRestorableStateWithCoder:coder];
NSRange range = [self selectionRange];
[coder encodeInt:range.length forKey:kMyTextViewSelectionRangeLength];
[coder encodeInt:range.location forKey:kMyTextViewSelectionRangeLocation];
}
// Restore the text selection.
- (void) decodeRestorableStateWithCoder:(NSCoder *)coder {
[super decodeRestorableStateWithCoder:coder];
if ([coder containsValueForKey:kMyTextViewSelectionRangeLength] &&
[coder containsValueForKey:kMyTextViewSelectionRangeLocation]) {
NSRange range;
range.length = [coder decodeIntForKey:kMyTextViewSelectionRangeLength];
range.location = [coder decodeIntForKey:kMyTextViewSelectionRangeLocation];
if (range.length > 0)
[self setSelectionRange:range];
}
}
實現(xiàn)易于維護的數(shù)據(jù)源
因為表或集合視圖顯示的數(shù)據(jù)可以更改,所以只有當(dāng)它們的數(shù)據(jù)源實現(xiàn)了UIDataSourceModelAssociation協(xié)議時谭企,這兩個類才可以保存關(guān)于當(dāng)前選擇和可見單元的信息廓译。這個協(xié)議為表和集合視圖提供一個方式來識別它們所包含的內(nèi)容,而不必依賴這些內(nèi)容的索引路徑债查。因此非区,無論數(shù)據(jù)源在下一個啟動周期如何放置項目的位置,該視圖仍然具有查找該項目所需的信息盹廷。
為了成功實現(xiàn)UIDataSourceModelAssociation協(xié)議征绸,你的數(shù)據(jù)源對象必須能夠識別應(yīng)用后續(xù)啟動中的項目。這意味著任何你設(shè)計的識別方案對給定的數(shù)據(jù)必須是不變的。這是至關(guān)重要的管怠,因為數(shù)據(jù)源必須能夠在每次請求的時候為相同的標(biāo)識符取回相同的數(shù)據(jù)淆衷。實現(xiàn)這個協(xié)議本身,是從數(shù)據(jù)項映射到唯一的ID并再次返回渤弛。
使用Core Data的應(yīng)用可以通過利用對象標(biāo)識符來實現(xiàn)協(xié)議祝拯。每個Core Data庫中對象都有一個唯一的對象標(biāo)識符,它可以被轉(zhuǎn)化為URI她肯,并用于定位對象佳头,如果應(yīng)用不是使用Core Data,如果你想讓你的視圖支持狀態(tài)保存晴氨,你需要設(shè)計自己的唯一標(biāo)識符的格式康嘉。
注意:記住,實現(xiàn)UIDataSourceModelAssociation協(xié)議僅需要保存屬性籽前,例如表或集合視圖的當(dāng)前選擇亭珍。這個協(xié)議不用于保存由數(shù)據(jù)源管理的真實數(shù)據(jù)。確保數(shù)據(jù)在合適的時候保存是應(yīng)用的責(zé)任聚假。
保存應(yīng)用的高級狀態(tài)
除了通過應(yīng)用的視圖控制器和視圖來保存數(shù)據(jù)之外块蚌,UIKit提供了鉤子(hooks)來保存應(yīng)用需要的任何雜項數(shù)據(jù)。具體來說膘格,需要重寫UIApplicationDelegate協(xié)議的下列兩個方法:
- application:willEncodeRestorableStateWithCoder:
- application:didDecodeRestorableStateWithCoder:
如果應(yīng)用包含不在視圖控制器中的狀態(tài),但又需要保存财松,你可以使用上面的方法來保存和恢復(fù)瘪贱。application:willEncodeRestorableStateWithCoder:方法在存儲過程剛開始的時候調(diào)用,所以你可以在這里寫入高級應(yīng)用狀態(tài)辆毡,例如當(dāng)前的用戶界面版本菜秦。application:didDecodeRestorableStateWithCoder:方法在恢復(fù)狀態(tài)結(jié)束的時候調(diào)用,你可以在這里解碼任何數(shù)據(jù)并根據(jù)應(yīng)用要求執(zhí)行最后的清理舶掖。
保存和恢復(fù)狀態(tài)信息的提示
當(dāng)你向應(yīng)用添加狀態(tài)保存和恢復(fù)的支持的時候球昨,請考慮以下準(zhǔn)則:
- 版本信息可以和應(yīng)用的其他狀態(tài)一起編碼。在保存過程期間眨攘,建議對指明當(dāng)前應(yīng)用用戶界面的版本字符串或數(shù)字進行編碼主慰。你可以在應(yīng)用委托的application:willEncodeRestorableStateWithCoder:方法里面編碼這個狀態(tài)。當(dāng)應(yīng)用委托的application:shouldRestoreApplicationState:方法被調(diào)用的時候鲫售,你可以從提供的編碼器中取回這些信息共螺,并使用它來確定狀態(tài)是否可以保存。
- 不要在應(yīng)用的狀態(tài)中包含來自數(shù)據(jù)模型的對象情竹。應(yīng)用應(yīng)該保持吧數(shù)據(jù)保存在iCloud或者磁盤的本地文件上藐不。不要使用狀態(tài)恢復(fù)機制來保存數(shù)據(jù)。如果在恢復(fù)操作期間發(fā)生錯誤,有可能使保存的界面數(shù)據(jù)被刪除雏蛮。因此涎嚼,你寫入磁盤的任何與保存相關(guān)的數(shù)據(jù)都會被認為可清除。
- 狀態(tài)保存系統(tǒng)期望你依照設(shè)計目的來使用視圖控制器挑秉。視圖控制器層次結(jié)構(gòu)是依賴于視圖控制器之間的控制和呈現(xiàn)創(chuàng)建的法梯。如果應(yīng)用通過其他方式顯示視圖控制器的視圖,(例如衷模,通過把它添加到另一個和相應(yīng)的視圖控制器沒有控制關(guān)系的視圖中鹊汛,)保存系統(tǒng)將不能找到你的視圖控制器并保存它。
- 記住你或許并不想保存所有的視圖控制器阱冶。在某些情況下刁憋,保存視圖控制器或許沒有意義。例如木蹬,如果在修改密碼的時候用戶退出了應(yīng)用至耻,你可能希望能取消這個操作,并恢復(fù)到上一個屏幕镊叁。這種情況下尘颓,就不需要保存要求輸入新密碼信息的視圖控制器。
- 避免在恢復(fù)過程期間交換視圖控制器類晦譬。狀態(tài)保存系統(tǒng)編碼它保存的視圖控制器類疤苹。在恢復(fù)期間,如果應(yīng)用返回的對象的類和原來對象的類不匹配(或不是其子類)敛腌,系統(tǒng)不會要求視圖控制器解碼任何狀態(tài)信息卧土。因此,交換了視圖控制器的類像樊,將不能恢復(fù)對象的完整狀態(tài)尤莺。
- 當(dāng)用戶強退應(yīng)用的時候,系統(tǒng)會自動刪除應(yīng)用保存的狀態(tài)生棍。當(dāng)應(yīng)用被殺死的時候颤霎,刪除保存的狀態(tài)信息是一種安全預(yù)防措施。(為了安全起見涂滴,如果系統(tǒng)連著啟動兩次都崩潰友酱,系統(tǒng)也會刪除保存的狀態(tài)。)如果你想測試應(yīng)用恢復(fù)它狀態(tài)的功能氢妈,調(diào)試期間就不要使用多任務(wù)欄來殺死應(yīng)用粹污。相反,使用Xcode來殺死應(yīng)用首量,或通過安裝臨時命令壮吩,或安裝手勢來按需調(diào)用退出函數(shù)來殺死應(yīng)用进苍。
開發(fā)VoIP應(yīng)用的提示
互聯(lián)網(wǎng)語音協(xié)議(VoIP)應(yīng)用允許用戶使用網(wǎng)絡(luò)連接,而非設(shè)備的蜂窩服務(wù)來撥打電話鸭叙。在iOS 8及更高的版本中觉啊,你可以使用APNS和PushKit框架的API來創(chuàng)建VoIP應(yīng)用。以來推送通知來啟用VoIP功能沈贝,意味著應(yīng)用不需要維持相關(guān)服務(wù)的持續(xù)網(wǎng)絡(luò)連接杠人,或者配置供VoIP使用的套接字。當(dāng)VoIP推送通知到達的時候宋下,即使應(yīng)用處于終止?fàn)顟B(tài)嗡善,應(yīng)用也會花時間來處理該通知。
注意:VoIP的推送通知只發(fā)送給iOS 8及更高版本的設(shè)備学歧。如果你需要支持較早版本的iOS設(shè)備罩引,你需要處理處理兼容問題。
和任何后臺音頻應(yīng)用一樣枝笨,VoIP的音頻會話必須正確配置袁铐,以便確保其他基于音頻的應(yīng)用能夠平滑的運行。因為VoIP的音頻播放和錄制并不是一直運行的横浑,所以創(chuàng)建只有在必要的時候才創(chuàng)建并配置應(yīng)用的音頻會話是非常重要的剔桨。例如,你創(chuàng)建音頻會話來通知用戶有電話呼入或者用戶實際就在通話中徙融。一旦通話結(jié)束洒缀,你應(yīng)該移除對于音頻會話的強引用,以便其他音頻應(yīng)用可以播放它們的音頻欺冀。
關(guān)于如何為VoIP應(yīng)用配置和管理音頻會話的信息帝洪,參見Audio Session Programming Guide。想要學(xué)習(xí)更多關(guān)于使用VoIP推送通知以及用PushKit APIs創(chuàng)建VoIP應(yīng)用的內(nèi)容脚猾,參見Energy Efficiency Guide for iOS Apps。
在實現(xiàn)VoIP應(yīng)用時有下列要求:
- 為應(yīng)用啟用Voice over IP 后臺模式砚哗。(因為VoIP涉及音頻內(nèi)容龙助,建議還要啟用Audio and AirPlay后臺模式。)你在Xcode項目的Capabilities選項卡中設(shè)置這些后臺模式蛛芥。
- 使用PushKit APIs來注冊接收VoIP推送通知提鸟,并處理傳入的通知。
- 配置你的音頻會話來處理出仅淑、入內(nèi)容的轉(zhuǎn)換称勋。
- 為了確保在iPhone上獲得更好的用戶體驗,使用Core Telephony框架來調(diào)整與手機通話相關(guān)的行為涯竟。參見Core Telephony Framework Reference赡鲜。
- 為了確保VoIP應(yīng)用有良好的性能空厌,使用System Configuration框架來檢測網(wǎng)絡(luò)改變,并運行應(yīng)用盡可能的休眠银酬。
- 申請VoIP Services證書來允許你的通知服務(wù)器連接VoIP服務(wù)嘲更。
啟用VoIP后臺模式,讓系統(tǒng)知道它將允許應(yīng)用必要時在后臺運行揩瞪,來管理其網(wǎng)絡(luò)套接字赋朦。此鍵還允許應(yīng)用在后臺播放音頻(盡管如此,還時鼓勵啟用Audio and AirPlay模式)李破。支持這個模式的應(yīng)用在系統(tǒng)啟動后立即在后臺重啟宠哄,以確保VoIP服務(wù)始終可用。
使用可達性(Reachbility)接口來提高用戶體驗
因為VoIP應(yīng)用嚴重依賴網(wǎng)絡(luò)嗤攻,所以它們應(yīng)該使用System Configuration框架的可達性接口來跟蹤網(wǎng)絡(luò)的狀態(tài)毛嫉,并調(diào)整它們的相應(yīng)行為⊥筒埽可達性接口允許應(yīng)用在網(wǎng)絡(luò)條件發(fā)生變化的時候能收到通知狱庇。例如,當(dāng)網(wǎng)絡(luò)不可用的時候恶耽,VoIP應(yīng)用可以關(guān)閉它的網(wǎng)絡(luò)連接密任,而在網(wǎng)絡(luò)恢復(fù)的時候,重新創(chuàng)建它們偷俭。應(yīng)用還可以使用這些變化來通知用戶VoIP連接現(xiàn)在狀態(tài)浪讳。
為了使用可達性接口,你必須使用該框架來注冊一個回調(diào)函數(shù)涌萤,并使用它來處理改變淹遵。通過以下步驟注冊會掉函數(shù):
- 為你的遠程目標(biāo)主機創(chuàng)建一個SCNetworkReachabilityRef結(jié)構(gòu)。
- 分配一個回調(diào)函數(shù)被你的結(jié)構(gòu)(使用SCNetworkReachabilitySetCallback函數(shù))负溪,它處理目標(biāo)的可達狀態(tài)的改變透揣。
- 使用SCNetworkReachabilityScheduleWithRunLoop 函數(shù)添加該目標(biāo)到應(yīng)用的一個活動的運行循環(huán)(例如主運行循環(huán))
根據(jù)網(wǎng)絡(luò)的可達性調(diào)整應(yīng)用的行為,還可以有助于提高底層設(shè)備的電池壽命川抡。讓系統(tǒng)跟蹤網(wǎng)絡(luò)改變意味著應(yīng)用可以讓它自己盡可能的休眠辐真。
更多關(guān)于可達性接口的信息,參見System Configuration Framework Reference崖堤。
(本節(jié)結(jié)束)