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

Swift 4中基于Array与TableViewCell的数据持久化问题求助

Hey Markus, let’s fix that data persistence problem for your iOS password manager app. I’ll walk you through two solid options—UserDefaults and CoreData—showing exactly how to hook them up with your existing array and TableView setup.


方案1:使用 UserDefaults(适合少量密码数据)

UserDefaults is quick to implement, but note: it stores data in plaintext by default—you’ll want to add encryption for passwords (like using Keychain) if you go this route. Here’s how to integrate it:

  1. Define a reusable password structure
    Create a Codable struct to represent your username/password pairs—this lets us easily convert the array to/from data for storage:

    struct PasswordItem: Codable {
        let username: String
        let password: String
    }
    
  2. Update your array type
    Replace your existing array with one that holds PasswordItem instances:

    var passwordItems: [PasswordItem] = []
    
  3. Add save/load methods

    • Save your array to UserDefaults whenever data changes:
      func savePasswords() {
          do {
              let encodedData = try JSONEncoder().encode(passwordItems)
              UserDefaults.standard.set(encodedData, forKey: "SavedPasswords")
          } catch {
              print("Oops, failed to save passwords: \(error.localizedDescription)")
          }
      }
      
    • Load data when your view loads (call this in viewDidLoad()):
      func loadPasswords() {
          guard let savedData = UserDefaults.standard.data(forKey: "SavedPasswords") else { return }
          do {
              passwordItems = try JSONDecoder().decode([PasswordItem].self, from: savedData)
              tableView.reloadData() // Refresh your TableView right away
          } catch {
              print("Failed to load passwords: \(error.localizedDescription)")
          }
      }
      
  4. Connect to your TableView
    Update cellForRowAt to use your new array:

    override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCell(withIdentifier: "YourCellIdentifier", for: indexPath)
        let item = passwordItems[indexPath.row]
        cell.textLabel?.text = item.username
        cell.detailTextLabel?.text = String(repeating: "*", count: item.password.count) // Hide plaintext password!
        return cell
    }
    
  5. Trigger saves
    Call savePasswords() after adding/editing a password, or add it to applicationWillTerminate in your AppDelegate to ensure data is saved when the app exits.


方案2:使用 CoreData(适合大量密码数据,更 scalable)

CoreData is better for larger datasets and gives you built-in support for sorting, filtering, and relationships. Here’s how to set it up:

  1. Create a CoreData Entity

    • Open your .xcdatamodeld file, add a new Entity named PasswordEntity
    • Add two attributes: username (String) and password (String)
  2. Access the CoreData Context
    In your ViewController, get the shared context from your AppDelegate:

    let context = (UIApplication.shared.delegate as! AppDelegate).persistentContainer.viewContext
    
  3. Update your array
    Use an array of PasswordEntity objects instead of your current array:

    var passwordItems: [PasswordEntity] = []
    
  4. Fetch data from CoreData
    Add a method to load existing passwords (call this in viewDidLoad()):

    func fetchPasswords() {
        let fetchRequest: NSFetchRequest<PasswordEntity> = PasswordEntity.fetchRequest()
        do {
            passwordItems = try context.fetch(fetchRequest)
            tableView.reloadData()
        } catch {
            print("Failed to fetch passwords: \(error.localizedDescription)")
        }
    }
    
  5. Save new passwords
    When adding a new username/password pair, create a new entity and save the context:

    func addNewPassword(username: String, password: String) {
        let newPassword = PasswordEntity(context: context)
        newPassword.username = username
        newPassword.password = password
        
        do {
            try context.save()
            fetchPasswords() // Refresh the array and TableView
        } catch {
            print("Failed to save password: \(error.localizedDescription)")
        }
    }
    
  6. Connect to TableView
    Just like with UserDefaults, update cellForRowAt to use your CoreData array:

    override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCell(withIdentifier: "YourCellIdentifier", for: indexPath)
        let item = passwordItems[indexPath.row]
        cell.textLabel?.text = item.username
        cell.detailTextLabel?.text = String(repeating: "*", count: item.password?.count ?? 0)
        return cell
    }
    
  7. Add delete functionality (optional)
    If you want users to delete passwords, implement the TableView’s edit action:

    override func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCell.EditingStyle, forRowAt indexPath: IndexPath) {
        if editingStyle == .delete {
            let itemToDelete = passwordItems[indexPath.row]
            context.delete(itemToDelete)
            
            do {
                try context.save()
                fetchPasswords()
            } catch {
                print("Failed to delete password: \(error.localizedDescription)")
            }
        }
    }
    

Important Security Note

Neither UserDefaults nor CoreData encrypt data by default. For a password manager, you must encrypt the password fields before storing them. Apple’s Keychain Services API is the right tool for this—you can store encrypted passwords linked to your app, keeping them safe even if the device is compromised.

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.27 06:48:51