自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

Swift +CloudKit開(kāi)發(fā)入門(mén)篇

譯文
開(kāi)發(fā)
使用蘋(píng)果公司推出的有著強(qiáng)大后端API支持的CloudKit,相信你能夠把你的應(yīng)用程序提升到一個(gè)更高的水平!

簡(jiǎn)介

CloudKit是蘋(píng)果公司推出的基于iCloud的遠(yuǎn)程數(shù)據(jù)存儲(chǔ)服務(wù)。它為存儲(chǔ)和使用用戶(hù)的iCloud賬戶(hù)的后端存儲(chǔ)服務(wù)共享應(yīng)用數(shù)據(jù)提供了一種低成本的選擇方案。

總體來(lái)看,CloudKit主要提供了兩個(gè)組件:

  • 一個(gè)網(wǎng)絡(luò)中心,用于管理記錄類(lèi)型和任何公共數(shù)據(jù)。
  • 一組API,用于在iCloud和設(shè)備之間傳輸數(shù)據(jù)。

CloudKitr的安全性是很高的。用戶(hù)的私有數(shù)據(jù)受到完全保護(hù),因?yàn)殚_(kāi)發(fā)人員只能訪(fǎng)問(wèn)他們自己的私人數(shù)據(jù)庫(kù)而不能查看任何其他用戶(hù)的私人數(shù)據(jù)。

對(duì)于只運(yùn)行于iOS平臺(tái)的使用大量數(shù)據(jù)但不需要服務(wù)器端大量邏輯的應(yīng)用程序來(lái)說(shuō),CloudKit是一個(gè)不錯(cuò)的選擇。此外,CloudKit也可用于網(wǎng)絡(luò)和服務(wù)器應(yīng)用程序。

在這個(gè)CloudKit教程中,您將獲得使用CloudKit的切身體驗(yàn),即你需要?jiǎng)?chuàng)建一個(gè)名為BabiFüd的餐廳評(píng)級(jí)應(yīng)用程序。

為何選擇CloudKit?

你可能想知道,為什么要選擇基于核心數(shù)據(jù)(Core Data)基礎(chǔ)之上的CloudKit,而不是其他BaaS(后端即服務(wù))產(chǎn)品,甚至是基于你自己的服務(wù)器?

原因有三:簡(jiǎn)單性,高信譽(yù)度和低成本。

簡(jiǎn)單性

不像其他的后端解決方案,CloudKit僅需要很少的設(shè)置。你不必選擇、配置或安裝服務(wù)器。此外,安全性和伸縮性也都由蘋(píng)果公司來(lái)處理。

只需在蘋(píng)果官方網(wǎng)站注冊(cè)成為iOS開(kāi)發(fā)者項(xiàng)目成員,您就擁有了使用CloudKit的資格。你不必注冊(cè)額外的服務(wù)或創(chuàng)建新帳戶(hù)。當(dāng)您在自己的應(yīng)用程序中啟用CloudKit支持時(shí),所有必要的服務(wù)器設(shè)置都將魔術(shù)般自動(dòng)發(fā)生。

你不需要下載額外的庫(kù)并對(duì)它們進(jìn)行配置。CloudKit就像任何其他iOS框架一樣導(dǎo)入。CloudKit框架本身通過(guò)提供一些針對(duì)常見(jiàn)操作的便利的API實(shí)現(xiàn)了一定程度的簡(jiǎn)單性。

這也方便了用戶(hù)使用。由于在設(shè)備設(shè)置(甚至是設(shè)置結(jié)束進(jìn)入應(yīng)用程序時(shí))時(shí)CloudKit使用的是輸入的iCloud憑據(jù),所以沒(méi)有必要建立復(fù)雜的登錄屏幕。只要用戶(hù)登錄,他們就可以無(wú)縫地開(kāi)始使用你的應(yīng)用程序。

高信譽(yù)度

CloudKit的另一個(gè)好處是,通過(guò)依靠蘋(píng)果公司而不是應(yīng)用程序開(kāi)發(fā)人員,用戶(hù)可以相信他們的數(shù)據(jù)的隱私性和安全性。CloudKit能夠把您(開(kāi)發(fā)人員)與用戶(hù)數(shù)據(jù)隔離開(kāi)來(lái)。

雖然在調(diào)試程序時(shí)無(wú)法訪(fǎng)問(wèn)可能令人沮喪,但另一個(gè)方面這也帶來(lái)一定好處,因?yàn)槟悴槐負(fù)?dān)心安全或說(shuō)服用戶(hù)其數(shù)據(jù)的安全性。如果一個(gè)應(yīng)用程序用戶(hù)信任iCloud,那么他們也可以信任作為開(kāi)發(fā)人員的你。

低成本

***,對(duì)于任何開(kāi)發(fā)者來(lái)說(shuō),運(yùn)行服務(wù)的成本也是一個(gè)巨大的投資。即使是***的服務(wù)器主機(jī)也不能為小型、免費(fèi)或廉價(jià)的應(yīng)用程序提供低成本的解決方案。所以總是會(huì)有與運(yùn)行應(yīng)用程序相關(guān)的成本問(wèn)題。

