URLSession успешен, но возвращает пустые данные JSON. ИЗМЕНИТЬ проблему синтаксического анализа JSON. - PullRequest
0 голосов
/ 01 мая 2018

Я работаю над приложением для 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()
}

EDIT

Ниже приведена распечатка 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

Применение

  • [02 / May / 2018: 09: 51: 04 +0100] "GET / общедоступный / отдых / стандартное соответствие каталога / HTTP / 1.1" 200 15669
  • [02 / May / 2018: 09: 51: 04 +0100] "GET / public / rest / catalog-multi-fit / HTTP / 1.1" 200 14302
  • [02 / May / 2018: 09: 51: 04 +0100] "GET / public / rest / каталог-аксессуар / HTTP / 1.1" 200 216

POSTMAN

10.2.13.221 - - [02 / May / 2018: 09: 52: 55 +0100] "GET / public / rest / каталог-аксессуар / HTTP / 1.1" 200 216

EDIT

Данные возвращаются, и проблема связана с методом, используемым для анализа данных JSON.

Я использую подход Codable, доступный в swift 4, и используемые структуры приведены ниже вместе с тем, как вывод данных 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. Может кто-нибудь пролить некоторый свет на это? Почему это простое изменение сработало? Еще раз спасибо.

Ответы [ 2 ]

0 голосов
/ 05 декабря 2018

Пожалуйста, вы должны изолировать вашу проблему. Сначала попробуйте разобрать ответ .. При использовании данных отладчика можно указывать ноль байтов, не берите это в качестве ссылки. Просто проанализируйте ответ внутри блока 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)
}

если вы проверяете экземпляр URLResponse с переменной pectedContentLength , вы должны увидеть содержимое ответа.

0 голосов
/ 05 мая 2018

Я использовал следующую игровую площадку для иллюстрации вашего (маленького) сбоя:

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 из вашей второй версии в сочетании с PartType и Availability из вашей первой версии. Это отлично разбирает, так что я думаю, что все хорошо.

Однако ваша первая версия AccessorySearch (которую я для простоты сравниваю как AccessorySearch0) - другое животное. Он не просто определяет класс, он также инициализирует его. Поскольку он использует let для определения своих свойств, это первое назначение больше не может быть изменено, и все, что вы получите от JSONDecoder, будет объект с пустыми массивами.

Как я уже сказал, это был просто небольшой сбой.

...