快速的json操作,无法获取数据

时间:2015-11-01 05:46:42

标签: ios json swift dictionary

我正在编写我的第一个swift代码,尝试使用Json,我使用在GitHub中找到的JSONSerializer来帮助我将类转换为json,这部分工作正常,现在我试图将Json字符串转换为字典并获取数据我无法做到这一点,我附上了我的playGround代码,有人可以帮我吗?

import UIKit
import Foundation

   /// Handles Convertion from instances of objects to JSON strings.      Also     helps with casting strings of JSON to Arrays or Dictionaries.
public class JSONSerializer {

/**
 Errors that indicates failures of JSONSerialization
 - JsonIsNotDictionary: -
 - JsonIsNotArray:          -
 - JsonIsNotValid:          -
 */
public enum JSONSerializerError: ErrorType {
    case JsonIsNotDictionary
    case JsonIsNotArray
    case JsonIsNotValid
}

//http://stackoverflow.com/questions/30480672/how-to-convert-a-json-string-to-a-dictionary
/**
Tries to convert a JSON string to a NSDictionary. NSDictionary can be easier to work with, and supports string bracket referencing. E.g. personDictionary["name"].
- parameter jsonString: JSON string to be converted to a NSDictionary.
- throws: Throws error of type JSONSerializerError. Either JsonIsNotValid or JsonIsNotDictionary. JsonIsNotDictionary will typically be thrown if you try to parse an array of JSON objects.
- returns: A NSDictionary representation of the JSON string.
*/
public static func toDictionary(jsonString: String) throws -> NSDictionary {
    if let dictionary = try jsonToAnyObject(jsonString) as? NSDictionary {
        return dictionary
    } else {
        throw JSONSerializerError.JsonIsNotDictionary
    }
}

/**
 Tries to convert a JSON string to a NSArray. NSArrays can be iterated and each item in the array can be converted to a NSDictionary.
 - parameter jsonString:    The JSON string to be converted to an NSArray
 - throws: Throws error of type JSONSerializerError. Either JsonIsNotValid or JsonIsNotArray. JsonIsNotArray will typically be thrown if you try to parse a single JSON object.
 - returns: NSArray representation of the JSON objects.
 */
public static func toArray(jsonString: String) throws -> NSArray {
    if let array = try jsonToAnyObject(jsonString) as? NSArray {
        return array
    } else {
        throw JSONSerializerError.JsonIsNotArray
    }
}

/**
 Tries to convert a JSON string to AnyObject. AnyObject can then be casted to either NSDictionary or NSArray.
 - parameter jsonString:    JSON string to be converted to AnyObject
 - throws: Throws error of type JSONSerializerError.
 - returns: Returns the JSON string as AnyObject
 */
private static func jsonToAnyObject(jsonString: String) throws -> AnyObject? {
    var any: AnyObject?

    if let data = jsonString.dataUsingEncoding(NSUTF8StringEncoding) {
        do {
            any = try NSJSONSerialization.JSONObjectWithData(data, options: .MutableContainers)
        }
        catch let error as NSError {
            let sError = String(error)
            NSLog(sError)
            throw JSONSerializerError.JsonIsNotValid
        }
    }
    return any
}

/**
 Generates the JSON representation given any custom object of any custom class. Inherited properties will also be represented.
 - parameter object:    The instantiation of any custom class to be represented as JSON.
 - returns: A string JSON representation of the object.
 */
public static func toJson(object: Any) -> String {
    var json = "{"
    let mirror = Mirror(reflecting: object)

    var children = [(label: String?, value: Any)]()
    let mirrorChildrenCollection = AnyRandomAccessCollection(mirror.children)!
    children += mirrorChildrenCollection

    var currentMirror = mirror
    while let superclassChildren = currentMirror.superclassMirror()?.children {
        let randomCollection = AnyRandomAccessCollection(superclassChildren)!
        children += randomCollection
        currentMirror = currentMirror.superclassMirror()!
    }

    let size = children.count
    var index = 0

    for (optionalPropertyName, value) in children {

        /*let type = value.dynamicType
        let typeString = String(type)
        print("SELF: \(type)")*/

        let propertyName = optionalPropertyName!
        let property = Mirror(reflecting: value)

        var handledValue = String()
        if value is Int || value is Double || value is Float || value is Bool {
            handledValue = String(value ?? "null")
        }
        else if let array = value as? [Int?] {
            handledValue += "["
            for (index, value) in array.enumerate() {
                handledValue += value != nil ? String(value!) : "null"
                handledValue += (index < array.count-1 ? ", " : "")
            }
            handledValue += "]"
        }
        else if let array = value as? [Double?] {
            handledValue += "["
            for (index, value) in array.enumerate() {
                handledValue += value != nil ? String(value!) : "null"
                handledValue += (index < array.count-1 ? ", " : "")
            }
            handledValue += "]"
        }
        else if let array = value as? [Float?] {
            handledValue += "["
            for (index, value) in array.enumerate() {
                handledValue += value != nil ? String(value!) : "null"
                handledValue += (index < array.count-1 ? ", " : "")
            }
            handledValue += "]"
        }
        else if let array = value as? [Bool?] {
            handledValue += "["
            for (index, value) in array.enumerate() {
                handledValue += value != nil ? String(value!) : "null"
                handledValue += (index < array.count-1 ? ", " : "")
            }
            handledValue += "]"
        }
        else if let array = value as? [String?] {
            handledValue += "["
            for (index, value) in array.enumerate() {
                handledValue += value != nil ? "\"\(value!)\"" : "null"
                handledValue += (index < array.count-1 ? ", " : "")
            }
            handledValue += "]"
        }
        else if let array = value as? [String] {
            handledValue += "["
            for (index, value) in array.enumerate() {
                handledValue += "\"\(value)\""
                handledValue += (index < array.count-1 ? ", " : "")
            }
            handledValue += "]"
        }
        else if let array = value as? NSArray {
            handledValue += "["
            for (index, value) in array.enumerate() {
                if !(value is Int) && !(value is Double) && !(value is Float) && !(value is Bool) && !(value is String) {
                    handledValue += toJson(value)
                }
                else {
                    handledValue += "\(value)"
                }
                handledValue += (index < array.count-1 ? ", " : "")
            }
            handledValue += "]"
        }
        else if property.displayStyle == Mirror.DisplayStyle.Class {
            handledValue = toJson(value)
        }
        else if property.displayStyle == Mirror.DisplayStyle.Optional {
            let str = String(value)
            if str != "nil" {
                handledValue = String(str).substringWithRange(Range<String.Index>(start: str.startIndex.advancedBy(9), end: str.endIndex.advancedBy(-1)))
            } else {
                handledValue = "null"
            }
        }
        else {
            handledValue = String(value) != "nil" ? "\"\(value)\"" : "null"
        }

        json += "\"\(propertyName)\": \(handledValue)" + (index < size-1 ? ", " : "")
        ++index
    }
    json += "}"
    return json
}
}

          /***********************************************************************/