借助于CloudKit,你可以實(shí)現(xiàn)針對(duì)免費(fèi)的公共數(shù)據(jù)的適量的存儲(chǔ)和數(shù)據(jù)傳輸。在WWDC 2015視頻的CloudKit新增功能(https://developer.apple.com/videos/play/wwdc2015/704/)中提供了非常詳盡的收費(fèi)解釋。

上述所有這些優(yōu)勢(shì),使得CloudKit服務(wù)成為Mac和iOS應(yīng)用程序開(kāi)發(fā)中更值得選擇的解決方案。

BabiFüd項(xiàng)目功能介紹

本教程中提供的BabiFüd示例應(yīng)用程序使用時(shí)下最標(biāo)準(zhǔn)的“速度餐廳”型應(yīng)用程序風(fēng)格。不是沿用傳統(tǒng)式的基于食品質(zhì)量、服務(wù)速度以及價(jià)格等評(píng)價(jià)標(biāo)準(zhǔn),而是使用新型的兒童友好性進(jìn)行評(píng)價(jià)。這包括設(shè)施更換、加高座椅和健康性食品選擇等可用性標(biāo)準(zhǔn)。

應(yīng)用程序包含四個(gè)選項(xiàng)卡:一個(gè)附近的餐館列表;一個(gè)附近餐館地圖展示;用戶(hù)生成注釋和功能設(shè)置。附近的餐館列表選項(xiàng)卡是您將在本教程中使用的唯一部分。當(dāng)然,你現(xiàn)在就可以一瞥運(yùn)行中的這個(gè)示例應(yīng)用程序。

 

開(kāi)發(fā)過(guò)程中,我使用了一個(gè)模型類(lèi)來(lái)支持這些視圖,并封裝對(duì)CloudKit的調(diào)用。其中,CloudKit對(duì)象稱(chēng)為記錄(Record)。模型中主要的記錄類(lèi)型是一個(gè)Establishment,它代表了你的應(yīng)用程序中不同的餐館。

開(kāi)始

首先,請(qǐng)下載本教程中的啟動(dòng)項(xiàng)目,地址是https://cdn2.raywenderlich.com/wp-content/uploads/2016/06/BabiFud-Cloudkit-Starter.zip。

你必須改變你的應(yīng)用程序的資源標(biāo)識(shí)符和團(tuán)隊(duì)類(lèi)型,然后才能開(kāi)始編碼。為了從蘋(píng)果公司獲得必要的授權(quán),您需要設(shè)置團(tuán)隊(duì)。擁有一個(gè)獨(dú)特的資源標(biāo)識(shí)符可以使得很多的事更容易操作。

現(xiàn)在,請(qǐng)使用Xcode打開(kāi)工程BabiFud.xcodeproj。然后,從「Project Navigator」下選擇BabiFud項(xiàng)目,然后選擇「BabiFud target」。接下來(lái),選擇「General」選項(xiàng)卡,使用一些獨(dú)特的字符串內(nèi)容更換資源標(biāo)識(shí)符(Bundle Identifier)。標(biāo)準(zhǔn)的做法是,使用反向域名符號(hào)并包括項(xiàng)目名稱(chēng)。然后,選擇合適的團(tuán)隊(duì)(Team): 

現(xiàn)在,你需要在你的應(yīng)用程序中設(shè)置CloudKit支持,并創(chuàng)建一些容器來(lái)保存數(shù)據(jù)。

權(quán)限和容器

在向應(yīng)用程序中添加任何數(shù)據(jù)之前,你需要一個(gè)容器來(lái)保存應(yīng)用程序的記錄。容器,其實(shí)僅是一個(gè)概念上的位置術(shù)語(yǔ),對(duì)應(yīng)于所有應(yīng)用程序在服務(wù)器上的數(shù)據(jù)。它分為公共和私有數(shù)據(jù)庫(kù)兩個(gè)組。 

要?jiǎng)?chuàng)建一個(gè)容器,你首先需要擁有啟用您的應(yīng)用程序的iCloud權(quán)限?,F(xiàn)在,請(qǐng)從目標(biāo)編輯器選擇【Capabilities】選項(xiàng)卡。然后,把iCloud部分中的開(kāi)關(guān)切換為ON。 

現(xiàn)在,Xcode可能會(huì)提示您輸入與您的iOS開(kāi)發(fā)者帳戶(hù)相關(guān)聯(lián)的蘋(píng)果ID。如果是這樣,那么根據(jù)要求輸入即可。***,通過(guò)勾選【Services】組中的CloudKit復(fù)選框來(lái)啟用CloudKit。

這將創(chuàng)建一個(gè)名為iCloud.<your app’s bundle id>的默認(rèn)容器,如下圖所示: 

克服Xcode中iCloud安裝錯(cuò)誤

