D10- 用 Swift 和公开资讯,打造投资理财的 Apps { 台股申购实作.3-让申购资讯放进可以清楚理解的 TableView }

接下来,进行台股申购 Model 实作,这个 Model 该负责的任务如下

  • 申购资料下载
  • 申购列表总共数量
  • 第 n 个列表是哪个申购资讯?

程序码如下

//
//  StockSubscriptionModel.swift
//  ITIronMan
//
//  Created by Marvin on 2021/9/4.
//

import Foundation

protocol StockSubscriptionModelDelegate: AnyObject {
    
    func didRecieveList(_ subscriptionList: [StockSubscriptionInfo], error: Error?)
}

/// 股票申购 VC 所需的 Model
class StockSubscriptionModel {
    
    weak var delegate: StockSubscriptionModelDelegate?
    
    var subscriptionList = [StockSubscriptionInfo]()
    
    private lazy var manager: StockSubscriptionManager = {
        return StockSubscriptionManager()
    }()
    
    var count: Int {
        return subscriptionList.count
    }
    
    func getSubscriptionInfo(at indexPath: IndexPath) -> StockSubscriptionInfo? {
        
        let index = indexPath.row
        
        if subscriptionList.indices.contains(index) {
            return subscriptionList[index]
        }
        
        return nil
    }
    
    func requestStockSubscription() {
        
        let year = 2021
        manager.requestStockSubscriptionInfo(year: year) { [weak self] subscriptionList, error in
            
            self?.subscriptionList = subscriptionList
            self?.delegate?.didRecieveList(subscriptionList, error: error)
        }
    }
}

要呈现的资料,先大概设计装载下列资讯

  • 申购状态
  • 股票名称
  • 股票代号
  • 申购价格
  • 中签率

简单拉一个 UITableViewCell

https://ithelp.ithome.com.tw/upload/images/20210919/20140622cbtI2JgmPl.png

然後 VC 负责把 View 和 Model 连结起来,程序码如下

//
//  StockSubscriptionViewController.swift
//  ITIronMan
//
//  Created by Marvin on 2021/9/4.
//

import UIKit

class StockSubscriptionViewController: UIViewController {
    
    @IBOutlet weak var tableView: UITableView!
    
    private lazy var model: StockSubscriptionModel = {
        let model = StockSubscriptionModel()
        model.delegate = self
        return model
    }()

    // MARK: - life cycle
    override func viewDidLoad() {
        super.viewDidLoad()
        setupUI()
    }
    
    // MARK: - private methods
    private func setupUI() {
        tableView.dataSource = self
        tableView.delegate = self
    }
    
    // MARK: - IBAction
    @IBAction func requestSubscriptionButtonDidTap(_ sender: Any) {
        model.requestStockSubscription()
    }
    
}

extension StockSubscriptionViewController: UITableViewDelegate, UITableViewDataSource {
    
    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return model.count
    }
    
    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        
        guard let cell = tableView.dequeueReusableCell(withIdentifier: StockSubscriptionTableViewCell.identifier, for: indexPath) as? StockSubscriptionTableViewCell,
              let info = model.getSubscriptionInfo(at: indexPath) else {
            return UITableViewCell()
        }
        
        let state = "申购状态"
        let firstSection = "\(info.stockName) - (\(info.stockCode))"
        let secondSection = "申购股数: \(info.stockCountString)"
        let thirdSection = "申购价: \(info.actualPrice)"
        let forthSection = "中签率: \(info.subscriptionRateString) %"
        
        cell.stateLabel.text = state
        cell.firstSectionLabel.text = firstSection
        cell.secondSectionLabel.text = secondSection
        cell.thirdSectionLabel.text = thirdSection
        cell.forthSectionLabel.text = forthSection
        
        return cell
    }
}

extension StockSubscriptionViewController: StockSubscriptionModelDelegate {
    
    func didRecieveList(_ subscriptionList: [StockSubscriptionInfo], error: Error?) {
        
        if let error = error {
            print("you got error during subscriptions request: \(error.localizedDescription)")
            return
        }
        
        tableView.reloadData()
    }
}

基本的 UI 大致如下

https://ithelp.ithome.com.tw/upload/images/20210919/201406229i9lBgNyjF.png

不过还差一点,因为这个申购资讯包含了一般人不会感兴趣的央债,市面上常用的下单软件,都会把央债去掉,而这一部分的职责,应该是 Model 要处理。当 Model 在接收到 StockSubscriptionManager 传过来的资料时,会 filter 掉央债,再通知 VC。

在 model 内加上一个 private func 做去除。股票代号的前几码是有意义的,举例来说 00 开头一定是 ETF,11 开头一定是水泥类股,12 开头一定是食品类股。

而央债的开头第一个字母是 A,我们可以用这个规则,把央债去掉。

private func filterNotAvailable(_ subscriptionList: [StockSubscriptionInfo]) -> [StockSubscriptionInfo] {
        
        let list = subscriptionList.filter { info in
            let code = info.stockCode
            let firstCharacter = code.first ?? "0"
            return firstCharacter != "A"
        }
        
        return list
    }

然後在收到申购列表後,进行清除,所以 func requestStockSubscription() 要改成这样。

func requestStockSubscription() {
        
        let year = 2021
        manager.requestStockSubscriptionInfo(year: year) { [weak self] subscriptionList, error in
            
            // 需要去掉中央债的资料
            self?.subscriptionList = self?.filterNotAvailable(subscriptionList) ?? []
            self?.delegate?.didRecieveList(subscriptionList, error: error)
        }
    }

这样,你的列表中就不会有央债的资料了

https://ithelp.ithome.com.tw/upload/images/20210919/20140622FlcfTtf1D1.png

下一篇,介绍 TableViewCell 最左边的 [申购状态] 处理,下一篇会用到大量的 Date 相关 API。


<<:  D19-(9/19)-巨大(9921)-不只是台湾单车龙头,也是世界龙头

>>:  DAY 8- 《区块密码1》DES(2)- 密钥生成及安全性

Day 09 CSS <背景属性>

CSS背景属性 可以给页面元素添加背景样式 背景属性可设置背景颜色、背景图片、背景平舖、背景图片位置...

Day 9 python函式

今天我们要介绍的是python的函式,所谓的函式就是指当我们需要做到重复的动作时可以使用函式来简化程...

Day 07 line bot sdk python范例程序在做什麽

知道了line bot sdk python上的程序的功能是回复你和你传送相同的讯息。这边会看成是在...

Day4 Android - Layout版面(上)

接续前一天提到的,每一种layout都有它不同的属性名称以及排序模式,我这边就先举三个较常用的lay...

自动化 End-End 测试 Nightwatch.js 之踩雷笔记:点击物件 III

点击物件是蛮基本的操作,不过还是有很多地方需要注意。 回顾 第一天提到了如果该物件是 div,例如这...