+ 2020.05.18
2020/05/18 - [iyOmSd/Title: Swift] - [Swift] - Alamofire 5.1 변경된 통신 및 Json Dynamic Key
안녕하세요😄😄
앱을 만드는데 있어서 중요한 통신을 해볼거에요
통신하는 방법에는 여러가지가 있는데 저는 Alamofire이라는 라이브러리를 이용해서 할 거에요
Alamofire는 많은 사람들이 사용하고있는 대표적인 통신 라이브러리 입니다.!!
JSON을 받고 파싱( JSON을 사용하기위해 변수로 바꾸는 작업 )을 하는 방법은 아래와 같아요
URLSession을 이용한 통신 방법
구조체를 이용해서 JSON을 파싱하는방법
라이브러리를 사용해서 간단하게 JSON을 파싱하는방법
.
.
.
라이브러리는 편하라고 만든거니까
당연히 훨씬 쉬워요
처음에는 어렵더라도 노가다로 시작해볼게요
URLSession을 이용한 통신
func requestSignIn(){
//회원가입 post
let url = URL(string: "http://1111.1111.1111.1111/api/a/c")!
var request = URLRequest(url: url)
request.httpMethod = "POST"
//post body부분
let parameters = "phone=\(phoneTextField.text ?? " ")&password=\(pwTextField.text ?? " ")"
request.httpBody = parameters.data(using: .utf8)
let task = URLSession.shared.dataTask(with: request) { (data, response, error) in
if let e = error {
print("\(e.localizedDescription)")
return
}
//응답처리
DispatchQueue.main.async {
do {
let object = try JSONSerialization.jsonObject(with: data!, options: []) as? NSDictionary
guard let jsonObject = object else {return}
print("success")
print(jsonObject)
self.checkCode = jsonObject.value(forKey: "result") as! Int //결과코드
if self.checkCode == 2000 {
let dataObject = jsonObject["data"] as! NSArray
let data = dataObject[0] as! NSDictionary
LoginUserInfo.shared.name = data["name"] as? String
LoginUserInfo.shared.id = data["id"] as? Int
LoginUserInfo.shared.phone = data["phone"] as? String
LoginUserInfo.shared.type = data["type"] as? Int
LoginUserInfo.shared.email = data["email"] as? String
self.nextView() //회원정보일치확인
}else{
self.fail()
}
}catch let e {
print("\(e.localizedDescription)")
}
}
}
task.resume()
}
이부분에서 data로 위의 그림과같은 JSON이 들어와요
지금 보는 JSON형식은 [result : Int], [data : [User]] 이런식의 타입이에요 ( User은 id,type,del_yn....등의 1세트라고 가정)
이용할 수 있도록 NSDictionary의 형태로 변경해줄거에요!
처음에key 값으로 result를 통해서 2000일때 성공이라는 코드가 온것을 확인할 수 있어요
key값으로 data를 넣으면 JSON배열이 나올거에요
여기서는 JSON값이 하나만 충족해서 하나의 배열요소만 나왓지만 다른 경우라면 id:3, id:2, id:1... 이런 여러 값이 나올수있죠
그래서 NSArray의 형태로 변경할거에요
그중 위의 사진에는 1개만 나타나있으므로
인덱스 0에 원하는 정보(회원정보)가 들어있겟죠?
각 회원정보는 [id : Int]이런 딕셔너리형식이므로 다시
NSDictionary의 형태로 변경해주고
key값으로 원하는 값을 파싱받을 수 있어요!!
참어렵고 복잡하죠...?
구조체를 이용해서 JSON을 디코딩하는 방법은 Alamofire을 이용해서 해봅시다!!
사용법은 비슷해요
구조체를 이용해서 JSON을 파싱
이제 좀더 쉽게 통신해봐요!!
Alamofire를 사용하기위해선 CocoaPods라는 프로그램을 깔아줘야해요
이 CocoaPods을 통해서 라이브러리를 쉽게 다운 받을 수 있어요
터미널에
sudo gem install cocoapods
를 입력해줘요!!
깔리고나면 해당되는 프로젝트 경로로 가서
pod init
을 해줍니다~!
그러면
podfile
이라는 파일이 생기는데 거기에 라이브러리를 추가할거에요
https://github.com/Alamofire/Alamofire
글작성 기준 시점으로
pod 'Alamofire', '~> 4.8.2'
를 써주면 되요!!
그뒤에
pod install을 하면 라이브러리가 깔리고, 새로운
파란색이아닌 흰색바탕의 엑스코드를 볼수 잇어요
이제부터는 꼭 이거를 클릭해서 들어가서 작업해야합니다!!!
struct LoginService {
let LoginUrl = "http://1111.1111.1111.1111/api/a/b"
static let shared = SocialLoginService()
let header: HTTPHeaders = [
"Content-Type" : "application/json"
]
func getLoginResult(type: Int, id: String, name: String, email: String, completion: @escaping (_ data: [LoginInfo]) -> Void) {
let body: Parameters = [
"type": type,
"id": id,
"name": name,
"email": email
]
Alamofire.request(SocialLoginUrl, method: .post, parameters: body, encoding: JSONEncoding.default, headers: header).responseJSON {
response in
switch response.result{
case .success:
guard let result = response.data else {return}
do {
let decoder = JSONDecoder()
let json = try decoder.decode(LoginResult.self, from: result)
if json.result == 2000{
completion(json.data)
}
} catch {
print("error!\(error)")
}
default:
return
}
}
}
}
struct LoginResult: Codable {
let result: Int
let data: [LoginInfo]
}
struct LoginInfo: Codable {
let id: Int
let type: Int
let del_yn: Int?
let name: String
let phone: String
let phone_verified_at: String?
let email: String?
let insurance: String?
let guardian: String?
let created_at: String?
let updated_at: String?
}
필요한 정보를 전달해줘서 함수를 호출하면 통신할 수도있도록
만든 코드에요
POST형식인 경우!!
body에 Parameters형으로 서버에서 필요한 정보들을 넣어서 보내줄거에요
response의 result에는 라이브러리의 성공코드가 전달되요
정상적으로 됬는지 안됬는지 enum형으로 되어있어요
response data엔 이제 원하는 데이터의 JSON이 들어있어요
JSONDecoder를 사용해서 데이터를 사용할 수 있도록
파싱해주는 작업을 할거에요!!
파싱받을 JSON의 형태에 맞게 Codable구조체를 만들어주고
변수명도 똑같이 맞춰줘야되요
변수명을 바꾸고 싶을땐
//키값 바꾸고싶은것만 값할당해주기
enum CodingKeys: String, CodingKey {
case id, type
case delYn = "del_yn" //del_yn 키값이 delYn 으로변경
}
이런식으로 순서대로 해줘야해요!
함수 끝부분에 보면 completion이라는게 보여요
escaping closure 문법인데 한번 공부하고오면좋아요!!
간단하게 설명하면 completion함수가 호출되면 함수를 탈출하게되고
데이터를 전달하는 기능을 한다면 전달 할수있죠
completion(json.data)
에서 json.data는 [LoginInfo]형의 데이터에요
escaping의 data의 데이터형을 맞게 설정해줘야해요
이렇게 설정하고나면!!!
getLoginResult에 원하는 정보를 넣고
통신을 시작하고
결과가 나오면 completion (escaping closure)이 실행되서
데이터를 넘겨 줄 수 있어요!!
그렇게 받아온 데이터는 아래처럼 사용할 수 있어요
LoginService.shared.getLoginResult(type: 3, id: token, name: name, email: email){
data in
LoginUserInfo.shared.name = data[0].name
LoginUserInfo.shared.id = data[0].id
LoginUserInfo.shared.phone = data[0].phone
LoginUserInfo.shared.type = data[0].type
LoginUserInfo.shared.email = data[0].email
.
.
.
.
}
저희는 방금 getLoginResult의 completion에 [LoginInfo]형의 데이터를 전달했어요
그 [LoginInfo]형 데이터를 함수를 호출한 부분에서 사용 할 수 있어요!!
데이터는 하나만 나올 것이기때문에 인덱스 0에있는 정보를 가져왔어요
구조체를 사용하면 애매하게 서버의 JSON으로 주는 값들이 하나라던까 적을 때
굳이 구조체를 하나하나 다 만들어서 해야하나...?
라는 불편함이 생길 수 있어요!!
그래서 위처럼 JSON디코더를 사용하지않고 한다던가...
는 좀 복잡하잖아요?!
그래서 이제 SwiftyJSON 이라는 라이브러리를
사용해서 파싱해볼 겁니다!!
[다음글 SwiftyJSON을 이용한 파싱]
'iyOmSd > Title: Swift' 카테고리의 다른 글
[Swift] ScrollView 오토레이아웃 잡기 (2) | 2019.11.17 |
---|---|
[Swift] Alamofire를 사용하여 API JSON 데이터 받기 (2/2) (2) | 2019.10.27 |
[Swift] 코드로만 AutoLayout 적용하기(Programmatically AutoLayout) (1) | 2019.10.23 |
[Swift] Push, Present 화면 전환하기 (0) | 2019.10.01 |
[Swift] 날짜형식 변환하기, 시간차 구하기 (0) | 2019.09.17 |