"Невозможно добавить значение словаря типа ' Ошибка с индексом типа «Строка» - PullRequest
0 голосов
/ 21 января 2020

Я работал над проектом, которому нужно восстановить сохраненные данные из .plist, но я обнаружил ошибку Невозможно добавить значение типа «Словарь» с индексом типа «Строка» в моем коде. Я пытаюсь решить это, но, к сожалению, я не знаю как. Я попробовал какое-то решение, которое я получил здесь в stackoverflow , но оно не сработало. Пожалуйста, помогите мне с этим, потому что я впервые создаю функцию для восстановления данных. Спасибо

error here

 @objc func restoreSucceed() {
    performSelector(inBackground: #selector(stopIndicator), with: nil)
    //エラーアラートビューの表示
    let alertController = UIAlertController(title: "", message: "リストアが完了しました \n (Restore completed)", preferredStyle: .alert)
    alertController.addAction(UIAlertAction(title: "OK", style: .default))
    self.present(alertController, animated: true, completion: nil)

    if floor(NSFoundationVersionNumber) > NSFoundationVersionNumber_iOS_7_1 {
        var pref = UserDefaults.standard
        //ローカルplist格納先を取得
        let strWorkPath = NSSearchPathForDirectoriesInDomains(.libraryDirectory, .userDomainMask, true)[0]
        let strPlistPath = "\(strWorkPath)/\(S_DIRECTORY_NAME)/\(S_PLIST_NAME)"
        let dicPref = NSDictionary(contentsOfFile: strPlistPath) as Dictionary?
        if let key1 = (dicPref as NSDictionary?)?.keyEnumerator() {
            for key in key1 {
                let strKey = key as? String
                pref.set(dicPref?[strKey ?? ""], forKey: strKey ?? "")
            }
        }
        pref.synchronize()
    }

    navigationController?.popViewController(animated: true)
}

Ответы [ 5 ]

2 голосов
/ 21 января 2020

Используйте следующее

pref.set(dicPref?[strKey! as NSString], forKey: strKey ?? "")

@ Ответ Роя верный, но он предупредит вас о развертывании

1 голос
/ 21 января 2020

В вашем коде используется много неуместных target- c -i sh API.

Это рекомендуемый Swift способ чтения и анализа файла списка свойств

if #available(iOS 7.1, *) {   
    //ローカルplist格納先を取得
    do {
        let strWorkURL = try FileManager.default.url(for: .libraryDirectory, in: .userDomainMask, appropriateFor: nil, create: false)
        let strPlistURL = strWorkURL.appendingPathComponent("\(S_DIRECTORY_NAME)/\(S_PLIST_NAME)")
        let strPlistData = try Data(contentsOf: strPlistURL)
        guard let dicPref = try PropertyListSerialization.propertyList(from: strPlistData, format: nil) as? [String:Any] else { return }
        for (key, value) in dicPref {
            UserDefaults.standard.set(value, forKey: key)
        }
    } catch { print(error) }
}

И не используйте performSelector(inBackground:). Использовать GCD

DispatchQueue.global().async {
    stopIndicator()
}
1 голос
/ 21 января 2020

Заменить dicPref?[strKey ?? ""] на dicPref?[strKey as! NSString]

Примечание: по возможности избегайте принудительного разворачивания.

0 голосов
/ 21 января 2020

Попробуйте код ниже

var pref = UserDefaults.standard
let strWorkPath = NSSearchPathForDirectoriesInDomains(.libraryDirectory, .userDomainMask, true)[0]
let strPlistPath = "\(strWorkPath)/\(S_DIRECTORY_NAME)/\(S_PLIST_NAME)"

if let dicPref = NSDictionary(contentsOfFile: strPlistPath) as? Dictionary<String, AnyObject> {
     // use swift dictionary as normal
     if let key1 = (dicPref as NSDictionary?)?.keyEnumerator() {
         for key in key1 {
             if let strKey = key as? String {
                 pref.set(dicPref[strKey], forKey: strKey)
             }
          }
      }
}

pref.synchronize()
0 голосов
/ 21 января 2020

заменить:

let dicPref = NSDictionary(contentsOfFile: strPlistPath) as Dictionary?

на:

 let dicPref = NSDictionary(contentsOfFile: strPlistPath)

.

 let pref = UserDefaults.standard

    let dicPref = NSDictionary(contentsOfFile: "")
    if let key1 = dicPref?.keyEnumerator() {
        for key in key1 {
            let strKey = key as? String
            pref.set(dicPref?[strKey ?? ""], forKey: strKey ?? "")
        }
    }
...