swift parse json-由于数据格式不正确,因此无法读取 代码

这是我的JSON响应值:

 {
   "_embedded": {
    "task": [
        {
            "_embedded": {
                "variable": [
                    {
                        "_links": {
                            "self": {
                                "href": "/process-instance/412a03b7-06ae-11ea-8860-120ef5ab2c25/variables/loanAmount"
                            }
                        },"_embedded": null,"name": "loanAmount","value": "650000","type": "String","valueInfo": {}
                    }
                ]
            },"id": "412a2aca-06ae-11ea-8860-120ef5ab2c25","name": "Quick Evaluation","assignee": "demo","created": "2019-11-14T07:13:27.558+0000","processDefinitionId": "quickEvaluation:1:129ce2b1-0616-11ea-8860-120ef5ab2c25"

        }

    ]
},"count": 13
}

这是结构可编码代码:

import Foundation

public struct TaskID: Codable {
    let embedded: Embedded
}

public struct Embedded: Codable {
    let task: [Task]
}

public struct Task : Codable {

    let embedded: EmbeddedVariable
    let id : String
    let name: String
    let assignee: String
    let created: String
    let processDefinitionId: String
}

public struct EmbeddedVariable: Codable {

    let variable : [Variables]
}

public struct Variables: Codable {

    let value : String
    let name: String
}

我尝试过encodingKey,也尝试使用_embedded。面对同样的问题。

错误日志:由于错误而无法解码响应:

 Alamofire.AFError.
 ResponseSerializationFailureReason.decodingFailed(error: Swift.DecodingError.typeMismatch(Swift.Dictionary<Swift.String,Any>,Swift.DecodingError.Context(codingPath: [],debugDescription: "Expected to decode Dictionary<String,Any> but found an array instead.",underlyingError: nil)))))

由于数据格式不正确,因此无法读取。

这是JSONSerialization的代码:

      // MARK: - URLRequestConvertible
func asURLRequest() throws -> URLRequest {
    let url = try K.ProductionServer.baseURL.asURL()

    var urlRequest = URLRequest(url: url.appendingPathComponent(path))
    print(urlRequest)
    // HTTP Method
    urlRequest.httpMethod = method.rawValue

    let authToken = UserDefaults.standard.string(forKey: "authToken")
    let bearerToken: String = "Bearer " + (authToken ?? "")
    print("baearer token::\(bearerToken)")

    // Common Headers
    urlRequest.setvalue(ContentType.json.rawValue,forHTTPHeaderField: HTTPHeaderField.acceptType.rawValue)
    urlRequest.setvalue(ContentType.json.rawValue,forHTTPHeaderField: HTTPHeaderField.contentType.rawValue)
    urlRequest.setvalue(bearerToken,forHTTPHeaderField: HTTPHeaderField.authentication.rawValue)

    // Parameters
    if let parameters = parameters {
        do {
            urlRequest.httpBody = try JSONSerialization.data(withJSONObject: parameters,options: [])
        } catch {
            throw AFError.parameterEncodingFailed(reason: .jsonEncodingFailed(error: error))
        }
    }

    return urlRequest
}

这是代码json返回响应:

   import Foundation
  import Alamofire

public class APIClient {
@discardableResult
private static func performRequest<T:Decodable>(route:APIRouter,decoder: JSONDecoder = JSONDecoder(),completion:@escaping (AFResult<T>)->Void) -> DataRequest {

    return AF.request(route)
                    .responseDecodable (decoder: decoder){ (response: AFDataResponse<T>) in
                        completion(response.result)
                        print("framework response::",response.result)
    }
}

public static func taskID(id: String,completion:@escaping (AFResult<MyTaskData>)->Void) {

    performRequest(route: APIRouter.TaskById(id: id),completion: completion)
}


}//APIClient
gay1314 回答:swift parse json-由于数据格式不正确,因此无法读取 代码

在您的JSON有效负载中,键 processDefinitionId 的值的末尾有一个逗号。