如果你在創(chuàng)建權(quán)限、構(gòu)建項(xiàng)目或運(yùn)行應(yīng)用程序時(shí)看到任何警告或錯(cuò)誤,并注意到Xcode抱怨容器ID;那么,下面提供一些故障排除提示,供您參考:

  • 如果有任何的警告或錯(cuò)誤顯示在【iCloud】部分中的【Steps】組中;那么,你可以嘗試按下「Fix Issue」按鈕。這可能需要反復(fù)操作好幾次。

 

  • 應(yīng)用程序的包ID和iCloud的容器要相匹配并存在于開(kāi)發(fā)人員帳戶(hù)中,這一點(diǎn)是很重要的。例如,如果包標(biāo)識(shí)為“com.<your domain>.BabiFud”,那么,iCloud的容器名稱(chēng)應(yīng)是“iCloud.”,再加上資源包ID“iCloud.com.<your domain>.BabiFud”。
  • iCloud的容器名稱(chēng)必須是唯一的,因?yàn)檫@是使用CloudKit訪(fǎng)問(wèn)數(shù)據(jù)的全球標(biāo)識(shí)符。由于iCloud的容器名稱(chēng)包含了資源ID,所以該資源ID也必須是唯一的(這就是為什么它必須由com.raywendrelich.BabiFud進(jìn)行修改的原因)。
  • 為了過(guò)權(quán)限這一關(guān),應(yīng)用程序/包ID顯示于【Certificates】,【Identifiers】和【Profiles】的App ID部分。這意味著,用于簽名應(yīng)用程序的證書(shū)必須來(lái)自于設(shè)置的團(tuán)隊(duì)ID并且必須列出應(yīng)用程序ID;這也就是iCloud的容器id。通常情況下,如果你登錄了一個(gè)有效的開(kāi)發(fā)帳戶(hù),Xcode能夠自動(dòng)地完成這一切。不幸的是,這有時(shí)會(huì)導(dǎo)致不同步情況。你可以通過(guò)一個(gè)新的ID刷新來(lái)重新開(kāi)始,并使用iCloud的功能窗格更改CloudKit容器ID以便進(jìn)行匹配。否則,要解決這個(gè)問(wèn)題,你可能要編輯info.plist文件或BabiFud.entitlements文件,以確保ID值反映你為應(yīng)用程序設(shè)置的包ID。

CloudKit控制面板簡(jiǎn)介

在創(chuàng)建完工程所必需的餐館數(shù)據(jù)之后,下一步就是創(chuàng)建一些記錄類(lèi)型來(lái)定義您的應(yīng)用程序所使用的數(shù)據(jù)。您可以使用CloudKit控制面板來(lái)實(shí)現(xiàn)這一點(diǎn)。從工程的【Capabilities】窗格中點(diǎn)擊【CloudKit Dashboard】,如圖所示。

 

【注意】你還可以通過(guò)在瀏覽器中打開(kāi)網(wǎng)址https://icloud.developer.apple.com/dashboard/ 來(lái)啟動(dòng)CloudKit控制面板。

這個(gè)控制面板是什么樣子呢?請(qǐng)觀察一下這個(gè)圖形: 

注意到,該控制面板由四部分組成:架構(gòu)(Schema),公共數(shù)據(jù)(Public Data),私有數(shù)據(jù)(Private Data)和管理員(Admin)。

其中,Schema部分代表CloudKit容器中的***層次對(duì)象:記錄類(lèi)型(Record Types),安全角色(Security Roles)及訂閱類(lèi)型(Subscription Types)。在本教程中,你只要關(guān)心記錄類(lèi)型即可。

記錄類(lèi)型(Record Types),是一組定義了單個(gè)記錄的字段。對(duì)于面向?qū)ο缶幊潭?,一個(gè)記錄類(lèi)型就像一個(gè)類(lèi)。一個(gè)記錄可以被認(rèn)為是一個(gè)特殊的記錄類(lèi)型的實(shí)例。它代表了容器中的結(jié)構(gòu)化數(shù)據(jù),就像數(shù)據(jù)庫(kù)中的一個(gè)典型的行,它封裝了一系列鍵/值對(duì)。

公共數(shù)據(jù)(PUBLIC DATA)和私有數(shù)據(jù)(PRIVATE DATA)部分,可以讓您在您能夠訪(fǎng)問(wèn)的數(shù)據(jù)庫(kù)中添加數(shù)據(jù)或搜索數(shù)據(jù)。請(qǐng)記住,作為一名開(kāi)發(fā)人員你可以訪(fǎng)問(wèn)所有的公共數(shù)據(jù),但只能訪(fǎng)問(wèn)你自己的私有數(shù)據(jù)。其中,「User Records」存儲(chǔ)關(guān)于當(dāng)前iCloud用戶(hù)的數(shù)據(jù),如姓名和電子郵件等?!赣涗泤^(qū)域」(Record Zone)(這里使用的是默認(rèn)的區(qū)域),用于提供一個(gè)邏輯組織到一個(gè)私有數(shù)據(jù)庫(kù);實(shí)現(xiàn)方法是對(duì)記錄進(jìn)行分組。注意,自定義區(qū)域支持原子事務(wù),即允許在處理其它操作之前把多個(gè)記錄同時(shí)保存。不過(guò),有關(guān)自定義區(qū)域的探討已經(jīng)超出本教程的范圍。

