본문 바로가기
Developer/iOS, Swift

[iOS] AlamoFire로 서버 통신하기 (feat. Retrofit 안드로이드)

by Doony 2019. 8. 19.

이번 포스팅에서는 가장 먼저 해보고 싶었던 서버 통신 라이브러리, AlamoFire에 대해 다루겠습니다. (아직 공부중인 관계로, 완벽한 정보는 아닌 점 감안하고 보시기 바랍니다.)

  • AlamoFire

안드로이드에 retrofit이 있다면, iOS에는 Alamofire가 있습니다. 즉, 두 라이브러리 모두 웹 주소를 가지는 서버와 통신할 때 매우 유용합니다. retrofit에 대한 설명은 여기에서 보실 수 있습니다.

먼저 Alamofire 에 대한 설명을 한 후에, retrofit과 비교해보겠습니다.

  • 목적: Alamofire을 통해 JSON형태의 데이터를 가져오고, view에 띄우기 (총 10개의 데이터)
  1. CocoaPod를 통해 AlamoFire을 설치합니다. 설치 방법은 간단합니다. cocoaPod를 init시켜주고, pod파일에 alamofire을 작성한 뒤 install해주면 됩니다. (추가로, SwiftyJSON 도 설치해줍니다. JSON데이터를 처리할 때 사용합니다.)

  2. CollectionViewController를 사용합니다. 뷰에 들어갈 서버데이터의 각 cell을 컨트롤하기 위해 Cocoa Touch Class파일을 생성한 뒤, cell과 연동시켜줍니다.

  3. 스토리보드에서 cell에 들어갈 오브젝트들을 삽입해주고, 아웃렛으로 선언합니다. 이 포스팅에서는 레이블 1개와, 이미지뷰 1개를 넣었습니다. 레이블에서는 서버 데이터의 텍스트를 불러와 띄울 것이고, 이미지뷰에서는 서버에 있는 이미지URL로 띄워보도록 하겠습니다.

  4. CollectionView의 스위프트 코드는 다음과 같습니다.

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
     
    import UIKit
    import Alamofire
    import SwiftyJSON
     
    private let reuseIdentifier = "Cell"
     
    class CollectionViewController: UICollectionViewController {
        var nameList = [String]() // 레이블에 들어갈 어레이입니다.
        var profileURL = [String]() // 이미지뷰에 들어갈 이미지URL 어레이입니다.
     
        
        override func viewDidLoad() {
            super.viewDidLoad()
            loadServer()
            // Uncomment the following line to preserve selection between presentations
            // self.clearsSelectionOnViewWillAppear = false
     
            // Register cell classes
            self.collectionView!.register(UICollectionViewCell.self, forCellWithReuseIdentifier: reuseIdentifier)
           
        }
        
        func loadServer() {
            let token = "Authentication Token" //서버용 접속 토큰이 있을 경우 지정합니다.
            let header: HTTPHeaders = [
                "Authorization": token
            ]
            Alamofire.request("Server URL", method: .get,  encoding: URLEncoding.default, headers: header) .validate(statusCode: 200..<300) .responseJSON { (response) -> Void in
                var swiftyJsonVar = JSON(response.result.value!)
                var eachCellObject = swiftyJsonVar["data"]
                // JSON 포맷의 서버 데이터를 eachCellObject라는 변수로 한번에 저장합니다.
     
                // 10개의 데이터를 불러오기 위해, 첫번째부터 앞서 선언한 어레이 데이터를 저장합니다.
                for i in 0 ... 9 {
                    let imageURL:String= eachCellObject[i]["imageURL"].string
                    self.profileURL.append(imageURL:String!)
                    self.nameList.append(eachCellObject[i]["name"].string!)
                }
     
                // 데이터를 다 저장했기 때문에, 뷰를 갱신합니다.
                self.collectionView?.reloadData()
                
                
            }
            
        }
     
        
     
        override func didReceiveMemoryWarning() {
            super.didReceiveMemoryWarning()
            // Dispose of any resources that can be recreated.
        }
     
        // MARK: UICollectionViewDataSource
     
        override func numberOfSections(in collectionView: UICollectionView) -> Int {
            // #warning Incomplete implementation, return the number of sections
            return 1
        }
     
     
        override func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int-> Int {
            // #warning Incomplete implementation, return the number of items
            return nameList.count
        }
     
        override func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
            let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "myCell"for: indexPath) as! CollectionViewCell
            cell.lblName.text = nameList[indexPath.row]
            
            // 서버 데이터에 null값이 있으므로, 걸러줍니다.
            var url = URL(string: profileURL[indexPath.row])
            if url == nil {
                url = URL(string: "디폴트 이미지 주소")
            }
            
            let data = try? Data(contentsOf: url!//make sure your image in this url does exist, otherwise unwrap in a if let check / try-catch
            cell.imgProfile.image = UIImage(data: data!)
            
            // Configure the cell
        
            return cell
        }
     
    }
     
    cs

안드로이드와 비교했을 때, 별도의 데이터 그릇 역할을 하는 클래스파일 없이 그대로 읽어들인다는 점이 흥미로웠습니다. 어쩌면 안드로이드에서도 그렇게 할 수 있었을지도 모르겠습니다만, retrofit을 사용할 때에는 JSON포맷에 맞는 클래스 파일을 계속 만들어 사용했었습니다. 그런 면에서, 실수 방지? 차원에서는 안드로이드가 좀 더 안전한 방향인 듯 하고, 코더의 입장에서는 iOS가 좀 더 깔끔하지 않았나 싶습니다. 물론 iOS에서도 안드로이드와 동일한 방식으로 작동할 수 있지 않나 싶습니다. 별도의 클래스 파일을 만들어서 관리할 수 있는 방식 말입니다.
어떻게보면 두 작동방식이 매우 유사한 것 같으면서도 약간씩 다른 점들이 있는 것 같은데, 이 부분은 앞으로 좀 더 공부해가면서 포스팅 이어나가도록 하겠습니다.

댓글