D3-用 Swift 和公开资讯,打造投资理财的 Apps { 使用 Alamofire 套件进行 URLRequest }

现在的 App ,已经很少单纯只用到手机功能而没有网路功能的。 Alamofire 是 iOS 开发中很知名的套件,有超过 200 个开发者贡献过这个套件,星星数超过 60k。

这次铁人赛在网路沟通上,会使用这个套件协助开发。安装过程在 repo 的 Readme 有详细的说明,使用方法也在 Readme 上。

https://github.com/Alamofire/Alamofire

MVC 架构

开发架构上,我选择使用 Apple 官方文件推荐的 MVC 架构,细节可以看 Stanford CS193P 过去的课程。

Stanford CS193P - MVC
https://ithelp.ithome.com.tw/upload/images/20210913/20140622Zqlkm5fSSN.jpg

https://www.youtube.com/watch?v=gI3pz7eFgfo

如果 MVC 运作的合理,那你的物件传递值的时候,看起来像这样
https://ithelp.ithome.com.tw/upload/images/20210913/20140622wc4YdeP5Mn.jpg

https://www.youtube.com/watch?v=gI3pz7eFgfo

如果 MVC 运作的不合理,App 还是可以运作,但他看起来会像这样
https://ithelp.ithome.com.tw/upload/images/20210913/201406227jDHNdD7ZS.jpg

网路沟通这一块,我视为 Model,而呼叫方法,我习惯写个 Adapter 将第三方元件包住,不让其他物件直接呼叫第三方元件。

程序码 Adapter

//
//  AlamofireAdapter.swift
//  ITIronMan
//
//  Created by Marvin on 2021/9/3.
//

import Foundation
import Alamofire

class AlamofireAdapter {
    
    private lazy var session: Session = {
        return Session()
    }()
    
    func requestForString(_ urlConvertible: URLConvertible, method: HTTPMethod, parameters: Parameters? = nil, headers: HTTPHeaders? = nil, completion: @escaping ((Result<String, Error>) -> Void)) {
        
        session.request(urlConvertible, method: method, parameters: parameters, headers: headers)
            .responseString { response in
                
                let result = response.result
                
                switch result {
                case .success(let string):
                    completion(.success(string))
                case .failure(let error):
                    completion(.failure(error))
                }
            }
    }
    
    func request(_ urlConvertible: URLConvertible, method: HTTPMethod, parameters: Parameters? = nil, headers: HTTPHeaders? = nil, completion: @escaping ((Data?, HTTPURLResponse?, Error?) -> Void)) {
        
        session.request(urlConvertible, method: method, parameters: parameters, headers: headers)
            .validate(statusCode: 200..<300)
            .response { afResponse in
                
                completion(afResponse.data, afResponse.response, afResponse.error)
            }
    }
}

这边有一个 func 开出 requestForString() 的原因,在公开资讯上,很多档案的格式都是 CSV 档,而这些档案在回到 App 的时候,是一连串 string,後续会用处理 CSV 档案的第三方套件,进行处理。

接下来,在 ViewController 的 viewDidLoad() 中进行呼叫,并试着打网路上的免费的 API

"https://jsonplaceholder.cypress.io/todos/1"

VC 的程序码如下

//
//  LandingViewController.swift
//  ITIronMan
//
//  Created by Marvin on 2021/9/3.
//

import UIKit

class LandingViewController: UIViewController {
    
    private lazy var alamofireAdapter: AlamofireAdapter = {
        return AlamofireAdapter()
    }()

    override func viewDidLoad() {
        super.viewDidLoad()
        requestPlaceholderAPI()
    }
    
    private func requestPlaceholderAPI() {
        
        let urlString = "https://jsonplaceholder.cypress.io/todos/1"
        
        alamofireAdapter.request(urlString, method: .get) { data, response, error in
            
            if let error = error {
                print("you got error: \(error.localizedDescription)")
                return
            }
            
            if let data = data {
                print("you got data: \(String(data: data, encoding: .utf8))")
            }
        }
    }
}

在 run 完模拟器後并进入画面後,你应该可以看到下方印出 Todo 的资讯。

you got data: Optional("{\n "userId": 1,\n "id": 1,\n "title": "delectus aut autem",\n "completed": false\n}")

如果看到 console 印出这样的资讯,就表示发动 request 成功,也成功的拿到回应。


<<:  电子书阅读器上的浏览器 [Day13] 自订工具列

>>:  Ruby on Rails Route 起步走

大共享时代系列_014_线上白板

事情讲不清楚吗? 那我觉得你需要来块白板~(๑•̀ω•́)ノ 给我一块白板,让我们一起得到更多 爲什...

Consistency and Consensus (3-1) - Ordering Guarantees

顺序这件事在 Design Data Intensive Applications 这本书中重复到提...

Proxy 代理模式

今天要谈到代理模式,其实跟昨天的装饰器模式很类似。代理模式的目的在於,因应某些条件替换物件原本的行为...

Day 10- 物品借用纪录系统 (2) 设定 Calendar

昨天我们完成了基础建设,但是有个地方忘记讲到,我现在赶快补充一下! 我们昨天设定归还日期时,一定有人...

EP17 - [TDD] 建立 Request 参数

Youtube 频道:https://www.youtube.com/c/kaochenlong ...