/* This is my code                                                     */
/***********************************************************************/
class jsonContainer{
var json:LoginToSend
init(){
    json = LoginToSend(password:"String",email:"String",
    deviceToken:"String",
    os:"String",
    osType:"String",
    ver:"String",
    height:1,
    width:1,
    IP:"String",
    errorCode:1,
    errorText:"String")

}
}
class LoginToSend{
var pType:String = "Login"
var userList :Array<AnyObject> = []
var deviceList :Array<AnyObject> = []
var errorList :Array<AnyObject> = []


//    var userList:UserList
init(password:String,email:String,
    deviceToken:String,
    os:String,
    osType:String,
    ver:String,
    height:Int,
    width:Int,
    IP:String,
    errorCode:Int,
    errorText:String){

        let userLista = UserList(password: password,email: email)
        userList.append(userLista)
        let deviceLista = DeviceList(deviceToken: deviceToken,
            os: os,
            ver: ver,
            osType: osType,
            height: height,
            width: width,
            IP: IP)
        deviceList.append(deviceLista)
        let errorLista = ErrorList(errorCode: errorCode, errorText: errorText)
        errorList.append(errorLista)

}
}
class UserList{
var Password = ""
var Email = ""
init( password:String,  email:String){
    Password = password
    Email = email
 }

}
class DeviceList{
var deviceToken = ""
var os = ""
var ver = ""
var osType = ""
var height = -1
var width = -1
var IP = ""
init(deviceToken:String, os:String, ver:String, osType:String,height:Int,width:Int,IP:String){
    self.deviceToken = deviceToken
    self.os = os
    self.ver = ver
    self.osType = osType
    self.height = height
    self.width = width
    self.IP = IP
}
}
class ErrorList{
var errorCode = -1
var errorText = ""
init(errorCode:Int,errorText:String)
{
    self.errorCode = errorCode
    self.errorText = errorText
}
}
var loginToSend = LoginToSend(password:"String",email:"String",
deviceToken:"String",
os:"String",
osType:"String",
ver:"String",
height:1,
width:1,
IP:"String",
errorCode:1,
errorText:"String")
//*****************************************************
//* Creating json from my classes                     *
//*****************************************************

