You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

点击ViewController按钮向另一控制器UITableView添加名片数据并永久存储

嘿,刚好我之前做过类似的名片扫描保存需求,给你一步步拆解实现方案,保证能搞定:

实现步骤拆解

1. 先把扫描信息结构化:定义名片数据模型

OCR扫出来的都是零散的字符串,咱们得把它们打包成一个清晰的模型,方便后续存储和展示。用struct就够了,加上Codable协议还能直接序列化存到本地:

struct BusinessCard: Codable {
    let name: String
    let address: String? // 允许空值,毕竟有些名片可能没写地址
    let phoneNumber: String?
    let email: String?
    
    // 写个初始化方法,直接把OCR返回的字典转成模型
    init(ocrResult: [String: String]) {
        self.name = ocrResult["name"] ?? ""
        self.address = ocrResult["address"]
        self.phoneNumber = ocrResult["phoneNumber"]
        self.email = ocrResult["email"]
    }
}

2. 搞定永久存储:实现数据持久化逻辑

要让数据重启APP也不丢,最简单的用UserDefaults(适合名片数量不多的场景),如果之后要存几百上千张,再换成Core Data或者Realm就行。咱们整个单例工具类来管理存储,方便全局调用:

class CardStorage {
    static let shared = CardStorage() // 单例,全局唯一实例
    private let userDefaults = UserDefaults.standard
    private let storageKey = "SavedBusinessCards" // 存数据的key
    
    // 保存整个名片数组
    func saveCards(_ cards: [BusinessCard]) {
        do {
            let encodedData = try JSONEncoder().encode(cards)
            userDefaults.set(encodedData, forKey: storageKey)
        } catch {
            print("名片保存失败:\(error.localizedDescription)")
        }
    }
    
    // 获取所有已保存的名片
    func getSavedCards() -> [BusinessCard] {
        guard let savedData = userDefaults.data(forKey: storageKey) else {
            return []
        }
        do {
            return try JSONDecoder().decode([BusinessCard].self, from: savedData)
        } catch {
            print("读取名片失败:\(error.localizedDescription)")
            return []
        }
    }
    
    // 追加新名片到已有数据里
    func addNewCard(_ card: BusinessCard) {
        var existingCards = getSavedCards()
        existingCards.append(card)
        saveCards(existingCards)
    }
}

3. 扫描完成后:保存并跳转/刷新列表

假设你已经完成了OCR扫描,拿到了姓名、地址这些信息,点击保存按钮的时候这么做:

// 这里替换成你真实的OCR扫描结果
let ocrScanResult = [
    "name": "张三",
    "address": "北京市朝阳区XX大厦15层",
    "phoneNumber": "138XXXX1234",
    "email": "zhangsan@example.com"
]
// 转成模型
let newBusinessCard = BusinessCard(ocrResult: ocrScanResult)

// 保存到本地
CardStorage.shared.addNewCard(newBusinessCard)

// 跳转到第二个ViewController(如果是用storyboard的话,记得给VC设好identifier)
if let secondVC = storyboard?.instantiateViewController(withIdentifier: "CardListVC") as? SecondViewController {
    navigationController?.pushViewController(secondVC, animated: true)
}

4. 第二个VC的TableView配置:展示所有名片

在第二个ViewController里,咱们要做的就是每次进入页面时读取最新数据,然后刷新TableView:

class SecondViewController: UIViewController, UITableViewDataSource, UITableViewDelegate {
    @IBOutlet weak var cardTableView: UITableView!
    private var savedCards: [BusinessCard] = []
    
    override func viewWillAppear(_ animated: Bool) {
        super.viewWillAppear(animated)
        // 每次进入页面都拉取最新的名片数据
        savedCards = CardStorage.shared.getSavedCards()
        cardTableView.reloadData()
    }
    
    // MARK: - UITableView数据源方法
    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return savedCards.count
    }
    
    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        // 记得在storyboard里给cell设好identifier为"CardCell"
        let cell = tableView.dequeueReusableCell(withIdentifier: "CardCell", for: indexPath)
        let currentCard = savedCards[indexPath.row]
        
        // 配置cell内容,这里用默认cell的文本标签举例,你也可以自定义cell显示更多信息
        cell.textLabel?.text = currentCard.name
        cell.detailTextLabel?.text = currentCard.phoneNumber ?? currentCard.email ?? "无联系方式"
        return cell
    }
    
    // 可以自定义cell高度,让内容显示更舒服
    func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
        return 80
    }
}

几个额外的小提示

  • 一定要在storyboard里给TableView的cell设置正确的identifier,不然会崩溃
  • 建议在保存前加个编辑页面,让用户核对OCR识别的信息(毕竟OCR偶尔会出错)
  • 如果之后名片数量暴涨,UserDefaults就不够高效了,这时候只需要替换CardStorage里的存储逻辑(换成Core Data),上层的展示代码完全不用改,很灵活

内容的提问来源于stack exchange,提问作者Snehal

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.27 07:34:40