iyOmSd/Title: Swift

[Swift] Alamofire를 사용하여 API JSON 데이터 받기 (1/2)

냄수 2019. 10. 27. 01:31
반응형

+ 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을 이용한 파싱]

[Swift] Alamofire를 사용하여 API JSON 데이터 받기 (2/2)

반응형