将多个变量保存到 NSUserdefaults 并按保存顺序显示在另一个视图控制器上的最佳方法是什么?

What's the best way to save multiple variables into NSUserdefaults and display on another view controller in the order saved?

新 swift 来了!我在概念化如何存储具有多个详细信息的位置信息时遇到问题。用户默认是最好的方法吗?也许json数组文件?

我有两个视图控制器 1. 收藏夹和 2. 信息。

FavoritesViewController 像这样按照收藏顺序显示多组数据


Favorites

Group 1             Remove button
- Name of location
- Address
- latitude
- longitude
- Hours

then continues groups

在 infoViewController 上,它显示数据库中的位置。它有一个最喜欢的按钮,用于存储它以供在 favoritesViewController 中使用。

  @IBAction func favoriteThis(_ sender: Any) { 

       // check the state of favorited button
          if toggleState == 1 {
            toggleState = 2
            favoriteThis.setTitle("favorited!", forState: .normal)
            UserDefaults.standard.set(toggleState, forKey: "favorited")

        } else {
            toggleState = 1
         favoriteThis.setTitle("favorite", forState: .normal)
            UserDefaults.standard.set(toggleState, forKey: "favorited")

        }

        //set the current values to variables

        let name = self.selectedLocation!.name
        let address = self.selectedLocation!.address
        let lat = self.selectedLocation!.latitude
        let long = self.selectedLocation!.longitude

         // set them to an array and store them with a unique id
         let array = [id, name, address, lat, long]

         let defaults = UserDefaults.standard
          defaults.set(array, forKey: "FavArray")

   }

这确实存储在 FavArray 中,但是如果我需要在 favoriteViewController 中保存和显示这些组中的多个组,您认为解决这个问题的更好解决方案是什么?

谢谢大家!

UserDefaults 适用于小块数据。因此,我建议不要使用用户默认值,而是让您的自定义 PList 文件(您可以将其视为您的自定义 UserDefaults 文件)专门用于您的自定义类型数组。

为了解决您的问题,我创建了一个自定义类型,它将像这样保存您的所有位置数据:-

struct FavoriteLocation: Codable {
    let name: String
    let address: String
    let latitude:CLLocationDegrees
    let longitude: CLLocationDegrees

    init(name: String,address: String, latitude: CLLocationDegrees,longitude: CLLocationDegrees) {
        self.name = name
        self.address = address
        self.latitude = latitude
        self.longitude = longitude
    }
}

注意:您的自定义类型应符合 Codable 协议,以便它可以在自定义 Plist 文件中进行编码和解码。

下一个:- 在您的 ViewController 中,您可以填充此类型的数组并使用它来保存以及从您的 customPList 文件中检索数据。我在 ViewController 中总结了所有内容,并附有评论,如下所示。如果您不理解其中的任何部分,请告诉我。

class CustomPListViewController: UIViewController {

    /// Make your array of Favorite Locations
    let favLocationArray:[FavoriteLocation] = []

   /**
      Create our own directory to save data locally in a custom Plist file, inside our apps Document directory.
      This is used both when writing and retrieving.
     */
    let dataFilePath = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first?.appendingPathComponent("FavoriteLocations.plist")

    /// Save your array in custom PList file (Encode)
    func saveFavoritePLacesInCustomPList(favLocationArray: [FavoriteLocation]) {
        let encoder = PropertyListEncoder()
        do {
            let data = try encoder.encode(favLocationArray)
            guard let dataFilePath = self.dataFilePath else { return }
            do {
                try data.write(to: dataFilePath)
            } catch {
                // Handle error
            }
        } catch {
            // Handle error
        }

    }


    // Retrieve your saved data (Decode)
    func retrieveFavoriteLocations() {
        guard let filePath = self.dataFilePath else {return }
        do {
            let data = try Data(contentsOf: filePath)
            let decoder = PropertyListDecoder()
            do {
                let favoriteLocationsArray = try decoder.decode(Array<FavoriteLocation>.self, from: data)
                // This is your data ready to use
                print(favoriteLocationsArray)

            } catch  {
                // Handle error
            }

        } catch  {
           // Handle error
        }

    }



}




它是如何工作的?

我们正在使用 PropertyListEncoderencode,即将您的自定义对象转换为可以保存在 .plist 文件中的格式。为了将您的数据返回到您应用程序的模型 (FavoriteLocation),我们使用 PropertyListDecoder 做相反的事情,即 decode .plist 格式的数据返回到您的自定义对象。

如何查看您的自定义 .plist 文件?

在您的 viewDidLoad 方法调用中 print(dataFilePath!) 这将打印完整的文件路径,您可以导航到它并查看您的 FavoriteLocations.plist