【Swift 學(xué)習(xí)筆記】iCloud:Key-Value Storage
想讓自己的程序支持iCloud洗鸵。搜索發(fā)現(xiàn)OC的教程比較多。照貓畫(huà)虎仗嗦,翻譯+整理一個(gè)swift版本的膘滨。
參考:http://code.tutsplus.com/tutorials/working-with-icloud-key-value-storage--pre-37542
開(kāi)始之前
需要一個(gè)付費(fèi)的iOS 開(kāi)發(fā)者賬號(hào)。
至少要2臺(tái)iOS設(shè)備才可以測(cè)試數(shù)據(jù)同步功能稀拐。(iOS Simulator無(wú)法做iCloud Storage的測(cè)試)
如果你手頭沒(méi)有iOS開(kāi)發(fā)者賬號(hào)火邓,或者沒(méi)有2臺(tái)iOS設(shè)備。這篇文章還是可以讓你了解如何配置iCloud的德撬,如何使用iCloud讓你的程序變得更好铲咨。
Step 1:新建一個(gè)項(xiàng)目
首先需要對(duì)本地Xcode中的項(xiàng)目進(jìn)行配置。
用創(chuàng)建一個(gè)新的項(xiàng)目蜓洪。
template: Single View Application project
name: iCloudKeyValue
Language: Swift
Step 2: 配置iCloud
在Xcode 6中纤勒,配置iCloud比較簡(jiǎn)單。
在Project Navigator 中選擇項(xiàng)目隆檀。在Capabilities中將iCloud的switch開(kāi)關(guān)設(shè)置為On摇天。
Xcode會(huì)自動(dòng)幫你 創(chuàng)建App ID,將Entitlements權(quán)限文件添加到項(xiàng)目中
- 進(jìn)入開(kāi)發(fā)者中心刚操。
- 點(diǎn)擊右上角的“Certificates, Identifiers & Profiles”
- 在新的頁(yè)面中闸翅,選擇“Provisioning Profiles”
- 在新頁(yè)面中選擇App IDs【账可以看到,通過(guò)剛才的步驟a济赎,Xcode已經(jīng)自動(dòng)創(chuàng)建了App ID: brincell.iCloudKeyValue
- 點(diǎn)擊這個(gè)App ID鉴逞,展開(kāi)。你會(huì)發(fā)現(xiàn)iCloud 服務(wù)處于Configurable狀態(tài)司训。
(以Key-Value Storage來(lái)使用iCloud构捡,不需要iCloud Container文件。所以這里是需要配置的狀態(tài)壳猜。)
Step 3: demo 程序
demo 用的是Apple官方教程YourFirstApp
稍加修改勾徽,改為iOS App。
class Track: NSObject {
var volume : Float = 0
}
class ViewController: UIViewController {
let track = Track()
@IBOutlet weak var textField: UITextField!
@IBOutlet weak var slider: UISlider!
@IBAction func mute(sender: AnyObject) {
track.volume = 0.0
updateUserInterface()
println("click mute button")
}
@IBAction func textField(sender: AnyObject) {
var newValue = slider.value
track.volume = newValue
updateUserInterface()
println("\(slider.value)")
}
func updateUserInterface() {
var volume = track.volume
self.textField.text = "\(volume)"
self.slider.value = volume
}
}
運(yùn)行程序统扳。測(cè)試slider和Mute按鈕能否正常工作喘帚。拖動(dòng)slider,textField顯示對(duì)應(yīng)的值咒钟。
Step 4. 保存數(shù)據(jù)和加載數(shù)據(jù)
現(xiàn)在在手機(jī)上退出重啟程序吹由,數(shù)據(jù)是無(wú)法保存的。
我們這里用user defaults database 來(lái)保存數(shù)據(jù)朱嘴。
添加saveVolume() loadVolume() 兩個(gè)方法倾鲫。
func saveVolume() {
let ud = NSUserDefaults.standardUserDefaults()
let trackVolume = track.volume
ud.setValue(trackVolume, forKey: "Track")
}
func loadVolume(){
let ud = NSUserDefaults.standardUserDefaults()
if ud.valueForKey("Track") != nil {
track.volume = ud.valueForKey("Track") as Float
} else {
track.volume = 5
}
}
在viewDidLoad() 中調(diào)用loadVolume()粗合。在Mute和Slider的action中調(diào)用saveVolume()方法。
class ViewController: UIViewController {
let track = Track()
@IBOutlet weak var textField: UITextField!
@IBOutlet weak var slider: UISlider!
@IBAction func mute(sender: AnyObject) {
track.volume = 0.0
updateUserInterface()
saveVolume()
println("click mute button")
}
@IBAction func textField(sender: AnyObject) {
var newValue = slider.value
track.volume = newValue
updateUserInterface()
saveVolume()
println("\(slider.value)")
}
func updateUserInterface() {
var volume = track.volume
self.textField.text = "\(volume)"
self.slider.value = volume
}
override func viewDidLoad() {
super.viewDidLoad()
loadVolume()
updateUserInterface()
}
func saveVolume() {
let ud = NSUserDefaults.standardUserDefaults()
let trackVolume = track.volume
ud.setValue(trackVolume, forKey: "Track")
}
func loadVolume(){
let ud = NSUserDefaults.standardUserDefaults()
if ud.valueForKey("Track") != nil {
track.volume = ud.valueForKey("Track") as Float
} else {
track.volume = 5
}
}
}
運(yùn)行程序乌昔。雙擊Home隙疚,在程序列表中上劃完全退出demo。重新啟動(dòng)demo看是否能夠成功保存數(shù)據(jù)磕道。
Step 5. iCloud 同步數(shù)據(jù)
為了讓demo程序更加好用供屉,我們用iCloud來(lái)同步設(shè)備間的數(shù)據(jù)。這個(gè)過(guò)程非常的簡(jiǎn)單捅厂。
iCloud's Key-Value Storage 和 NSUserDefaults 用法非常的像贯卦,也是存儲(chǔ)key-value鍵值對(duì)。iCloud對(duì)應(yīng)的類(lèi)叫做 NSUbiquitousKeyValueStore焙贷。
我們先來(lái)實(shí)現(xiàn)iCloud的存儲(chǔ)撵割。
在saveVolume() 方法中,仿造NSUserDefaults寫(xiě)NSUbiquitousKeyValueStore方法辙芍。(注:NSUserDefaults可以用setValue方法來(lái)存儲(chǔ)啡彬。NSUbiquitousKeyValueStore用這個(gè)方法程序缺一直crash。不知道是swift的坑還是什么故硅。這里先轉(zhuǎn)換成double值庶灿,用setDouble試一下。)
func saveVolume() {
let ud = NSUserDefaults.standardUserDefaults()
let trackVolume = track.volume
ud.setValue(trackVolume, forKey: "Track")
// Save to iCloud
let store = NSUbiquitousKeyValueStore.defaultStore()
let trackVolumeDouble = Double(trackVolume)
store.setDouble(trackVolumeDouble, forKey: "Track")
store.synchronize()
println("Saving to iCloud")
}
那么我們的demo程序是如何知道其他設(shè)備中的程序已經(jīng)改變了iCloud 中的Key-Value吃衅,把改動(dòng)同步到當(dāng)前設(shè)備的呢往踢?
每當(dāng) Key-Value 被改變,程序會(huì)發(fā)送一個(gè)notification出來(lái)徘层,我們的程序收到這個(gè)notification峻呕,把數(shù)據(jù)覆蓋到本地就可以了。
在 viewDidLoad() 中做4件事趣效。
首先得到Key-Value Store的引用瘦癌。
把我們的View Controller當(dāng)做一個(gè)監(jiān)聽(tīng)器。監(jiān)聽(tīng)NSUbiquitousKeyValueStoreDidChangeExternallyNotification
當(dāng)接受到這個(gè)notification的時(shí)候跷敬,用updateKeyValuePairs: 方法來(lái)處理它讯私。給store發(fā)送一個(gè)synchronize消息。
-
刷新數(shù)據(jù)
override func viewDidLoad() { super.viewDidLoad() let store = NSUbiquitousKeyValueStore.defaultStore() NSNotificationCenter.defaultCenter().addObserver(self, selector: Selector("updateKeyValuePairs:"), name: NSUbiquitousKeyValueStoreDidChangeExternallyNotification, object: store) store.synchronize() loadVolume() updateUserInterface() } func updateKeyValuePairs(notification: NSNotification) { println("updateKeyValuePairs") let userInfo = notification.userInfo let changeReason: AnyObject? = userInfo?["NSUbiquitousKeyValueStoreChangeReasonKey"] var reason = -1
if (changeReason == nil) {
return
} else {
reason = changeReason as Int
println("reason is: (reason)")
}if (reason == NSUbiquitousKeyValueStoreServerChange) || (reason == NSUbiquitousKeyValueStoreInitialSyncChange) { let changeKeys = userInfo?["NSUbiquitousKeyValueStoreChangedKeysKey"] as NSArray let store = NSUbiquitousKeyValueStore.defaultStore() for key in changeKeys { if key.isEqualToString("Track") { // Update Data Source let trackVolumeFromStore = store.doubleForKey("Track") as Double println("track volume from store: \(trackVolumeFromStore)") // Save Local Copy track.volume = Float(trackVolumeFromStore) let ud = NSUserDefaults.standardUserDefaults() ud.setValue(trackVolumeFromStore, forKey: "Track") updateUserInterface() } } }
}
在兩臺(tái)設(shè)備中運(yùn)行程序西傀。改變一臺(tái)設(shè)備的數(shù)據(jù)斤寇。觀察另一臺(tái)設(shè)備的打印日志〕仄啵可以看到它接受到通知抡驼,調(diào)用了
updateKeyValuePairs:
GitHub:
https://github.com/vivijie/iCloudTest
參考文獻(xiàn):
http://code.tutsplus.com/tutorials/working-with-icloud-key-value-storage--pre-37542