проблема в разборе json в разработке SWIFT для iOS - PullRequest
1 голос
/ 02 апреля 2019

У меня ошибка при разборе JSON Format с веб-службы ASMX,
Мой код

func getData() {
    let url = URL(string: "http://192.168.11.188/getItems.asmx/theItems")
    let theCategory = "ALL"
    let theSubCategory = "ALL"
    let postString = "theCategory=\(theCategory)&theSubCategory=\(theSubCategory)"
    var request = URLRequest(url: url!)
    request.httpMethod = "POST"
    request.cachePolicy = NSURLRequest.CachePolicy.reloadIgnoringCacheData
    request.httpBody = postString.data(using: String.Encoding.utf8)
    URLSession.shared.dataTask(with: request) { (data, respons, error) in
        if let error = error {
            print("Error conning to server \(error)")
        } else {
            if let respons = respons as? HTTPURLResponse {
                if respons.statusCode == 200 {
                    print(data!)
                    if let data = data {
                        do {
                            let json = try JSONDecoder().decode([ITEMS].self, from: data)
                            print(json)
                        } catch let parsingError {
                            print("Error parsing json \(parsingError)")
                        }
                    }
                } else {
                    print("Error in responce code.... \(respons.statusCode)")
                }
            }
        }
    }.resume()
}

Я использую структуру декодера в этом коде:

struct ITEMS: Codable {
    let CODE:String
    let CAT_ID:String
    let SUB_ID:String
    let PRODUCT_AR:String
    let PRODUCT_EN:String
    let OLD_PRICE:String
    let NEW_PRICE:String
    let UNIT:String
    let BARCODE:String
    let THE_DATE:String
    let TIME:String
}

Значение JSON

{ ITEMS : [{"CODE":111,"CAT_ID":203,"SUB_ID":null,"PRODUCT_AR":"ITEM 1","PRODUCT_EN":"ITEM 1","OLD_PRICE":133.0035,"NEW_PRICE":109,"UNIT":null,"BARCODE":"328031002009","THE_DATE":"\/Date(1553673958397)\/","TIME":"11:05 AM"},
           {"CODE":222,"CAT_ID":201,"SUB_ID":null,"PRODUCT_AR":"ITEM 2","PRODUCT_EN":"ITEM 2","OLD_PRICE":18.95,"NEW_PRICE":9.95,"UNIT":null,"BARCODE":"628103400012","THE_DATE":"\/Date(1553673958260)\/","TIME":"11:05 AM"}]}

но этот код возвращает ошибку

Ошибка синтаксического анализа ошибки JSON Domain = NSCocoaErrorDomain Code = 3840 "Текст JSON не начинался с массива или объекта, и параметр, позволяющий не устанавливать фрагменты." UserInfo = {NSDebugDescription = Текст JSON не начинался с массива или объекта и опции, позволяющей не задавать фрагменты.}

Что я делаю не так?

Ответы [ 2 ]

0 голосов
/ 02 апреля 2019

В вашей структуре использовались неправильные типы, вот фиксированная структура

struct ITEM: Codable {
    let CODE:Int           // not String
    let CAT_ID:Int         // not String
    let SUB_ID:Int?        // its null in JSON, use either Int? or String?
    let PRODUCT_AR: String
    let PRODUCT_EN: String
    let OLD_PRICE:Double   // not String
    let NEW_PRICE:Double   // not String
    let UNIT:String?
    let BARCODE:String
    let THE_DATE:String
    let TIME:String
}

Поскольку у вас в JSON есть корневой элемент ITEMS, вам необходимо выполнить декодирование с использованием этой структуры

struct BaseItems: Codable {
    let ITEMS: [ITEM] // Actual array of items are within this JSON element
}

Использование:

do {
    let decoded = try JSONDecoder().decode(BaseItems.self, from: data)
    print(decoded.ITEMS)
} catch {
    print(error)
}
0 голосов
/ 02 апреля 2019

когда вы пишете это,

let json = try JSONDecoder().decode([ITEMS].self, from: data)

он должен запросить синтаксический анализ массива ITEMS, но ваш JSON - это просто объект, а не массив (он запускаетсяс {ITEMS: [array_here]}).

Для решения этой проблемы вам нужно сделать структуру, подобную приведенной ниже, и выполнить синтаксический анализ данных в этом объекте.

struct ITEMS: Codable {
    let CODE:String
    let CAT_ID:String
    let SUB_ID:String
    let PRODUCT_AR:String
    let PRODUCT_EN:String
    let OLD_PRICE:String
    let NEW_PRICE:String
    let UNIT:String
    let BARCODE:String
    let THE_DATE:String
    let TIME:String
}

struct MyAPIData: Codable {
    let ITEMS: [ITEMS]
}

Теперь выполните синтаксический анализ данных с использованием приведенной ниже строки кода,

let json = try JSONDecoder().decode(MyAPIData.self, from: data)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...