-1

この質問は、ネストされた NSDictionary の NSNull の出現を置換するに似ています

迅速にエラーが発生します(NSNullが原因だと思います)NSNullが空の文字列になるかnilになるかはあまり気にしません。コードを機能させたいだけです。

JSONからNSDictionaryとして入ってくる大きなデータ構造があります。次に、それを一時ファイルに保存しています。コードは次のとおりです。

var jsonResult = NSJSONSerialization.JSONObjectWithData(data, options: .MutableContainers, error: &err) as! NSDictionary

let json = JSON(jsonResult)

if (json["errors"].array?.count > 0) {
                println("could not load stuff")
            } else {
                println("retrieving the stuff")

                let file = "file.txt"
                let file_path = NSTemporaryDirectory() + file
                let dict:NSDictionary = jsonResult
                let readDict:NSDictionary? = NSDictionary(contentsOfFile: file_path)

                    if dict.writeToFile(file_path, atomically: true) {
                        let readDict:NSDictionary? = NSDictionary(contentsOfFile: file_path)

                        //--- need to handle the NSNull junk here


                        if let dict = readDict {
                            println("Temp file created, here are the contents: \(dict)")
                        } else {
                            println("!!!Failed to READ the dictionary data back from disk.")
                        }
                    }
                    else {
                        println("!!!Failed to WRITE the dictionary to disk.")
                    }
                }

jsonResult がどのように見えるかの例を次に示します

things = (
  {
                "one" = one;
                two = "<null>";
                "three" = three;
                "four" = "<null>";
                "five" = five;
                "six" = "six-6";
                seven = 7;
                eight = eight;
                nine = "<null>";
                ten = "<null>";
                eleven = "<null>";
                "twelve" = "<null>";
            },
4

1 に答える 1

1

アップデート:

問題: 非常に大量の JSON (テキストとして約 600 KB) があり、その JSON データ内に null があります。私が抱えていた問題は、NSJSONSerialization を NSDictionary として実行すると、null が NSNull オブジェクトに変換されることです (文字列として表示されるため、これを印刷するとファンキーに見えますが、これは間違っています。

解決策: 「プルーニング」または「サニタイズ」された辞書が必要です。これが意味することは、キーと値を完全に捨てることです。これを行うために、sanitized_dict 関数を追加しました。関数は次のとおりです。

func sanitize_dict(obj: AnyObject) -> AnyObject {

    if obj.isKindOfClass(NSDictionary) {

        var saveableObject = obj as! NSMutableDictionary

        for (key, value) in obj as! NSDictionary {

            if (value.isKindOfClass(NSNull)) {

                //println("Removing NSNull for: \(key)")

                saveableObject.removeObjectForKey(key)

            }

            if (value.isKindOfClass(NSArray)) {

                let tmpArray: (AnyObject) = sanitize_dict(value as! NSArray)

                saveableObject.setValue(tmpArray, forKey: key as! String)

            }

            if (value.isKindOfClass(NSDictionary)) {

                let tmpDict: (AnyObject) = sanitize_dict(value as! NSDictionary)

                saveableObject.setValue(tmpDict, forKey: key as! String)

            }

        }

        return saveableObject



    //--- because arrays are handled differently,

    //--- you basically need to do the same thing, but for an array

    //--- if the object is an array

    } else if obj.isKindOfClass(NSArray) {

        var saveableObject = [AnyObject]()

        for (index, ele) in enumerate(obj as! NSArray) {

            if (ele.isKindOfClass(NSNull)) {

                // simply don't add element to saveableobject and we're good

            }

            if (ele.isKindOfClass(NSArray)) {

                let tmpArray: (AnyObject) = sanitize_dict(ele as! NSArray)

                saveableObject.append(tmpArray)

            }

            if (ele.isKindOfClass(NSDictionary)) {

                let tmpDict: (AnyObject) = sanitize_dict(ele as! NSDictionary)

                saveableObject.append(tmpDict)

            }

        }

        return saveableObject

    }



    // this shouldn't happen, but makes code work

    var saveableObject = [AnyObject]()

    return saveableObject

}

したがって、他のコードはその関数を呼び出す必要があり、次のようになります。

変数エラー: NSError?

        var jsonResult = NSJSONSerialization.JSONObjectWithData(data, options: .MutableContainers, error: &err) as! NSDictionary

        //--- right now jsonResult is not actual json, and actually has the NSNulls

        //--- get that result into the sanitized function above

        let saveableDict: (AnyObject) = self.sanitize_dict(jsonResult)

        let json = JSON(saveableDict)



        if (json["errors"].array?.count > 0) {

            println("!!!Failed to load.")

        } else {

            println("Load json successful. Attempting to save file...")



            //--- set up basic structure for reading/writing temp file

            let file = "file.txt"

            let file_path = NSTemporaryDirectory() + file

            let dict:NSDictionary = jsonResult

            let readDict:NSDictionary? = NSDictionary(contentsOfFile: file_path)



                if dict.writeToFile(file_path, atomically: true) {

                    let readDict:NSDictionary? = NSDictionary(contentsOfFile: file_path)



                    if let dict = readDict {

                        println("Temp file created, here are the contents: \(dict)")

                    } else {

                        println("!!!Failed to READ the dictionary data back from disk.")

                    }

                }

                else {

                    println("!!!Failed to WRITE the dictionary to disk.")

                }

            }

これが、大きな JSON データセットと null を使用する誰かに役立つことを願っています。それはすべてそのサニタイズ機能です!

于 2015-05-05T17:08:49.613 に答える