var json1 = JSONSerializer.toJson(loginToSend)

// next line Create the structure i need **
json1 = "{\"json\":" + json1 + "}"
print("===== print the consructed json ====")

print(json1)

let data = json1.dataUsingEncoding(NSUTF8StringEncoding,     allowLossyConversion: false)!

let json6 = try NSJSONSerialization.JSONObjectWithData(data, options: []) as! [String: AnyObject]
print("==== print the objects created after converting to NSData and  using NSJSONSerialization.JSONObjectWithData====")

print (json6)
//let j = json6[json]
//let c = j[deviceList]
print (json6["json"]!["deviceList"])
let deviceList = json6["json"]!["deviceList"]?!["IP"]
let ip = deviceList?!["IP"]
print("==== Trying to get internal dta and get nil=====")
print (ip)

这是playGround outPut

=====打印构成的json ==== {“json”:{“pType”:“Login”,“userList”:[{“Password”:“String”,“Email”:“String”}],“deviceList”:[{“deviceToken”:“String “,”os“:”String“,”ver“:”String“,”osType“:”String“,”height“:1,”width“:1,”IP“:”String“}],”errorList “:[{”errorCode“:1,”errorText“:”String“}]}} ====打印转换为NSData后使用NSJSONSerialization.JSONObjectWithData ====创建的对象 [“json”:{     deviceList =(                 {             IP =字符串;             deviceToken = String;             height = 1;             os = String;             osType = String;             ver = String;             width = 1;         }     );     errorList =(                 {             errorCode = 1;             errorText = String;         }     );     pType =登录;     userList =(                 {             Email = String;             密码=字符串;         }     ); }] 可选的((         {         IP =字符串;         deviceToken = String;         height = 1;         os = String;         osType = String;         ver = String;         width = 1;     } )) ====尝试获取内部dta并获得nil ===== 零

1 个答案:

答案 0 :(得分:1)

我只看了你代码的最后一部分,与你的问题相关的部分,以及我看到的你应该真正使用安全解包

我只是通过摆脱!展开的所有力量并用安全的可选绑定替换它来使你的代码工作。

此外,deviceList是一个数组,而不是字典。

因此,在行let data = json1.dataUsingEncoding.....之后,用此替换所有内容,它将起作用:

if let json6 = try NSJSONSerialization.JSONObjectWithData(data, options: []) as? [String: AnyObject] {
    if let innerJSON = json6["json"] as? [String: AnyObject], let deviceList = innerJSON["deviceList"] as? [[String: AnyObject]] {
        for device in deviceList {
            print(device["IP"])
        }
    }
}

这个想法是使用可选绑定将对象强制转换为正确的类型:json6是一个字典,它的“json”键有一个值的字典,这个字典的“deviceList”键包含一个数组包含IP的词典。

请注意,您的JSON数据似乎包含错误。 'IP'字段包含字符串“String”,我不确定这是你期望的......