URLSession 成功,但 returns 空 JSON 数据编辑 JSON 解析问题

URLSession successful, but returns empty JSON data EDIT JSON parsing issue

我正在为 iOS 开发一个应用程序,我正在使用 Swift 4 来开发它。该应用程序将使用 REST 调用来填充选择器和表格。下面的代码已用于成功处理呼叫,但是现在,我没有收到任何数据。 REST 已经通过邮递员进行了测试,这给了我预期的结果。

typealias JSONCompletionHandler = (Data?, Int?, Error?) -> void

static function getData(completionHandler: @escaping JSONCompletionHandler){
    let url = URL(string: "http://apiurl.com")
    let task = URLSession.shared.dataTask(with: url!) { data, response, error in
        let htttResponse = response as? HTTPURLResponse

        completeionHandler(data, httResponse?,statuscode, error)
    }
    task.resume()
}

编辑

下面是 HTTPURLResponse

的打印输出
Headers {
"Cache-Control" =     (
    "no-store, no-cache, must-revalidate, post-check=0, pre-check=0"
);
Connection =     (
    "Keep-Alive"
);
"Content-Type" =     (
    "application/json; charset=utf-8"
);
Date =     (
    "Tue, 01 May 2018 15:44:27 GMT"
);
Expires =     (
    "Thu, 19 Nov 1981 08:52:00 GMT"
);
"Keep-Alive" =     (
    "timeout=5, max=100"
);
Pragma =     (
    "no-cache"
);
Server =     (
    "Apache/2.2.29 (Win32) mod_ssl/2.2.29 OpenSSL/0.9.8zf"
);
"Set-Cookie" =     (
    "ZDEDebuggerPresent=php,phtml,php3; path=/"
);
"Transfer-Encoding" =     (
    Identity
);
"X-Powered-By" =     (
    "ZendServer 8.0.2"
);
} }

apache 连接日志

申请

邮递员

10.2.13.221 - - [02/May/2018:09:52:55 +0100] "GET /public/rest/catalogue-accessory/ HTTP/1.1" 200 216

编辑

正在返回数据,问题出在用于解析 JSON 数据的方法上。

我正在使用 swift 4 中可用的 Codable 方法,下面使用的结构以及 JSON 数据输出的方式(来自邮递员)

//Structures for JSON
struct PartType: Codable {
    let id: String
    let name: String
}

struct Availability: Codable {
    let id: String
    let status: String
}

struct AccessorySearch: Codable {
    let part_type = [PartType]()
    let availability = [Availability]()

}

JSON 来自 POSTMAN 的数据

{
"part_type": [
    {
        "id": "1",
        "name": "Type 1"
    },
    {
        "id": "2",
        "name": "Type 2"
    },
    {
        "id": "3",
        "name": "Type 3"
    }
],
"availability": [
    {
        "id": "1",
        "status": "In Stock"
    },
    {
        "id": "2",
        "status": "In Development"
    },
    {
        "id": "3",
        "status": "Not in Stock"
    }
]
}

使用的方法

    private func jsonDecodeString(data: Data?) {


    // array of the above structures 
    paryTypeArrayStructure.insert(PartType(id: "0", name: "Select Option"), at: 0)
    availabilityArrayStructure.insert(Availability(id: "0", status: "Select Option"), at: 0)

    let decoder = JSONDecoder()
    do {

        let decodeAccessories = try decoder.decode(AccessorySearch.self, from: data!)
        print("PART TYPE: ",decodeAccessories.part_type)
        print("AVAILABILITY: ",decodeAccessories.availability)

        let json = try JSONSerialization.jsonObject(with: data!, options: []) as! [String: AnyObject]

        print(json)

        for item in decodeAccessories.availability {
            print(item)
            availabilityArrayStructure.append(item)
        }

        for item in decodeAccessories.part_type {
            paryTypeArrayStructure.append(item)
        }

        //print(availabilityArrayStructure)
    } catch let jsonErr {
        print ("Failed to decode: ", jsonErr)
        displayErrorMessage(message: "[RCCA003 JSONException occurred when reading the response from server]")
    }

}

我尝试了 JSONSerilization 并且能够解析数据。所以现在我的问题是,为什么我最初的解析尝试失败了?对于任何混淆,我深表歉意,你们都非常有帮助,所以谢谢你们。

编辑 - 找到了解决方案...但为什么有效?

首先,我要感谢所有评论和提供研究领域的人。结果是 JSON 解析以及我如何设置结构的问题。

//Structures for JSON
struct PartType: Codable {
    let id: String?
    let name: String?
}

struct Availability: Codable {
    let id: String?
    let status: String?
}

struct AccessorySearch: Codable {

    let part_type:  [PartType]
    let availability: [Availability]
}

将解析 part_type 数组和可用性数组的结构将其变量设置为可选。这允许 JSON 被解析。任何人都可以阐明这一点吗?为什么这个简单的改变会奏效?再次感谢。

我使用以下游乐场来说明您的(小)故障:

import Cocoa

let jsonData = """
{
"part_type": [
    {
        "id": "1",
        "name": "Type 1"
    },
    {
        "id": "2",
        "name": "Type 2"
    },
    {
        "id": "3",
        "name": "Type 3"
    }
],
"availability": [
    {
        "id": "1",
        "status": "In Stock"
    },
    {
        "id": "2",
        "status": "In Development"
    },
    {
        "id": "3",
        "status": "Not in Stock"
    }
]
}
""".data(using: .utf8)!

struct PartType: Codable {
    let id: String
    let name: String
}

struct Availability: Codable {
    let id: String
    let status: String
}

struct AccessorySearch0: Codable {
    let part_type = [PartType]()
    let availability = [Availability]()
}

struct AccessorySearch: Codable {
    let part_type: [PartType]
    let availability: [Availability]
}

do {
    let accessory = try JSONDecoder().decode(AccessorySearch.self, from: jsonData)
    print(accessory)
} catch {
    print(error)
}

我使用了第二个版本的 AccessorySearch 以及第一个版本的 PartTypeAvailability。这解析完美,所以我认为一切都很好。

然而,您的第一个版本 AccessorySearch(为了便于比较,我将其设为 AccessorySearch0)是另一种动物。它不仅定义一个class,它还初始化它。因为它使用 let 来定义它的属性,所以这个第一个赋值不能再改变,你将从 JSONDecoder 得到的将是一个空数组的对象。

正如我所说,这只是一个小故障。

请您隔离问题。首先尝试解析响应.. 使用调试器数据可能会指示零字节,请勿以此作为参考。只需解析 try 块中的响应

do {
  //full dictionary response
  let json = 
  try JSONSerialization.jsonObject(with: data!, options: .mutableLeaves) as?Dictionary<String, AnyObject>
  //doe son parse correctly ?
catch {
  print(error.localizedDescription)
}

如果您使用 expectedContentLength 变量检查 URLResponse 的实例,您应该会看到响应的内容。