【发布时间】:2016-02-01 06:32:22
【问题描述】:
我正在编写我的第一个 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”:“登录”,“userList”:[{“密码”:“字符串”,“电子邮件”:“字符串”}],“deviceList”:[{“deviceToken”:“字符串","os":"String","ver":"String","osType":"String","height":1,"width":1,"IP":"String"}],"errorList ": [{"errorCode": 1, "errorText": "String"}]}} ==== 打印转换为 NSData 并使用 NSJSONSerialization.JSONObjectWithData 后创建的对象==== [“json”:{ 设备列表 = ( { IP = 字符串; 设备令牌 = 字符串; 高度 = 1; 操作系统 = 字符串; osType = 字符串; 版本 = 字符串; 宽度 = 1; } ); 错误列表 = ( { 错误代码 = 1; 错误文本 = 字符串; } ); pType = 登录; 用户列表 = ( { 电子邮件=字符串; 密码=字符串; } ); }] 可选的(( { IP = 字符串; 设备令牌 = 字符串; 高度 = 1; 操作系统 = 字符串; osType = 字符串; 版本 = 字符串; 宽度 = 1; } )) ==== 试图获取内部数据并得到 nil===== 无
【问题讨论】:
-
你的代码有什么问题?
-
我不知道如何获取数据,就像我尝试的那样:let deviceList = json6["json"]!["deviceList"]?!["IP"] let ip = deviceList ?!["IP"] print("==== 试图获取内部数据并得到 nil=====") print (ip)
-
你得到什么错误?什么意外日志?不要指望我们有一个操场,所以我们可以运行你所有的代码,让问题自己说清楚。
-
大部分代码是将类转换为 jscon 的实用程序,我的代码标有备注,在最后 3 行中,我尝试提取值“IP”并打印它并获得 null ,但如果你没有 playGround 我认为很难看到它,将游乐场结果添加到原始问题
标签: ios json swift dictionary