Опубликовать массив объектов с помощью Alamofire и SwiftyJSON

У меня есть массив словарей, которые я пытаюсь опубликовать в Alamofire с помощью SwiftyJSON.

API должен принимать:

[
    {
        "imageUrl": "someimage3.jpg"
    },
    {
        "imageUrl": "someimage4.jpg"
    }
]

Мой массив с объектами изображения при распечатке выглядит так с ключом imageUrl и именем изображения для значения.

uploadedFiles = [
    [imageUrl: "someimage.jpg"],
    [imageUrl: "someimage2.jpg"]
]

Пытаюсь преобразовать массив словарей в нужный для тела формат. Я не совсем уверен, как сделать их [String: AnyObject]

var body: [String: AnyObject] = [:]
let paramsJSON = JSON(uploadedFiles)
body = paramsJSON

пост Alamofire

Alamofire.request("\(BASE_URL)mainimages/\(someid)", method: .post, parameters: body, encoding: JSONEncoding.default, headers: header).responseString { (response) in
        if response.result.error == nil {
            let status = response.response?.statusCode
            completion(true, status)
        } else {
            completion(false, nil)
            debugPrint(response.result.error as Any)
        }
    }

person Keith    schedule 26.04.2018    source источник
comment
API принимает массив, поэтому дайте ему один.   -  person Sweeper    schedule 26.04.2018
comment
Имя ключа должно быть типа String в словаре uploadedFiles.   -  person iParesh    schedule 26.04.2018
comment
покажите свой код, в котором вы устанавливаете тело запроса Alamofire. (т.е. параметры)   -  person Mani    schedule 26.04.2018
comment
Только что обновили запрос на публикацию, спасибо.   -  person Keith    schedule 26.04.2018
comment
Пожалуйста, поясните: под объектами изображений вы на самом деле имеете в виду URL-адреса? Вы также хотите загрузить изображения? (если да, я бы порекомендовал составной запрос)   -  person CouchDeveloper    schedule 26.04.2018
comment
Нет, только URL-адреса. На этом этапе изображения уже загружены.   -  person Keith    schedule 26.04.2018


Ответы (4)


Вы можете добиться этого с помощью этого метода, он сработал для меня.

let payload = [["eventName": "Notifications","body":["version": "1.0","latitude": lat,"longitude":lon]]] as [[String : AnyObject]]

trackEventRequest(requestParams: payload, urlString: "https://xyz/youyURL")





func trackEventRequest(requestParams: [[String: AnyObject]], urlString: String) {

        let url = URL(string: urlString)
        var request = URLRequest(url: url!)
        request.setValue("application/json", forHTTPHeaderField: "Content-Type")
        request.httpMethod = "POST"
        request.httpBody = try! JSONSerialization.data(withJSONObject: requestParams, options: [])

        Alamofire.request(reqeust).responseJSON { (response) in
            switch response.result {
            case .success:
                print(response.result.value)
                break
            case .failure:
                print(response.error)
                break
            }
        }
    }
person Purnendu roy    schedule 15.09.2018

Вы можете сделать это, составив ручной запрос и позвонив Alamofire.request, как показано ниже.

var request = URLRequest(url: .......))
request.httpMethod = "POST"
request.setValue("application/json", forHTTPHeaderField: "Accept")

//parameter array

let uploadedFiles = [
   [imageUrl: "someimage.jpg"],
   [imageUrl: "someimage2.jpg"]
]

request.httpBody = try! JSONSerialization.data(withJSONObject: uploadedFiles)

Alamofire.request(request).responseJSON { response in

    switch (response.result) {
    case .success:

        //success code here

    case .failure(let error):

        //failure code here
    }
}

Если вы можете легко изменить формат на стороне Sever, проигнорируйте приведенное выше решение и измените его как словарь

[ "list_key" : [
       [imageUrl: "someimage.jpg"],
       [imageUrl: "someimage2.jpg"]
    ] 
 ]
