Теперь то, что я добавляю в корзину, отображается правильно. Но когда я снова открываю страницу, данные теряются. Я пытаюсь сохранить данные cartTableView в userdefaults. Я пробовал несколько способов, но не смог. Вот мой код для cartViewController:

import UIKit
class CartViewController: UIViewController, UITableViewDataSource, UITableViewDelegate {
    
    var arrdata = [jsonstruct]()
    var categorydata = [Categories]()
    var imgdata = [Images]()
    
    var cartArray = [CartStruct]()
    
    @IBOutlet var cartTableView: UITableView!
    
    @IBOutlet var totalCount: UILabel!
    @IBOutlet var subtotalPrice: UILabel!
    @IBOutlet var shippingPrice: UILabel!
    @IBOutlet var totalPrice: UILabel!
    @IBOutlet var proceedBtn: UIButton!
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        cartArray = (UserDefaults.standard.array(forKey: "cartt") as? [CartStruct])!
        cartTableView.reloadData()

    }
    func numberOfSections(in tableView: UITableView) -> Int {
        return 1
    }
    
    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return cartArray.count
    }
    
    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {

        let cell = tableView.dequeueReusableCell(withIdentifier: "CartCellTableViewCell", for: indexPath) as! CartCellTableViewCell
 
        cell.cartImageView.downloadImage(from: cartArray[indexPath.row].cartItems.images.first?.src ?? "place_holder_image")

        cell.productNameCart.text = cartArray[indexPath.row].cartItems.name
        cell.prodductDescCart.text = cartArray[indexPath.row].cartItems.categories.first?.type
        cell.productPriceCart.text = cartArray[indexPath.row].cartItems.price
        
        cell.addBtn.addTarget(self, action: #selector(add(sender:)), for: .touchUpInside)
        cell.addBtn.tag = indexPath.row
        
        let cartQuantity = cartArray[indexPath.row].cartQuantity
        cell.prodCount.text = "\(cartQuantity)"
        
        if cartQuantity >= 0 {
            cell.subBtn.isUserInteractionEnabled = true;
            cell.subBtn.addTarget(self, action: #selector(sub(sender:)), for: .touchUpInside)
            cell.subBtn.tag = indexPath.row
        } else {
            cell.subBtn.isUserInteractionEnabled = false;
        }
        return cell
    }
    
    func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCell.EditingStyle, forRowAt indexPath: IndexPath) {
        if editingStyle == .delete {
            cartArray.remove(at: indexPath.row)
            tableView.deleteRows(at: [indexPath], with: .fade)
            tableView.reloadData()
        }
    }
    
    @objc func add(sender: UIButton){
        if cartArray[sender.tag].cartQuantity >= 0 {
            cartArray[sender.tag].cartQuantity += 1
            cartTableView.reloadData()
        }
    }
    
    @objc func sub(sender: UIButton){
        if cartArray[sender.tag].cartQuantity > 0 {
            cartArray[sender.tag].cartQuantity -= 1
            cartTableView.reloadData()
        }
    }
}
   

Но здесь отображается некоторая ошибка времени выполнения: «Поток 1: сбой времени выполнения Swift: принудительно развернул нулевое значение»

Пожалуйста, подскажите, как я могу все это исправить .. Заранее спасибо!

-2
Ahana Chakraborty 11 Сен 2021 в 09:35

4 ответа

Лучший ответ

Да, мы можем хранить в UserDefaults, но он не является гибким по сравнению с Core Data или другим хранилищем для операций добавления, обновления или удаления.

Ниже код должен работать.

Вам нужно сделать "CartStruct" как Codable

struct CartStruct : Codable {
    var cartItems: jsonstruct
    var cartQuantity: Int
}

Затем добавьте это для вставки и сохраните в касании «addToCartbtnTapped». (DetailViewController)

 func saveCart(data: CartStruct) {
    let defaults = UserDefaults.standard
    if let cdata = defaults.data(forKey: "cartt") {
        var cartArray = try! PropertyListDecoder().decode([CartStruct].self, from: cdata)
        cartArray.append(data)
        cartCount.text = "\(cartArray.count)"
        if let updatedCart = try? PropertyListEncoder().encode(cartArray) {
            UserDefaults.standard.set(updatedCart, forKey: "cartt")
        }
    }
}

@IBAction func addToCartbtnTapped(_ sender: Any) {
    if let info = detailInfo {
        let cartData = CartStruct(cartItems: info, cartQuantity: 1)
        self.saveCart(data: cartData)
        showAlert()
        (sender as AnyObject).setTitle("Go to Cart", for: .normal)
        addToCartbtn.isUserInteractionEnabled = false
    }
}