请尝试使用此JSON格式化程序工具来验证JSON:jsonformatter

"task":[
        {
         //...

         "id": "412a2aca-06ae-11ea-8860-120ef5ab2c25","name": "Quick Evaluation","assignee": "demo","created": "2019-11-14T07:13:27.558+0000","processDefinitionId": "quickEvaluation:1:129ce2b1-0616-11ea-8860-120ef5ab2c25",// remove this coma(,) from this line

        }

更新

CodingKey用作_embedded。尝试以下方式

// MARK: - TaskID
struct TaskID: Codable {
    let embedded: Embedded
    let count: Int

    enum CodingKeys: String,CodingKey {
        case embedded = "_embedded"
        case count
    }
}

// MARK: - Embedded
struct Embedded: Codable {
    let task: [Task]
}

// MARK: - Task
struct Task: Codable {
    let embedded: EmbeddedVariable
    let id,name,assignee,created: String
    let processDefinitionID: String

    enum CodingKeys: String,CodingKey {
        case embedded = "_embedded"
        case id,created
        case processDefinitionID = "processDefinitionId"
    }
}

// MARK: - EmbeddedVariable
struct EmbeddedVariable: Codable {
    let variable: [Variable]
}

// MARK: - Variable
struct Variable: Codable {
    let links: Links
    let name,value,type: String
    let valueInfo: ValueInfo

    enum CodingKeys: String,CodingKey {
        case links = "_links"
        case name,type,valueInfo
    }
}

// MARK: - Links
struct Links: Codable {
    let linksSelf: SelfClass

    enum CodingKeys: String,CodingKey {
        case linksSelf = "self"
    }
}

// MARK: - SelfClass
struct SelfClass: Codable {
    let href: String
}

// MARK: - ValueInfo
struct ValueInfo: Codable {
}

,

如何将可编码结构中的所有embeded更改为_embeded

在您的APIClient类中,默认创建的JSONDecoder实例。并且在解码包括下划线时不会更改键名。

  

JSONDecoder.KeyDecodingStrategy.useDefaultKeys策略是未指定的策略。 Documentation from Apple

代码

public struct TaskID: Codable {
    let _embedded: Embedded
}

public struct Task : Codable {

    let _embedded: EmbeddedVariable
    let id : String
    let name: String
    let assignee: String
    let created: String
    let processDefinitionId: String
}
,

尝试使用QuickType.io

// MARK: - Welcome
struct Welcome: Codable {
    let embedded: WelcomeEmbedded
    let count: Int

    enum CodingKeys: String,CodingKey {
        case embedded = "_embedded"
        case count
    }
}
  

要解析Alamofire响应中的值:

   Alamofire.request(url).responseWelcomeEmbedded { response in
     if let welcomeEmbedded = response.result.value {
       ...
     }
   }
// MARK: - WelcomeEmbedded
struct WelcomeEmbedded: Codable {
    let task: [Task]
}
  

要解析Alamofire响应中的值:

   Alamofire.request(url).responseTask { response in
     if let task = response.result.value {
       ...
     }
   }
// MARK: - Task
struct Task: Codable {
    let embedded: TaskEmbedded
    let id,created
        case processDefinitionID = "processDefinitionId"
    }
}
  

要解析Alamofire响应中的值:

   Alamofire.request(url).responseTaskEmbedded { response in
     if let taskEmbedded = response.result.value {
       ...
     }
   }
// MARK: - TaskEmbedded
struct TaskEmbedded: Codable {
    let variable: [Variable]
}
  

要解析Alamofire响应中的值:

   Alamofire.request(url).responseVariable { response in
     if let variable = response.result.value {
       ...
     }
   }
// MARK: - Variable
struct Variable: Codable {
    let links: Links
    let embedded: JSONNull?
    let name,CodingKey {
        case links = "_links"
        case embedded = "_embedded"
        case name,valueInfo
    }
}
  

要解析Alamofire响应中的值:

   Alamofire.request(url).responseLinks { response in
     if let links = response.result.value {
       ...
     }
   }
