将 Json 数组映射到对象失败

Mapping Json Array to Object fails

我尝试将来自服务器的 JSON 响应转换为对象。我用 Swift.

这是打印服务器响应的结果:

(
    {
    1 = Horst;
    2 = Schnitzelhuber;
    3 = "0161 2213310";
    id = 0000040001;
    status = 2;
},
    {
    1 = "Mar\U00f0a";
    3 = "0163 5419374";
    id = 0000040005;
    status = 2;
}
)

这是我的模型:

class Profil: JSONSerializable {   
  var id: String?    
  required init() {}

  class func map(source: JsonSZ, object: Profil) {
    object.id <= source["id"]
  }
}

到目前为止,我一直在使用 SwiftJZ 进行解析。

let test: [Profil!]? = serializer.fromJSONArray(response, to: Profil.self)

如果我尝试打印映射对象:

println(test?[0].id)

=> 结果始终为零

这是JSONSZ的相关方法:

public func fromJSONArray<N: JSONSerializable>(JSON: AnyObject,  to type: N.Type) -> [N]? {
    if let string = JSON as? String {
        if let data =  JSON.dataUsingEncoding(NSUTF8StringEncoding, allowLossyConversion: true) {
            let parsed: AnyObject? = NSJSONSerialization.JSONObjectWithData(data, options: NSJSONReadingOptions.AllowFragments, error: nil)
      => FAIL if let array = parsed as? [[String: AnyObject]] {
                var objects: [N] = []

                for element in array {
                    self.values = element
                    var object = N()
                    N.map(self, object: object)
                    objects.append(object)
                }

                return objects
            }
        }
    }
    return nil
}

你能帮我快速解决这个问题吗?
也许另一个图书馆...
最后我想将模型的这个对象保存到 Cora Data 中。

编辑:

public func fromJSONArray<N: JSONSerializable>(JSON: AnyObject,  to type: N.Type) -> [N]? {
    if let string = JSON as? String {
        if let data =  JSON.dataUsingEncoding(NSUTF8StringEncoding, allowLossyConversion: true) {
            let parsed: AnyObject? = NSJSONSerialization.JSONObjectWithData(data, options: NSJSONReadingOptions.AllowFragments, error: nil)

问题来了:let parsed 为 nil。这就是序列化失败的原因。

我最近一直在做类似的事情,并构建了我自己的相当基本的 JSON 解析库。

这里有一点:

JSON 类型别名

typealias JSON = AnyObject
typealias JSONObject = [String : AnyObject]
typealias JSONArray = [JSON]

JSON可解码协议

// Represents an object that can be imported via JSON
protocol JSONDecodable
{
    func decodeJSON(json: JSONObject)
}

JSON 类型解析

private let iso8601DateFormatter : NSDateFormatter =
{
    let dateFormatter = NSDateFormatter()

    dateFormatter.locale = NSLocale(localeIdentifier: "en_US_POSIX")
    dateFormatter.dateFormat = "yyyy-MM-dd'T'HH:mm:ss.SSSZ"

    return dateFormatter
}()

func jsonString(object: AnyObject?) -> String?
{
    return object as? String
}

func jsonBoolean(object: AnyObject?) -> Bool?
{
    return object as? Bool
}

func jsonInt(object: AnyObject?) -> Int?
{
    return object as? Int
}

func jsonFloat(object: AnyObject?) -> Float?
{
    return object as? Float
}

func jsonDate(object: AnyObject?) -> NSDate?
{
    switch jsonString(object)
    {
    case .Some(let dateString): return iso8601DateFormatter.dateFromString(dateString)
    case .None: return nil
    }
}

func jsonDateString(date: NSDate) -> String
{
    return iso8601DateFormatter.stringFromDate(date)
}

空合并赋值运算符 (a ??= b)

// Null coalesce-assignment operator (a ??= b)
infix operator ??= { associativity left precedence 90 }

func ??= <T>(inout lhs: T, rhs: T?)
{
    // If the right-hand side is not-nil, assign the value to the left-hand
    if let rhs = rhs { lhs = rhs }
}

JSON 结果(枚举)

// Completion handler which receives a JSON result
typealias JSONCompletionHandler = (result: JSONResult) -> Void

enum JSONResult
{
    case Object(JSONObject)  // Dictionary
    case Array(JSONArray)    // Array
    case Null                // No Data
    case Error(NSError)      // Error occurred
}

JSON 数据任务(NSURLSession 扩展)

extension NSURLSession
{
    func jsonDataTaskWithRequest(request: NSURLRequest, completionHandler: JSONCompletionHandler? = nil) -> NSURLSessionDataTask
    {
        return self.dataTaskWithRequest(request) { data, urlResponse, error in

            // Check for network error
            if let error = error
            {
                completionHandler?(result: .Error(error))
                return
            }

            // Check for non-200 HTTP status
            if let httpResponse = urlResponse as? NSHTTPURLResponse
            {
                if httpResponse.statusCode < 200 || httpResponse.statusCode > 299
                {
                    let httpError = NSError(domain: "JSONDataTask", code: httpResponse.statusCode, userInfo: nil)

                    completionHandler?(result: .Error(httpError))
                    return
                }
            }

            var json : JSON?

            // If there is data available, try to deserialize it as JSON
            if data?.length > 0
            {
                // Deserialize the data into a JSON object
                var jsonError : NSError?
                json = NSJSONSerialization.JSONObjectWithData(data, options: NSJSONReadingOptions(0), error: &jsonError)

                if let jsonError = jsonError
                {
                    completionHandler?(result: .Error(jsonError))
                    return
                }
            }

            // Check what kind of JSON object is the root node
            switch json
            {
                // If the root node is a JSON object
            case let jsonObject as JSONObject:
                completionHandler?(result: .Object(jsonObject))

                // If the root node is a JSON array
            case let jsonArray as JSONArray:
                completionHandler?(result: .Array(jsonArray))

                // If there was no JSON data
            default:
                completionHandler?(result: .Null)
            }
        }
    }
}

网络代码示例

let session = NSURLSession.sharedSession()
let request = NSURLRequest(URL: NSURL(string: "http://www.digitlabs.us")!)

let task = session.jsonDataTaskWithRequest(request) { result in 

   switch result
   {
     case Object(let object): // JSON dictionary
     case Array(let array): // JSON array
     case Null: // No Data
     case Error(let error): // Error occurred
   }
}

task.resume()

示例 NSManagedObject Class

class Message : NSManagedObject, JSONDecodable
{
    @NSManaged var identifier : String
    @NSManaged var subject : String
    @NSManaged var bodyText : String
    @NSManaged var unread : NSNumber
    @NSManaged var dateSent : NSDate

    var isUnread : Bool
    {
        get { return self.unread as Bool }
        set { self.unread = NSNumber(bool: newValue) }
    }

    func decodeJSON(json: JSONObject)
    {
        self.identifier ??= jsonString(json["id"])
        self.subject ??= jsonString(json["subject"])
        self.bodyText ??= jsonString(json["bodyText"])
        self.isUnread ??= jsonBoolean(json["isUnread"])
        self.dateSent ??= jsonDate(json["dateSent"])
    }
}