Jiwift

[iOS/Swift] Alamofire Array에 담긴 JSON 데이터 보내기, Array 데이터를 서버로 전송 본문

라이브러리/Alamofire

[iOS/Swift] Alamofire Array에 담긴 JSON 데이터 보내기, Array 데이터를 서버로 전송

지위프트 2022. 12. 14. 12:10
반응형

 오늘은 Array로 이루어진 JSON을 보내려고 합니다. 어떻게 생긴 놈이냐 하면

[
	{
    	name: 김지태,
        age: 26,
        city: Seoul
    },
    {
    	name: 팀쿡,
        age: 58,
        city: Designed by Apple in California
    },
    {
    	name: 일론 머스크,
        age: 18,
        city: Mars
    }
]

위와 같이 생긴 데이터입니다. 내가 생각한 데이터 형식이랑 다르지만.. 서버에서 이렇게 전송하라고 했으니 해야지요.. 저는 키와 밸류로 이루어진 데이터만 다루다 보니.. 가끔 새로운 양식이 나오면 당황스럽더라고요 ㅋㅋ

 

struct Person {
	let name: String
    let age: Int
    let city: String
}

만약에 저 데이터를 수신받는다고 생각하면 Person과 같이 구조체를 작성하고

 

AF.request(url, method: .get, parameters: parameters, encoding: URLEncoding.queryString, headers: ["Content-Type":"application/json", "Accept":"application/json"])
                    .validate(statusCode: 200..<300)
                    .validate(contentType: ["application/json"])
                    .responseDecodable(of: [Person].self) { (response) in
                    switch response.result {
                    case let .success(response):
                        // 성공
                    case let .failure(error):
                        // 실패
                    }
                }

.responseDecodable(of: [Person].self)를 사용해서 Array형식으로 JSON을 편리하게 파싱 할 수 있습니다. 그래서 보내는 방법도 같은 수준으로 편할 줄 알고 parametersArray로 감싸 보았습니다. -> [parameters]

 

하지만 우리 parameter는 딕셔너리 형태로 [String : Any]로 키와 밸류 형식으로 넣어 주어야 합니다. 근데 지금 보내야 하는 데이터는 

Array인데 어떻게 넣어야 하는 거지? 싶어서 계속 찾아보았습니다.

 

제가 생각한 방법은 

1. Person 구조체를 생성한다.

2. Person Array를 만들어 1번에서 생성한 구조체를 넣어준다.

3. Person Array를 서버로 보낸다.

이거였습니다. 구조체로 데이터를 담고 이동하면 많이 편리해서 좋고, codable을 사용하다 보니 당연하게 될 줄 알았습니다.

 

하지만

 

Swift - Send an array as POST request parameter to PHP - Stack Overflow

 

Swift - Send an array as POST request parameter to PHP

I'm working on an app in Swift. I need to call PHP webservice from this app. Below code for webservice: // ViewController.swift // SwiftPHPMySQL // // Created by Belal Khan on 12/08/16. //

stackoverflow.com

swift - Post array of objects with Alamofire and SwiftyJSON - Stack Overflow

 

Post array of objects with Alamofire and SwiftyJSON

I have an array of dictionaries that I am trying to post to Alamofire with the help of SwiftyJSON. The api is set to take: [ { "imageUrl": "someimage3.jpg" }, { "imag...

stackoverflow.com

  몇 가지를 찾아본 결과 Array로 보내는 방법들 중에는 구조체로 보내는 게 없었습니다... (내가 못 찾은 거일 수도.. 알려주세요 ㅜ.ㅜ)

 

우선 우리가 보내고 싶은 데이터를 Dictionary로 만들어야 합니다. 그래서

// JSON
{
    name: 김지태,
    age: 26,
    city: Seoul
}

// Swift에서 보내는 딕셔너리
let parameters = [
					"name" : "2022",
                    "age": 26,
                    "city": "Seoul"
                  ]

 json 양식을 dictionaty 형태로 생성했습니다. 여기까지는 평범한 방법이니 다들 아시라 믿고, 이제는 json을 딕셔너리에 담을 겁니다.

 

var personArray: [[String : Any]] = []

for person in personInput {
	// Swift에서 보내는 딕셔너리
    let parameters = [
                        "name" : "이름",
                        "age": 26,
                        "city": "Seoul"
                      ]
    personArray.append(parameters)
}

보시다시피 딕셔너리를 Array에 담았습니다. 이제 이 데이터를 보낼 일만 남았는데요.

 

// URL String 
var request = URLRequest(url: try! url.asURL())
request.httpMethod = "PUT"

// 우리가 보내고 싶은 데이터를 JSONSerialization을 사용해서 body에 넣기
request.httpBody = try! JSONSerialization.data(withJSONObject: parameters)

// 헤더 추가
request.addValue("application/json", forHTTPHeaderField: "Accept")
request.addValue("application/json", forHTTPHeaderField: "Content-Type")

// 생성한 request를 Alamofire로 전송
AF.request(request)
            .validate(statusCode: 200..<300)
            .validate(contentType: ["application/json"])
            .response { (response) in
            switch response.result {
            case .success(_):
                print("성공이냐?")
            case .failure(let error):
            	print("실패냐?")
            }
        }

위에 제가 사용한 방법과는 다르게 URLRequest를 사용해서 request객체를 생성했습니다. 그리고 그 안에 필요한 옵션들을 설정하고 httpBody에 우리 데이터를 넣어줍니다. 데이터 변환에서 JSONSerialization를 사용했는데

 

Foundation 에서는 JSON 데이터를 그에 맞는 object로 변환하고, 다시 JSON으로 바꾸는 유틸리티 class 를 제공한다.
JSON을 Foundation objects로 변환하거나 그 반대를 하게 해주는 객체입니다. Foundation object를 JSON으로 바꾸기 위해서는 다음의 네 가지 조건을 지켜야 합니다.

1. top level object는 NSArray나 NSDictionary여야 합니다. 그렇지 않다면 fragmentsAllowed 옵션을 추가해줘야 합니다.

2. 모든 obejcts는 NSString, NSNumber, NSArray, NSDictionary or NSNull 중 하나입니다.

3. 모든 딕셔너리 key는 NSString입니다.

4. Numbers는 NaN이거나 무한대이면 안됩니다.

라고 합니다. 직접 파싱 해서 데이터 처리하는 건 Swift 배우고 초반에만 해서 그런지 낯설었습니다... 지금은 Codable이 최고야..

 

아무튼 위 방식을 사용하면 Array를 데이터로 전송이 가능해집니다. 분명 Codable을 사용한 간단한 방법이 있을 거라 생각하는데 아시는 분 있나요?? ㅜ.ㅜ

 

아니면 내가 오타가 나서 잠깐 에러가 발생했던 건가... 아무튼 해결은 했으니. 누군가에게도 도움이 되거나 더 좋은 방법을 아시는 분은 알려주시면 감사합니다.

 

 

 

 

JSON직렬화 | 애플 개발자 문서 (apple.com)

 

Apple Developer Documentation

 

developer.apple.com

JSONSerialization 공부하기 (tistory.com)

 

JSONSerialization 공부하기

JSON Parsing 하기 class JSONSerialization : NSObject JSON을 Foundation objects로 변환하거나 그 반대를 하게 해주는 객체입니다. Foundation object를 JSON으로 바꾸기 위해서는 다음의 네 가지 조건을 지켜야 합니다.

kangheeseon.tistory.com

 

반응형