// MARK: - Links
struct Links: Codable {
    let linksSelf: SelfClass

    enum CodingKeys: String,CodingKey {
        case linksSelf = "self"
    }
}
To parse values from Alamofire responses:

   Alamofire.request(url).responseSelfClass { response in
     if let selfClass = response.result.value {
       ...
     }
   }
// MARK: - SelfClass
struct SelfClass: Codable {
    let href: String
}
  

要解析Alamofire响应中的值:

   Alamofire.request(url).responseValueInfo { response in
     if let valueInfo = response.result.value {
       ...
     }
   }
// MARK: - ValueInfo
struct ValueInfo: Codable {
}

// MARK: - Helper functions for creating encoders and decoders

func newJSONDecoder() -> JSONDecoder {
    let decoder = JSONDecoder()
    if #available(iOS 10.0,OSX 10.12,tvOS 10.0,watchOS 3.0,*) {
        decoder.dateDecodingStrategy = .iso8601
    }
    return decoder
}

func newJSONEncoder() -> JSONEncoder {
    let encoder = JSONEncoder()
    if #available(iOS 10.0,*) {
        encoder.dateEncodingStrategy = .iso8601
    }
    return encoder
}

// MARK: - Alamofire response handlers

extension DataRequest {
    fileprivate func decodableResponseSerializer<T: Decodable>() -> DataResponseSerializer<T> {
        return DataResponseSerializer { _,response,data,error in
            guard error == nil else { return .failure(error!) }

            guard let data = data else {
                return .failure(AFError.responseSerializationFailed(reason: .inputDataNil))
            }

            return Result { try newJSONDecoder().decode(T.self,from: data) }
        }
    }

    @discardableResult
    fileprivate func responseDecodable<T: Decodable>(queue: DispatchQueue? = nil,completionHandler: @escaping (DataResponse<T>) -> Void) -> Self {
        return response(queue: queue,responseSerializer: decodableResponseSerializer(),completionHandler: completionHandler)
    }

    @discardableResult
    func responseWelcome(queue: DispatchQueue? = nil,completionHandler: @escaping (DataResponse<Welcome>) -> Void) -> Self {
        return responseDecodable(queue: queue,completionHandler: completionHandler)
    }
}
,

这是Alamofire的基本要求。 如果使用以下解析json的结构,应该没有错误。

    Alamofire.request(url,headers: headers).responseJSON { response in
        switch response.result {
        case .success(let value):
            let jsonData = value as! NSDictionary
            completionHandler(jsonData,nil)
            print("****** JSON \(jsonData)")
        case .failure(let error):
            completionHandler(nil,error)
        }

在这里,我将其放置在您的代码中。 您应该尝试如下所示的标题。 您需要填写适当的标题。

func asURLRequest() throws -> URLRequest {
    let url = try K.ProductionServer.baseURL.asURL()

    var urlRequest = URLRequest(url: url.appendingPathComponent(path))
    print(urlRequest)
    // HTTP Method
    urlRequest.httpMethod = method.rawValue

    let authToken = UserDefaults.standard.string(forKey: "authToken")
    let bearerToken: String = "Bearer " + (authToken ?? "")
    print("baearer token::\(bearerToken)")

    // Common Headers
    //urlRequest.setValue(ContentType.json.rawValue,forHTTPHeaderField: 
    //HTTPHeaderField.acceptType.rawValue)
    //urlRequest.setValue(ContentType.json.rawValue,forHTTPHeaderField: 
    //HTTPHeaderField.contentType.rawValue)
    //urlRequest.setValue(bearerToken,forHTTPHeaderField: 
    //HTTPHeaderField.authentication.rawValue)

    let headers: HTTPHeaders = [
        "Content-Type": "application/json","Authorization": "Basic " + currentToken
    ]

    Alamofire.request(url,error)
        }

//return urlRequest
}

希望这有帮助

本文链接:https://www.f2er.com/3097023.html

大家都在问