首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >用Swift实现iCloud密钥值存储

用Swift实现iCloud密钥值存储
EN

Stack Overflow用户
提问于 2017-06-19 02:03:10
回答 1查看 2.2K关注 0票数 0

在我的应用程序中实现密钥值存储时,我遇到了麻烦。我所有的iCloud相关代码都在我的ViewController中,如下所示:

代码语言:javascript
复制
import UIKit
import CloudKit
import NotificationCenter

var purchased = [[Bool]]() {
    didSet {
        instance.saveToiCloud()
        print("SAVED")
    }
}
var rockAmount = 0 {
    didSet {
        instance.saveToiCloud()
        print("SAVED")
    }
}
var goldAmount = 0 {
    didSet {
        instance.saveToiCloud()
        print("SAVED")
    }
}
var adBlock = false {
    didSet {
        instance.saveToiCloud()
        print("SAVED")
    }
}

var instance = GameViewController()

class GameViewController: UIViewController {
var iCloudKeyStore: NSUbiquitousKeyValueStore?

var interstitial: GADInterstitial!
var rewardAd = GADRewardBasedVideoAd()
var instRequest = receivingInst.GameScene //Placeholder

var instCatch = false
var rewardCatch = false

override func viewDidLoad() {
    super.viewDidLoad()

    //Set up iCloud Key-Value Storage
    iCloudKeyStore = NSUbiquitousKeyValueStore()
    iCloudKeyStore?.synchronize()

    //Retrieve Assets from database
    retrieveAssets()

    NotificationCenter.default.addObserver(self, selector: #selector(GameViewController.ubiquitousKeyValueStoreDidChange), name: NSUbiquitousKeyValueStore.didChangeExternallyNotification, object: iCloudKeyStore)

    instance = self

    if let view = self.view as! SKView? {
        // Load the SKScene from 'GameScene.sks'
        //if let scene = SKScene(fileNamed: "GameScene") {
        if let scene = SKScene(fileNamed: "LaunchScene") {
            // Set the scale mode to scale to fit the window
            scene.scaleMode = .aspectFill //.fill
            // Present the scene
            view.presentScene(scene)
        }

        view.ignoresSiblingOrder = true

        //view.showsFPS = true
        //view.showsPhysics = true
    }
}

func retrieveAssets() {
    //notFirst is to determine if it is the first ti
    let notFirst = UserDefaults.standard.bool(forKey: "notFirst")
    if !notFirst {
        //Create iCloud References
        var c = 0
        while c < 4 {
            var keyMake = ""
            switch c {
            case 0: keyMake = "purchasedCloud"
                saveToiCloudArray(purchased, keyMake)
            case 1: keyMake = "goldCloud"
                saveToiCloudInt(0, keyMake)
            case 2: keyMake = "rocksCloud"
                saveToiCloudInt(0, keyMake)
            case 3: keyMake = "adBlockCloud"
                saveToiCloudBool(false, keyMake)
            default: break
            }
            c += 1
        }

        print("SET")
    }

    //Retrieve iCloud Data
    getValuesFromiCloud()
}

func ubiquitousKeyValueStoreDidChange(notification: NSNotification) {
    let alert = UIAlertController(title: "Change detected",
                                  message: "iCloud key-value-store change detected",
                                  preferredStyle: UIAlertControllerStyle.alert)
    let cancelAction = UIAlertAction(title: "OK",
                                     style: .cancel, handler: nil)
    alert.addAction(cancelAction)
    self.present(alert, animated: true,
                 completion: nil)
    getValuesFromiCloud()
}

func iCloudGetInt(_ key: String) -> Int {
    var str = 0
    if let saved = iCloudKeyStore?.object(forKey: key) {
        print("B-INT\(saved)")
        str = saved as! Int
        print("A-INT\(saved)")
    } else {
        str = -10
        print("IntFailed")
    }
    return str
}

func iCloudGetArray(_ key: String) -> [[Bool]] {
    var str = [[Bool]]()
    if let saved = iCloudKeyStore?.array(forKey: key){
        print("B-AR\(saved)")
        str = saved as! [[Bool]]
        print("A-AR\(saved)")
    } else {
        str = [[]]
        print("ArFailed")
    }
    return str
}

func iCloudGetBool(_ key: String) -> Bool {
    var str = false
    if let saved = iCloudKeyStore?.bool(forKey: key){
        print("B-BOOL\(saved)")
        str = saved as! Bool
        print("A-BOOL\(saved)")
    } else {
        str = false
        print("BoolFailed")
    }
    return str
}

//Set if stored icloud value is greater than current (on button activation)
func saveToiCloudArray(_ txt: [[Bool]],_ key: String) {
    iCloudKeyStore?.set(txt, forKey: key)
    //iCloudKeyStore?.synchronize()
}

func saveToiCloudInt(_ txt: Int,_ key: String) {
    iCloudKeyStore?.set(txt, forKey: key)
    //iCloudKeyStore?.synchronize()
}

func saveToiCloudBool(_ txt: Bool,_ key: String) {
    iCloudKeyStore?.set(txt, forKey: key)
    //iCloudKeyStore?.synchronize()
}

func getValuesFromiCloud() {
    var c = 0
    while c < 4 {
        var keyMake = ""
        switch c {

        case 0: keyMake = "purchasedCloud"
            let ar = iCloudGetArray(keyMake)
            if !ar.isEmpty {
                purchased = ar
                UserDefaults.standard.set(purchased, forKey: "purchased")
            } else {
                print("Error\(keyMake)")
            }
        case 1: keyMake = "goldCloud"
            let g = iCloudGetInt(keyMake)
            if g != -10 {
                goldAmount = g
                UserDefaults.standard.set(goldAmount, forKey: "goldAmount")
            } else {
                print("Error\(keyMake)")
            }
        case 2: keyMake = "rocksCloud"
            let r = iCloudGetInt(keyMake)
            if r != -10 {
                rockAmount = r
                UserDefaults.standard.set(rockAmount, forKey: "rockAmount")
            } else {
                print("Error\(keyMake)")
            }
        case 3: keyMake = "adBlockCloud"
            let r = iCloudGetBool(keyMake)
            adBlock = r
            UserDefaults.standard.set(adBlock, forKey: "adBlock")

        default: break
        }
        c += 1
    }
    print(purchased, rockAmount, goldAmount)
}

func saveToiCloud() {
    var c = 0
    while c < 4 {
        var keyMake = ""
        switch c {
        case 0: keyMake = "purchasedCloud"
            saveToiCloudArray(purchased, keyMake)
        case 1: keyMake = "goldCloud"
            saveToiCloudInt(goldAmount, keyMake)
        case 2: keyMake = "rocksCloud"
            saveToiCloudInt(rockAmount, keyMake)
        case 3: keyMake = "adBlockCloud"
            saveToiCloudBool(adBlock, keyMake)
        default: break
        }
        c += 1
    }
}

我意识到代码不是优化的,也不是很干净的,但这是因为我已经尝试了很多不同的东西

我已经在我的功能中启用了iCloud,并为供应配置文件做了一切事情(容器存在并且是有效的):

我想知道也许我的问题是两件事中的一件:

  1. 我的代码应该在AppDelegate中,而不是在ViewController中。

  1. 我需要在这里写一个权限( .entitlements文件可以访问它):

突出显示的红色部分是我正在考虑更改的部分( iCloud密钥-值存储)。我是否打算写我自己的东西而不是$(TeamIdentifierPrefix)$(CFBundleIdentifier)?它说那是com.apple.developer.ubiquity-kvstore-identifier,但是这意味着什么,如果我需要的话,我应该如何填写它(例如泛库-kvstore-标识符是什么)?

任何形式的帮助和指导都将不胜感激。谢谢。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2017-06-19 08:40:10

我找到的解决方案是使用默认容器,而不是为iCloud使用指定的容器。我不知道2之间的真正区别是什么,但改变成这样对我有用。

此外,我不确定这是否有助于解决如何存储iCloud键值数据,但我将代码放入AppDelegate而不是ViewController中。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/44621313

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档