管理員(ADMIN)部分,能夠針對(duì)您的團(tuán)隊(duì)成員提供不同的權(quán)限配置控制。如果你有多個(gè)開(kāi)發(fā)團(tuán)隊(duì)成員,你可以在這里限制他們編輯數(shù)據(jù)的能力。當(dāng)然,這也超出本教程范圍。

添加餐館記錄類(lèi)型

現(xiàn)在,請(qǐng)略微想一想你的應(yīng)用程序的設(shè)計(jì)吧。你要跟蹤的每一家餐館都對(duì)應(yīng)大量的數(shù)據(jù):名稱(chēng)、位置以及各種兒童友好的設(shè)施的可用性,等等。記錄類(lèi)型使用字段來(lái)定義每個(gè)記錄包含的各個(gè)部分中的數(shù)據(jù)。

選擇記錄類(lèi)型(Record Types)后,單擊詳細(xì)信息窗格左上方的+圖標(biāo)添加一個(gè)新的記錄類(lèi)型,如圖所示。 

命名你剛剛創(chuàng)建的新記錄類(lèi)型為「Establishment」。

你會(huì)看到出現(xiàn)一行字段,其中定義了字段名、字段類(lèi)型和索引等,如下圖所示。注意,有一個(gè)字段使用了默認(rèn)名稱(chēng)「StringField」,這是系統(tǒng)自動(dòng)為您創(chuàng)建的。 

接下來(lái),你要使用新名字「Name」替換「StringField」。字段類(lèi)型和索引默認(rèn)已匹配您所需要的***個(gè)字段的定義,但接下來(lái),你需要對(duì)于其他一些字段改變字段類(lèi)型和索引。單擊【Add Field…】并根據(jù)需要增加新的字段即可。***,你需要添加以下字段: 

當(dāng)你添加完所有字段后,你的字段列表應(yīng)該是這樣的: 

點(diǎn)擊頁(yè)面底部【Save】按鈕保存您的新的記錄類(lèi)型。

現(xiàn)在,您已經(jīng)準(zhǔn)備好向您的數(shù)據(jù)庫(kù)中添加一些示例記錄了。

選擇左側(cè)導(dǎo)航窗格中【PUBLIC DATA】下部的【Default Zone】。該區(qū)域?qū)膽?yīng)用程序的所有公共記錄。如果還沒(méi)有選定,那么請(qǐng)從中心窗格的下拉列表中選擇「Establishment」記錄類(lèi)型。然后單擊右側(cè)詳細(xì)信息窗格中的+圖標(biāo)或【New Record】按鈕,如下圖所示: 

這將創(chuàng)建一個(gè)新的空的Establishment記錄。 

此時(shí),您已經(jīng)準(zhǔn)備好為您的應(yīng)用程序輸入一些測(cè)試數(shù)據(jù)了。

需要說(shuō)明的是,下面的示例數(shù)據(jù)都是虛構(gòu)的。這些餐館數(shù)據(jù)都位于蘋(píng)果總部附近,這樣它們可以很容易地出現(xiàn)在模擬器上。

現(xiàn)在,請(qǐng)輸入如下表所述的每個(gè)記錄:

【注意】每個(gè)CoverPhoto元素對(duì)應(yīng)的圖像文件都包含在Xcode項(xiàng)目的「Supporting Files\Sample Images」文件夾中。要將圖像添加到Establishment記錄中,只需將其拖動(dòng)到CoverPhoto字段中即可。 

一旦保存完所有三個(gè)記錄,控制面板應(yīng)該是這樣的: 

對(duì)于每個(gè)記錄,輸入的值都代表了數(shù)據(jù)的數(shù)據(jù)庫(kù)描述部分。在應(yīng)用程序中,數(shù)據(jù)類(lèi)型是不同的。例如,SeatingType和ChangingTable都是結(jié)構(gòu)類(lèi)型的。所以,對(duì)于SeatingType字段指定的int值可能對(duì)應(yīng)于“high chair”或“booster”這樣的座位。對(duì)于HealthyOption和KidsMenu這兩個(gè)字段指定的int值表示布爾類(lèi)型:其中,0是指沒(méi)有這一項(xiàng),1則指有這一項(xiàng)。

***,運(yùn)行應(yīng)用程序需要你有一個(gè)可以用于開(kāi)發(fā)的iCloud帳戶(hù)。請(qǐng)參考蘋(píng)果官方文檔https://developer.apple.com/library/tvos/documentation/DataManagement/Conceptual/CloudKitQuickStart/EnablingiCloudandConfiguringCloudKit/EnablingiCloudandConfiguringCloudKit.html#//apple_ref/doc/uid/TP40014987-CH2-SW7。

另外,您還需要在iPhone模擬器中輸入與此帳戶(hù)相關(guān)聯(lián)的icloud憑據(jù)。請(qǐng)參考蘋(píng)果官方文檔https://developer.apple.com/library/tvos/documentation/DataManagement/Conceptual/CloudKitQuickStart/CreatingaSchemabySavingRecords/CreatingaSchemabySavingRecords.html#//apple_ref/doc/uid/TP40014987-CH3-SW12。