person Mani    schedule 26.04.2018
comment
Мани, вы, вероятно, допустили опечатку: предложенный вами JSON по-прежнему является массивом, соответственно, недействительным JSON;) - person CouchDeveloper; 26.04.2018
comment
@CouchDeveloper Да. Я знаю. Но я не устанавливаю Alamofire's params, вместо этого я устанавливаю напрямую httpbody. чей сказал, массив словаря недействителен JSON? - person Mani; 26.04.2018
comment
Ну, ваш JSON не совсем верен - это просто не словарь, как вы сказали. Это JSON-массив объектов JSON (словарей). Если вы хотите опубликовать какой-либо объект как JSON, лучше всего использовать объект JSON (он же Словарь) в качестве корня. Если вы хотите опубликовать массив каких-либо объектов, вы можете отправить массив JSON объектов JSON (как объект такого типа) на сервер. Думаю, мы согласны :) - CouchDeveloper 5 минут назад редактировать - person CouchDeveloper; 26.04.2018
comment
@CouchDeveloper Вы можете использовать класс JSONSerialization фреймворка Foundation для преобразования JSON в типы данных Swift, например Dictionary, Array, String, Number, and Bool .. см. Здесь developer.apple.com/swift/blog/?id=37, поэтому объект не должен быть словарем для преобразования его в JSON, это может быть любой из упомянутых типов. - person Mani; 26.04.2018
comment
еще один момент. Я правильно it's best to use a JSON Object (aka Dictionary) as the root, но в то же время, если корневой объект не Dictionary, мы не можем сказать, что это не JSON. Это тоже JSON. - person Mani; 26.04.2018
comment
Я получаю эту ошибку *** Завершение работы приложения из-за неперехваченного исключения «NSInvalidArgumentException», причина: «Недопустимый тип в записи JSON (_SwiftValue)» - person Keith; 27.04.2018
comment
Я также попытался переформатировать свой api, как ваше второе предложение. Api в порядке, но при передаче в теле я получаю ту же ошибку недопустимого JSON. let body: [String: AnyObject] = [allImages: uploadedFiles as AnyObject] - person Keith; 27.04.2018

API, похоже, принимает JSON, который имеет массив в качестве верхнего уровня, а не словарь, поэтому преобразование вашего массива в словарь неверно.

Просто передайте массив!

JSON SwiftyJSON соответствует ExpressibleByArrayLiteral, поэтому вы можете просто использовать литерал массива:

let paramsJSON: JSON = [
    ["imageUrl": "someimage.jpg"],
    ["imageUrl": "someimage2.jpg"]
]

РЕДАКТИРОВАТЬ: Я только что понял, что метод request Alamofire принимает только [String: AnyObject]. Это означает, что вам нужно выполнить собственное кодирование параметров, продемонстрированное здесь.

Или создайте свой собственный URLRequest, как показано в этом сообщении:

var request = URLRequest(url: someURL)
request.httpMethod = "POST"
request.setValue("application/json", forHTTPHeaderField: "Content-Type")
request.httpBody = paramsJSON.rawData()
Alamofire.request(request)
person Sweeper    schedule 26.04.2018
comment
Извините, я, возможно, не понял, я не пытаюсь преобразовать его в словарь, это то, что у меня есть сейчас. Просто сделай что-нибудь, что я могу передать на аламофайр. Я попробовал ваш массив и получил ошибку Дополнительный аргумент 'метод' при вызове - person Keith; 26.04.2018
comment
Это решает проблему невозможности загрузить мой массив с помощью Alamofire. У меня все еще не получается преобразовать мой массив словарей в правильный формат JSON. let paramsJSON: JSON = JSON (uploadedFiles) дает мне неизвестно. Распечатанные файлы uploadedFiles выглядят следующим образом: [MyApp.NoteImage (imageUrl: someimage.png ”), MyApp.NoteImage (imageUrl: - person Keith; 27.04.2018

Я переформатировал свой API, как предложил Мани, чтобы упростить предоставление Alamofire того, что нужно. Теперь он ищет это:

{
    "allImages" : [
        {
            "imageUrl": "someimage5.jpg"
        },
        {
            "imageUrl": "someimage6.jpg"
        }
    ]
}

Мне также пришлось переформатировать свой массив, как в приведенном ниже коде, чтобы ошибки JSON исчезли.

var newUploadFilesArray = [AnyObject]()
    for item in uploadedFiles {
        let singleImageDict = ["imageUrl" : item.imageUrl]
        newUploadFilesArray.append(singleImageDict as AnyObject)
    }

    let body: [String: AnyObject] = [
        "allImages": newUploadFilesArray as AnyObject
    ]

    Alamofire.request("\(BASE_URL)mainimages/\(mainId)", method: .post, parameters: body, encoding: JSONEncoding.default, headers: header).responseString { (response) in
        if response.result.error == nil {
            let status = response.response?.statusCode
            completion(true, status)
        } else {
            completion(false, nil)
            debugPrint(response.result.error as Any)
        }
    }
person Keith    schedule 04.05.2018