꾸준히 안타치기

URL session 예제 / DispatchQueue 본문

iOS/Basic Study

URL session 예제 / DispatchQueue

글자줍기 2021. 12. 28. 16:57
반응형

서버링크 "https://randomuser.me/api/?results=20&inc=name,email,picture" 에 있는 정보를 가져와서 테이블뷰에 표현해보자 

위 내용을 가져와서 테이블뷰에 표시해보자

1. 코코아터치클래스를 만든다. 이름은 NetWorkViewController 생성

2. NetWorkViewController에 UITableViewDataSourse를 추가한다.

3. @IBOutlet weak var tableView: UITableView!  를 작성

4. let cellIdentifier: String = "friendCell"   - 셀이름 등록 

5. 테이블 내용 작성 

6. viewDidApper 작성

7. mainStroyboard로 가서 ViewController에 테이블을 생성 및 연결, 클래스연결, 셀생성 friendCell / IBOutlet DataSourse연결

8. Model에 가져올 데이터 작성 

 

NetWorkViewController

import UIKit

class NetWorkViewController: UIViewController, UITableViewDataSource {
    
    @IBOutlet weak var tableView: UITableView!
    let cellIdentifier: String = "friendCell"
    var friends: [Friend] = []
    
    
    
    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        
        let cell: UITableViewCell = tableView.dequeueReusableCell(withIdentifier: self.cellIdentifier, for:
                                                                    indexPath)
        let friend: Friend = self.friends[indexPath.row]
        
        cell.textLabel?.text = friend.name.full
        cell.detailTextLabel?.text = friend.email
        // 셀이 재사용되기전에 이미지를 빈값으로 세팅해준다.
        cell.imageView?.image = nil
        
        // 이미지를 비동기로 불러오기(메인에서 실행한다.  DispatchQueue.global() 백그라운드큐)
        DispatchQueue.global().async {
            // 이미지 받아오기 백그라운드에서 실행시키고
            guard let imageURL: URL = URL(string: friend.picture.thumbnail) else { return }
            guard let imageData: Data = try? Data(contentsOf: imageURL) else { return }
            
            // 이미지세팅은 메인으로 가져와서 동작시킨다.
            DispatchQueue.main.async {
                // 다운로드 받는동안 위치가 변경될수 있으므로, 현재 index와 다운로드가 다되었을때 index값이 같을때만 보여주는것으로 세팅한다.
                if let index: IndexPath = tableView.indexPath(for: cell){
                    if index.row == indexPath.row{
                        cell.imageView?.image = UIImage(data: imageData)
                        // 레이아웃결정해주기
                        cell.setNeedsLayout()
                        cell.layoutIfNeeded()
                    }
                }
            }
            
        }
        
        return cell
    }
    
    
    // 행의 갯수
    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return friends.count
    }
    
    
    override func viewDidAppear(_ animated: Bool) {
        super.viewDidAppear(animated)
        
        
        guard let url: URL = URL(string: "https://randomuser.me/api/?results=20&inc=name,email,picture") else
        {return}
        
        // 세션만들기
        let session: URLSession = URLSession(configuration: .default)
        // dataTask만들기                                              // 클로져요청에 대한 응답이 왔을때 실행됨 (백그라운드에서 실행)
        let dataTask: URLSessionDataTask = session.dataTask(with: url){ (data: Data?, response: URLResponse?, error:
                                                                            Error?) in
            if let error = error {
                print(error.localizedDescription)
                return
            }
            // 받아온데이터
            guard let data = data else {return}
            
            do{
                let apiResponse: APIResponse = try JSONDecoder().decode(APIResponse.self, from: data)
                self.friends = apiResponse.results
                
                // 백그라운드에서 동작하면 안되는 코드이다.  DispatchQueue를 사용해 메인쓰레드로 가져온다.
                DispatchQueue.main.async {
                    self.tableView.reloadData()
                }
                
            }catch(let err){
                print(err.localizedDescription)
            }
        }
        // 데이터 테스크 실행
        dataTask.resume()
    }
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        // Do any additional setup after loading the view.
    }
}

 

Model

위 내용을 가져와서 테이블뷰에 표시해보자

import Foundation

struct APIResponse: Codable {
    let results: [Friend]
}

struct Friend: Codable {
    struct Name: Codable{
        let title: String
        let first: String
        let last: String
        
        var full: String{
            return self.title.capitalized + ". " + self.first.capitalized + " " + self.last.capitalized
        }
    }
    
    struct Picture: Codable {
        let large: String
        let medium: String
        let thumbnail: String
    }
    
    let name: Name
    let email: String
    let picture: Picture
}

 

https://www.boostcourse.org/mo326/lecture/16918?isDesc=false 

 

iOS 앱 프로그래밍

부스트코스 무료 강의

www.boostcourse.org

 

반응형

'iOS > Basic Study' 카테고리의 다른 글

xcode 단축키  (0) 2022.01.30
Notification / 이벤트 전달! /노티피케이션 센터와 노티피케이션  (0) 2021.12.28
Grand Central Dispatch  (0) 2021.12.27
URLSession과 URLSessionDataTask  (0) 2021.12.27
OperationQueue  (0) 2021.12.26
Comments