我正在编写我的第一个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 ===== 零
答案 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”,我不确定这是你期望的......