@IBAction func cartTappedToNavigate(_ sender: Any) {
        let cart = self.storyboard?.instantiateViewController(withIdentifier: "CartViewController") as? CartViewController
        self.navigationController?.pushViewController(cart!, animated: true)
    }

Теперь получите данные своей корзины из того места, где вы сохранили. (CartViewController)

override func viewDidLoad() {
        super.viewDidLoad()
        self.getCartData()
    }

 func getCartData() {
        let defaults = UserDefaults.standard
        if let data = defaults.data(forKey: "cartt") {
            cartArray = try! PropertyListDecoder().decode([CartStruct].self, from: data)
            cartTableView.reloadData()
        }
    }
0
Abdul Hoque Nuri 13 Сен 2021 в 09:34

Вы можете использовать UserDefaults, но вы должны использовать основные данные или область для лучшей производительности. как использовать этот код? // Сохранить: CartCache.save ([Корзина])

// Получаем данные: let cart = CartCache.get ()

struct CartCache {
    
        static let key = "CartCache"
    
        static func save(_ value: [CartStruct]!) {
          UserDefaults.standard.set(try? PropertyListEncoder().encode(value), forKey: key)
        }
    
        static func get() -> [CartStruct]! {
          var cartData: User!
          if let data = UserDefaults.standard.value(forKey: key) as? Data {
            cartData = try? PropertyListDecoder().decode([User].self, from: data)
            return cartData!
          } else {
            return []
          }
        }
    
         static func remove() {
            UserDefaults.standard.removeObject(forKey: key)
          }
        }
1
luay ElGhossain 12 Сен 2021 в 19:07

Вы должны использовать другие методы сохранения данных, отличные от пользовательских значений по умолчанию. Пользовательские значения по умолчанию в основном используются для сохранения небольшой информации, такой как имя, имя пользователя, пол и т. Д. Я рекомендую вам использовать Core Data вместо пользовательских значений по умолчанию, и вот очень полезное объяснение и пример проекта Core Data.

https://www.raywenderlich.com/7569-getting-started-with-core-data-tutorial

Хорошего дня :)

0
Muhammet Taha Genç 11 Сен 2021 в 12:10

Как многие люди упоминали, UserDefaults на самом деле не предназначен для хранения данных этого типа. Из документов:

Класс UserDefaults предоставляет программный интерфейс для взаимодействия с системой по умолчанию. Система значений по умолчанию позволяет приложению настраивать свое поведение в соответствии с предпочтениями пользователя. Например, вы можете разрешить пользователям указывать предпочтительные единицы измерения или скорость воспроизведения мультимедиа. Приложения сохраняют эти предпочтения, присваивая значения набору параметров в пользовательской базе данных по умолчанию. Параметры называются значениями по умолчанию, потому что они обычно используются для определения состояния приложения по умолчанию при запуске или того, как оно действует по умолчанию.

Однако я чувствую, что это все еще актуальный вопрос, и каждый разработчик IOS / MacOS должен знать, как его использовать.

NSUserDefaults прост и удобен в использовании, но есть некоторые вещи, которые вам нужно понять.

А именно, вы можете хранить только элементы списка свойств.

Объект по умолчанию должен быть списком свойств, то есть экземпляром (или для коллекций, комбинацией экземпляров) NSData, NSString, NSNumber, NSDate, NSArray или NSDictionary. Если вы хотите сохранить любой другой тип объекта, вам обычно следует заархивировать его, чтобы создать экземпляр NSData.

Это означает, что CartStruct не может просто сохраняться в UserDefaults, потому что это не NSData, NSString, NSNumber, NSDate, NSArray или NSDictionary или их комбинация.

Теперь использовать UserDefaults просто: у них есть синглтон для приложения под названием standard.

UserDefaults.standard.setValue("Hello Defaults", forKey: "Hello_Key")
let greeting = UserDefaults.standard.value(forKey: "Hello_Key")

print(greeting!)// prints Hello Dafaults

Следующий вопрос - как превратить вашу структуру в данные. Я уверен, что если вы зададите этот вопрос здесь и опубликуете код для своей структуры, вы получите быстрое и легкое решение. Когда у вас есть данные, вы можете сохранить их в UserDefaults или, что еще лучше, в файловой системе. На самом деле, я думаю, что действительно вопрос, который вы пытаетесь задать, заключается в том, как сохранить и получить ваши структурные данные для использования в табличном представлении.

0
SeaSpell 11 Сен 2021 в 17:18