[Swift] API MVP 호출해서 써봤어요.

17567 단어 SwiftMVPAlamofire

개요


작업 중에 MVP를 이용해서 개발하는 자리가 늘었어요.
자신의 연습으로 MVP를 사용해 API를 두드리고 있다.
Alamofire·Codable 등에 익숙하지 않아서요.
아래 참고 문헌의 보도를 보고 제가 직접 했습니다.
이렇게 쓰면 더 좋고, 지적해 주시면 감사하겠습니다.
Qiita에 처음 투고하는 거라 읽기 어려우면 죄송합니다.

컨디션

  • xcode10.0
  • swift4.2
  • 라이브러리
  • Alamofire 4.7.3
  • SVProgresssHUD(미관을 위한)
  • API
  • Qita 녀석
  • 실행 결과


    APIListViewController
    APIInformationViewController


    파일 설명 만들기

  • View
  • APIlistViewController...TableView에 정보 표시
  • 획득한 URL을 바탕으로 WKWebView에 정보를 표시
  • Presenter
  • API 정보 획득 프로세스를 호출하고 얻은 정보를 View
  • 에 알림
  • Model
  • APIOperater·실제 API 두드려 정보 얻기
  • APIInformationModel...정보를 얻기 위한 구조
  • View


    APIListViewController
    여기, Presenter에서 API를 호출하여 처리
    Presenter에 의해 공지된 정보만 표시됩니다.
    viewDidLoad()에서
    APIlistPresenter의 appiListView 속성에 self 설정
    API 정보를 가져오는 프로세스라고 합니다.
    APIListViewController.swift
    
    final class APIListViewController: UIViewController {
    
        private let apiListPresenter = APIListPresenter()
        private var articleList = [APIInformationModel]()
        private var url = ""
    
        @IBOutlet private weak var apiListTableview: UITableView!
    
        override func viewDidLoad() {
            super.viewDidLoad()
    
            apiListPresenter.apiListView = self
            apiListPresenter.requestAPIInformations()
    
            // インジケータの設定
            SVProgressHUD.show(withStatus: "取得中...")
            SVProgressHUD.setDefaultMaskType(.black)
        }
    }
    
    확장은 APIlistView를 상속합니다.
    presenter에서 날아와서 각자의 프로토콜 방법을 실행합니다.
    APIListViewController.swift
    extension APIListViewController: APIListView {
    
        /// Presenterから通知されてきた情報をTableviewで使用する配列に格納
        ///
        /// - Parameter article: api取得情報
        func responseAPIInformations(article: [APIInformationModel]) {
            // インジケータを止める
            SVProgressHUD.dismiss()
    
            articleList = article
            // tableviewをリロードし、情報をtableviewに表示する
            apiListTableview.reloadData()
        }
    
        /// 情報の取得に失敗したとき
        func errorResponseAPI() {
            // インジケータを止める
            SVProgressHUD.dismiss()
            print("エラー")
        }
    }
    
    Tableview 디스플레이 처리
    APIListViewController.swift
    extension APIListViewController: UITableViewDelegate, UITableViewDataSource {
    
        /// セルの数を指定
        ///
        /// - Parameters:
        ///   - tableView: TableView
        ///   - section: 対象セクション番号
        /// - Returns: セル数
        public func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
            return articleList.count
        }
    
        /// セルの内容を指定
        ///
        /// - Parameters:
        ///   - tableView: TableView
        ///   - indexPath: 対象セクション及びセル番号情報
        /// - Returns: セル
        public func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
            let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath)
            cell.textLabel?.text = articleList[indexPath.row].title
    
            return cell
        }
    
        /// セル選択時
        ///
        /// - Parameters:
        ///   - tableView: TableView
        ///   - indexPath: 対象セクション及びセル番号情報
        public func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
            url = articleList[indexPath.row].url
            self.performSegue(withIdentifier: "APIInformationViewControllerPush", sender: nil)
    
            tableView.deselectRow(at: indexPath, animated: true)
        }
    }
    
    
    APIInformationViewController
    APIlistViewController에서 마이그레이션할 때 가격은
    URL에 전달하고 이를 바탕으로 WKWebView에 표시합니다.
    코드는 별다른 변화가 없기 때문에 생략할 수 있습니다...

    Persenter


    APIListPresenter
    Model의 API 가져오기 프로세스를 호출하고 반환된 정보를 Viewcontroller에 알립니다.
    APIListPresenter.swift
    // 委譲する処理をプロトコルメソッドとして宣言する。
    protocol APIListView: NSObjectProtocol {
        func responseAPIInformations(article: [APIInformationModel])
        func errorResponseAPI()
    }
    
    APIListPresenter.swift
    final class APIListPresenter {
    
        weak var apiListView: APIListView?
    
        /// APIOperater.getAPIInformationsを呼び出し、情報を取得する
        func requestAPIInformations() {
    
            APIOperater.getAPIInformations(callback: { [weak self] (articles) in
                guard let strongSelf = self else { return }
    
                // 情報が取得できているか判定
                if let articleValue = articles {
                    // 取得成功の場合は、成功パターンのプロトコルメソッドの引数に取得した情報を渡し呼び出し
                    strongSelf.apiListView?.responseAPIInformations(article: articleValue)
                } else {
                    // 取得失敗の場合、失敗パターンのプロトコルメソッドを呼び出し
                    strongSelf.apiListView?.errorResponseAPI()
                }
            })
        }
    }
    

    Model


    APIOperater
    API 가져오기 처리를 수행합니다.
    여기에서 성공할 때 정보를 콜백의 매개 변수로 설정합니다.
    APIOperater.swift
    struct APIOperater {
    
        /// APIを呼び出し
        ///
        /// - Parameter callback: callbackメソッドの引数に、取得した情報を構造体で渡す
        static func getAPIInformations(callback: @escaping ([APIInformationModel]?) -> Void) {
    
            Alamofire.request("https://qiita.com/api/v2/items").validate().responseJSON { response in
                guard let data = response.data else {
                    return
                }
                do {
                    // JSONのマッピング
                    let articles = try JSONDecoder().decode([APIInformationModel].self, from: data)
                    callback(articles)
    
                } catch {
                    callback(nil)
                }
            }
        }
    }
    
    APIInformationModel
    JSON 맵에서 사용하기 위해 Codable이 상속되었습니다.
    많이 정의할 수 있지만 이번에는 사용하는 것만 정의했다.
    APIInformationModel.swift
    struct APIInformationModel: Codable {
        var title: String
        var user: User
        var url: String
        struct User: Codable {
            var id: String
        }
    }
    

    마지막으로...


    이번 실상은 정말 심플한 느낌이에요.
    MVP의 장점을 더 많이 보실 수 있을 것 같아요.
    나는 더 좋은 작법이 있다고 생각한다.
    그런 것들을 만나기 위해
    앞으로도 계속 공부해야 돼...
    또한 방법명, 파일명, 변수명도
    더 쉽게 이해할 수 있는 이름을 만들도록 노력하겠습니다!!

    참고 문헌


    Codable의 위치를 참조하게 해 주세요.
    http://www.cl9.info/entry/2017/10/06/134510
    https://hfoasi8fje3.hatenablog.com/entry/2018/07/05/185348

    좋은 웹페이지 즐겨찾기