現(xiàn)在,切換回Xcode中。從下一節(jié)開(kāi)始,你要把上面創(chuàng)建的數(shù)據(jù)集成到您的應(yīng)用程序中!

查詢(xún)餐館記錄

CKQuery對(duì)象用于從數(shù)據(jù)庫(kù)中選擇記錄。CKQuery描述了如何找到符合特定條件的特定類(lèi)型的所有記錄。這些條件可以是這樣的:所有記錄都有一個(gè)以N開(kāi)頭的Name字段;所有記錄都帶有兒童增高座椅;所有記錄都要滿(mǎn)足在3公里以?xún)?nèi)。這些類(lèi)型的表達(dá)式都通過(guò)NSPredicate對(duì)象編碼于Cocoa庫(kù)中。NSPredicate能夠評(píng)估對(duì)象,看它們是否符合指定條件。NSPredicate也用在核心數(shù)據(jù)(Core Data)中,并且自然地融入CloudKit中,因?yàn)橹^詞通常被定義用于針對(duì)某個(gè)字段的比較方面。

事實(shí)上,CloudKit僅支持NSPredicate功能的一個(gè)子集。這些功能包括:數(shù)學(xué)比較,字符串和集合操作(例如“字段匹配列表中的項(xiàng)目之一”),還提供了一個(gè)特殊的距離函數(shù)。函數(shù)distanceToLocation:fromLocation:被專(zhuān)門(mén)添加到NSPredicate對(duì)象定義中,特別支持CloudKit以匹配帶有位置字段的記錄——此已知位置位于指定半徑的范圍內(nèi)。接下來(lái)的內(nèi)容中將詳細(xì)介紹這種類(lèi)型謂詞的用法。對(duì)于其他類(lèi)型的查詢(xún)中,CKQuery類(lèi)參考文檔(https://developer.apple.com/library/ios/documentation/CloudKit/Reference/CKQuery_class/)中包含了有關(guān)其支持的功能及如何使用的詳細(xì)描述。

【注意】CloudKit包括了對(duì)CLLocation對(duì)象的支持。有一些核心定位框架對(duì)象(Core Location Framework)包含了有關(guān)地理坐標(biāo)的信息。這使得開(kāi)發(fā)人員可以很容易創(chuàng)建一個(gè)查詢(xún)來(lái)尋找指定地理區(qū)域內(nèi)的餐館——而不需要我們自己進(jìn)行所有繁瑣的坐標(biāo)運(yùn)算。

接下來(lái),在Xcode中打開(kāi)文件Model/ Model.swift。該文件中包含了所有您的應(yīng)用程序進(jìn)行服務(wù)器調(diào)用的存根。

現(xiàn)在,請(qǐng)使用下面的內(nèi)容來(lái)更換fetchEstablishments(_:radiusInMeters:)方法:

  1. func fetchEstablishments(location:CLLocation, radiusInMeters:CLLocationDistance) { 
  2.   // 1 
  3.   let radiusInKilometers = radiusInMeters / 1000.0    
  4.   // 2 
  5.   let locationPredicate = NSPredicate(format: "distanceToLocation:fromLocation:(%K,%@) &lt; %f", "Location", location, radiusInKilometers)    
  6.   // 3 
  7.   let query = CKQuery(recordType: EstablishmentType, predicate: locationPredicate)    
  8.   // 4 
  9.   publicDB.performQuery(query, inZoneWithID: nil) { [unowned self] results, error in 
  10.     if let errorerror = error { 
  11.       dispatch_async(dispatch_get_main_queue()) { 
  12.         self.delegate?.errorUpdating(error) 
  13.         print("Cloud Query Error - Fetch Establishments: \(error)") 
  14.       } 
  15.       return 
  16.     } 
  17.   
  18.     self.items.removeAll(keepCapacity: true) 
  19.     results?.forEach({ (record: CKRecord) in 
  20.       self.items.append(Establishment(record: record, 
  21.         database: self.publicDB)) 
  22.     }) 
  23.   
  24.     dispatch_async(dispatch_get_main_queue()) { 
  25.       self.delegate?.modelUpdated() 
  26.     } 
  27.   } 

 

現(xiàn)在,我們按編號(hào)來(lái)分析一下上面代碼的功能:

1.    CloudKit在其距離謂詞中利用公里為計(jì)算單位。這一行簡(jiǎn)單地把radiusInMeters轉(zhuǎn)換為公里。

2.    根據(jù)從當(dāng)前位置到他們的位置的距離謂詞對(duì)餐館進(jìn)行篩選。這個(gè)語(yǔ)句使用從用戶(hù)的當(dāng)前位置到指定距離內(nèi)的位置值來(lái)查找所有餐館。

3.    使用謂詞和記錄類(lèi)型創(chuàng)建CKQuery對(duì)象。執(zhí)行查詢(xún)時(shí)兩者都將被使用。

4.    ***,方法performQuery(_:inZoneWithID:completionHandler :)負(fù)責(zé)發(fā)送查詢(xún)到iCloud中,并等待任何匹配的結(jié)果。通過(guò)傳遞nil作為inZoneWithID參數(shù)值,可以針對(duì)你所在的默認(rèn)區(qū)域進(jìn)行查詢(xún);也就是說(shuō),針對(duì)你的公共數(shù)據(jù)庫(kù)。如果你既想從公共數(shù)據(jù)庫(kù)也想從私有數(shù)據(jù)庫(kù)中檢索記錄,那么,你必須使用一個(gè)單獨(dú)的調(diào)用來(lái)查詢(xún)每個(gè)數(shù)據(jù)庫(kù)。

你可能想知道:CKDatabase的實(shí)例publicDB從何而來(lái)?讓我們來(lái)看看文件Model.swift的頂部的代碼吧。

  1. let container: CKContainer 
  2. let publicDB: CKDatabase 
  3. let privateDB: CKDatabase 
  4.   
  5. init() { 
  6.   // 1 
  7.   container = CKContainer.defaultContainer() 
  8.   // 2 
  9.   publicDB = container.publicCloudDatabase 
  10.   // 3 
  11.   privateDB = container.privateCloudDatabase 

 

在這里,您定義了您的數(shù)據(jù)庫(kù):

1.    默認(rèn)容器是指您在iCloud的功能窗格中指定的那個(gè)。

2.    公共數(shù)據(jù)庫(kù)是指在你的應(yīng)用程序的所有用戶(hù)中共享的那個(gè)。

3.    私有數(shù)據(jù)庫(kù)只包含屬于當(dāng)前登錄的用戶(hù)(在本實(shí)例中即指你)的數(shù)據(jù)。

總之,此代碼將從公共數(shù)據(jù)庫(kù)中檢索一些地方餐館,但為了在任何應(yīng)用程序中看到相應(yīng)的數(shù)據(jù),必須把它關(guān)聯(lián)到一個(gè)視圖控制器。

創(chuàng)建需求回調(diào)函數(shù)

你可以借助熟悉的委托模式來(lái)管理通知的問(wèn)題。下面這個(gè)協(xié)議位于Model.swift文件的頂部;當(dāng)然,你需要在你的視圖控制器中實(shí)現(xiàn)這個(gè)協(xié)議:

  1. protocol ModelDelegate { 
  2.   func errorUpdating(error: NSError) 
  3.   func modelUpdated() 
  4. 現(xiàn)在,打開(kāi)文件MasterViewController.swift,并用以下內(nèi)容替換modelUpdated()方法原有內(nèi)容: 
  5. func modelUpdated() { 
  6.   refreshControl?.endRefreshing() 
  7.   tableView.reloadData() 

 

當(dāng)新數(shù)據(jù)可用時(shí)此方法會(huì)被調(diào)用。在方法tableView(_:cellForRowAtIndexPath:)中實(shí)現(xiàn)了所有關(guān)于表格視圖單元格與CloudKit對(duì)象綁定的代碼。您可以自行分析學(xué)習(xí),恕在此不再贅述。

接下來(lái),在文件MasterViewController.swift中,請(qǐng)使用如下內(nèi)容更換errorUpdating(_ :)方法:

  1. func errorUpdating(error: NSError) { 
  2.     let alertController = UIAlertController(title: nil, 
  3.                                             message: error.localizedDescription, 
  4.                                             preferredStyle: .Alert) 
  5.     alertController.addAction(UIAlertAction(title: "Dismiss", 
  6.                                             style: .Default, 
  7.                                             handler: nil)) 
  8.     presentViewController(alertController, animated: true, completion: nil) 

 

當(dāng)查詢(xún)產(chǎn)生錯(cuò)誤時(shí)調(diào)用此方法??赡苡捎诰W(wǎng)絡(luò)條件較差或特定CloudKit問(wèn)題(如丟失或不正確的用戶(hù)憑據(jù)或沒(méi)有記錄從查詢(xún)返回等)發(fā)生錯(cuò)誤。

當(dāng)處理任何一種遠(yuǎn)程服務(wù)器連接時(shí),良好的錯(cuò)誤處理是必不可少的。現(xiàn)在,這段代碼只顯示給用戶(hù)返回的錯(cuò)誤信息。

但是,目前程序中存在的非常普遍的問(wèn)題是:一個(gè)是用戶(hù)不能登錄到iCloud;另一個(gè)是程序還不具有支持用戶(hù)自動(dòng)登錄icloud的功能。建議您自己修改一下errorUpdating(_:)方法使之至少能夠處理這些情況。提示:目前這兩類(lèi)錯(cuò)誤都返回1(CKErrorCode)。

現(xiàn)在,請(qǐng)構(gòu)建和運(yùn)行示例項(xiàng)目。目前,你應(yīng)該看到一個(gè)幾近完整的餐館單位名單列表了。 

查詢(xún)排錯(cuò)

如果你正在使用iOS模擬器但卻發(fā)現(xiàn)列表控件中沒(méi)有填充任何內(nèi)容,那么,你務(wù)必確保從Xcode的菜單項(xiàng)【Debug\Simulate Location\San Francisco, CA, USA】下設(shè)置了正確的位置。如果您需要在Xcode中改變這一位置,那么你可以從應(yīng)用程序的下拉列表中選擇其他位置,從而實(shí)現(xiàn)強(qiáng)制刷新而不是被動(dòng)地等待位置觸發(fā)。

如果您使用的是iPhone或iPad且啟用了定位服務(wù)而列表仍未填充,那么說(shuō)明餐館沒(méi)有足夠接近你當(dāng)前的位置。此時(shí),你有兩個(gè)選擇:改變樣本數(shù)據(jù)的坐標(biāo)以便更接近您的當(dāng)前位置;或者使用模擬器來(lái)運(yùn)行應(yīng)用程序。還有第三個(gè)選擇,但不是非常實(shí)用,即你不得不前往庫(kù)比提諾(Cupertino)并進(jìn)入蘋(píng)果公司地區(qū)進(jìn)行試驗(yàn)。

如果數(shù)據(jù)未顯示正確——或者根本不顯示,那么,請(qǐng)使用CloudKit控制面板檢查樣本數(shù)據(jù)。確保所有的記錄都存在,而且你已經(jīng)將它們添加到默認(rèn)區(qū)域,而且它們的值都是正確的。如果您需要重新輸入數(shù)據(jù),那么你可以通過(guò)單擊回收站圖標(biāo)刪除記錄(參考下圖)。 

調(diào)試CloudKit錯(cuò)誤有時(shí)可能非常棘手。在撰寫(xiě)本文時(shí),CloudKit錯(cuò)誤消息中并不包含大量信息。要確定錯(cuò)誤的原因,您需要查看與你的特定數(shù)據(jù)庫(kù)操作相關(guān)連的錯(cuò)誤代碼。使用數(shù)字錯(cuò)誤代碼,查找相匹配的CKErrorCode枚舉值進(jìn)行分析。在文檔中的名稱(chēng)和說(shuō)明將幫助你縮小問(wèn)題原因的分析范圍。

【注意】對(duì)于可通過(guò)CloudKit返回的錯(cuò)誤代碼列表,請(qǐng)參閱CloudKit框架常量參考(https://developer.apple.com/library/ios/documentation/CloudKit/Reference/CloudKit_constants/#//apple_ref/c/tdef/CKErrorCode)。

下面是一些常見(jiàn)的錯(cuò)誤枚舉和相關(guān)說(shuō)明:

  • BadContainer——指定的容器是未知的或未經(jīng)授權(quán)的。
  • NotAuthenticated——當(dāng)前用戶(hù)沒(méi)有通過(guò)驗(yàn)證,也沒(méi)有用戶(hù)記錄可用。如果用戶(hù)未登錄到iCloud時(shí)可能出現(xiàn)這種情況。
  • UnknownItem——指定的記錄不存在。

當(dāng)你得到餐館的名單列表時(shí),你可能已經(jīng)注意到了,你可以看到服務(wù)餐館名稱(chēng)及其提供的服務(wù)。但沒(méi)有顯示圖像!是云端那邊出問(wèn)題了嗎?

當(dāng)您檢索服務(wù)餐館記錄時(shí),將自動(dòng)檢索對(duì)應(yīng)的圖像。但是,您仍然需要執(zhí)行必要的步驟來(lái)將圖像加載到你的應(yīng)用程序中。這需要借助于云端方法了!

使用二進(jìn)制資源

對(duì)于二進(jìn)制形式的資源數(shù)據(jù),如圖像,都有相關(guān)聯(lián)的記錄。在本文實(shí)例中,你的應(yīng)用程序的資源數(shù)據(jù)都會(huì)顯示于MasterViewController表視圖的餐館照片中。

在本節(jié)中,您需要添加邏輯來(lái)加載當(dāng)檢索餐館記錄時(shí)已下載的資源。

為此,打開(kāi)文件Model/Establishment.swift,并用下面的代碼更換loadCoverPhoto(_ :)方法:

  1. func loadCoverPhoto(completion:(photo: UIImage!) -&gt; ()) { 
  2.   // 1 
  3.   dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0)) { 
  4.     var image: UIImage! 
  5.     // 4 
  6.     defer { 
  7.       completion(photo: image) 
  8.     } 
  9.     // 2 
  10.     guard let asset = self.record["CoverPhoto"] as? CKAsset, 
  11.       path = asset.fileURL.path, 
  12.       imageData = NSData(contentsOfFile: path) else { 
  13.         return 
  14.     } 
  15.     // 3 
  16.     image = UIImage(data: imageData) 
  17.   } 

 

此方法從asset有關(guān)屬性中加載相關(guān)圖片:

1.    雖然你下載了資源,但同時(shí)您還檢索了記錄的其余部分?jǐn)?shù)據(jù),因此,你需要使用異步方式加載圖像。如你所見(jiàn),我們把有關(guān)代碼全部封裝在dispatch_async代碼塊內(nèi)。

2.    資源存儲(chǔ)在CKRecord中,作為CKAsset的實(shí)例,所以需要相應(yīng)地轉(zhuǎn)換一下。接下來(lái),從資源提供的本地文件URL中加載圖像數(shù)據(jù)。

3.    使用圖像數(shù)據(jù)來(lái)創(chuàng)建UIImage的一個(gè)實(shí)例。

4.    執(zhí)行與檢索的圖像相關(guān)的completion回調(diào)函數(shù)。請(qǐng)注意,不管執(zhí)行哪一個(gè)return語(yǔ)句,延遲(defer)塊都被執(zhí)行。例如,如果沒(méi)有圖像資源,那么,在返回時(shí)永遠(yuǎn)不會(huì)設(shè)置image變量的值,當(dāng)然也就不顯示餐廳對(duì)應(yīng)的圖像。

現(xiàn)在,請(qǐng)構(gòu)建和運(yùn)行示例項(xiàng)目。你會(huì)注意到,由于上面的云端操作,現(xiàn)在餐館的圖像顯示出來(lái)了! 

目前,在CloudKit資源中還存在兩個(gè)不足:

  • 資源只能在CloudKit中作為記錄屬性存在,你不能把它們單獨(dú)存儲(chǔ)。刪除記錄也會(huì)刪除所有相關(guān)資源。
  • 因?yàn)橘Y源與記錄數(shù)據(jù)的其余部分在同一時(shí)間下載,所以,獲取資源會(huì)產(chǎn)生一定的負(fù)面性能影響。如果您的應(yīng)用程序使用了大量的資源,那么,你應(yīng)該專(zhuān)門(mén)存儲(chǔ)一下?lián)碛匈Y源的不同類(lèi)型記錄的引用。

總結(jié)

到現(xiàn)在為止,你應(yīng)該已經(jīng)看到了我們的最終項(xiàng)目中所提供的功能。目前,該應(yīng)用程序已經(jīng)可以下載餐館記錄,并把它們的詳細(xì)資料和照片加載到程序的表視圖中。

實(shí)際上,您還可以從以下幾個(gè)方面進(jìn)一步增強(qiáng)本文中的示例應(yīng)用:

允許用戶(hù)添加自己的照片、筆記、評(píng)論和投訴。這將有助于他們避免再次遭遇不愉快的經(jīng)歷。

允許用戶(hù)使用地圖創(chuàng)建一個(gè)新的餐館記錄。你可以把這樣的功能添加到Model類(lèi)中,用于把相應(yīng)記錄保存到公共或私有數(shù)據(jù)庫(kù)中。

添加過(guò)濾和搜索支持。工程提供的Model類(lèi)中已經(jīng)構(gòu)建了一個(gè)帶有一個(gè)距離謂詞的CKQuery,可以把它修改為一個(gè)更復(fù)雜的謂詞。當(dāng)然,CloudKit也是支持基于字符串字段的文本搜索的。

提高應(yīng)用程序的性能和數(shù)據(jù)加載體驗(yàn)。你會(huì)注意到,本教程中在一切準(zhǔn)備就緒時(shí)使用了一些工具方法來(lái)調(diào)用所需的完成處理器函數(shù)。另外,CKDatabase的實(shí)例也提供了基于NSOperation的方法來(lái)更好地控制API執(zhí)行方式。

為程序提供緩存和同步支持;這樣當(dāng)應(yīng)用程序連接到網(wǎng)絡(luò)時(shí),它能夠保持線(xiàn)下響應(yīng)并保持內(nèi)容***。

使用蘋(píng)果公司推出的有著強(qiáng)大后端API支持的CloudKit,相信你能夠把你的應(yīng)用程序提升到一個(gè)更高的水平!

 

 

責(zé)任編輯:陳琳 來(lái)源: 51cto
相關(guān)推薦

2014-06-06 09:46:52

SwiftSwift教程

2015-07-30 09:43:10

獨(dú)立游戲開(kāi)發(fā)入門(mén)

2011-01-18 17:00:31

Postfix入門(mén)

2017-09-12 10:26:47

springbootmaven結(jié)構(gòu)

2018-12-21 12:25:08

2009-06-15 17:22:36

JBoss Seam

2010-08-31 14:01:23

iPhone

2020-11-16 10:19:33

Java

2009-06-09 13:02:30

NetBeans使用教程

2022-03-28 09:31:58

for循環(huán)語(yǔ)句

2022-01-27 09:35:45

whiledo-while循環(huán)Java基礎(chǔ)

2020-11-13 07:22:46

Java基礎(chǔ)While

2012-01-17 10:47:07

jQuery

2022-07-06 07:57:37

Zookeeper分布式服務(wù)框架

2021-12-21 09:02:31

Matplotlib Python可視化

2020-11-09 10:19:05

Java

2020-11-19 10:36:16

Java基礎(chǔ)方法

2022-03-10 09:33:21

Java數(shù)組初始化

2010-09-08 13:42:06

2017-01-22 21:30:39

大數(shù)據(jù)Kaggle函數(shù)
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)