Here we are going to save objects in the document directory which supports
NSCoding
protocol. We are going to achieve this using NSKeyedArchiver
and NSKeyedUnarchiver
class which are defines under the Foundation
framework.We can save
Array
, String
, Dictionary
,
Set
, UIView
, UIColor
, etc.we can even save
Int
, Double
, Float
, etc.Add below
UIViewController
extension in your project.
extension UIViewController {
// Save object in document directory
func saveObject(fileName: String, object: Any) -> Bool {
let filePath = self.getDirectoryPath().appendingPathComponent(fileName)//1
do {
let data = try NSKeyedArchiver.archivedData(withRootObject: object, requiringSecureCoding: false)//2
try data.write(to: filePath)//3
return true
} catch {
print("error is: \(error.localizedDescription)")//4
}
return false
}
// Get object from document directory
func getObject(fileName: String) -> Any? {
let filePath = self.getDirectoryPath().appendingPathComponent(fileName)//5
do {
let data = try Data(contentsOf: filePath)//6
let object = try NSKeyedUnarchiver.unarchiveTopLevelObjectWithData(data)//7
return object//8
} catch {
print("error is: \(error.localizedDescription)")//9
}
return nil
}
//Get the document directory path
//10
func getDirectoryPath() -> URL {
let arrayPaths = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask)
return arrayPaths[0]
}
}
1: File name must be unique for your object otherwise, it will overwrite the older object if saved with same name. Using fileName we are creating a directory file path URL
2: Create a
Data
using an object with NSKeyedArchiver
class function archivedData
.3: Save this data at the above
URL
path.4: Check if there is an error while saving the Data.
5: When you are fetching the object from directory, provide the same file name using which you have saved it. Using the file name create file path
URL
.6: Get the Data from file path URL.
7: Convert Data into object using
NSKeyedUnarchiver
class function unarchiveTopLevelObjectWithData
.8: Return the object.
9: Catch the error while retrieving our object.
10: This function returns the document directory path
URL
.Move to your UIViewController Class
Open your ViewViewController class and inside your viewDidLoad function add below code.override func viewDidLoad() {
super.viewDidLoad()
// Your object that needs to be save
let array = ["iPhone", "Macbook Pro", "iPad", "Watch"]
// Save your objet
if self.saveObject(fileName: "myArray", object: array) {
print("saved")
} else {
print("not saved")
}
// Get your object
if let value = self.getObject(fileName: "myArray") as? [String] {
print("value is: \(value)")
}
}
Saving the custom class object
As discussed earlier we can save the custom class object which confirmsNSCoding
protocol.
Suppose we have a custom Car as below.
class Car: NSObject, NSCoding {
var brand: String?
var madel: String?
func encode(with aCoder: NSCoder) {
aCoder.encode(self.madel, forKey:"madel")
aCoder.encode(self.brand, forKey:"brand")
}
required init?(coder aDecoder: NSCoder) {
self.madel = aDecoder.decodeObject(forKey:"madel") as? String
self.brand = aDecoder.decodeObject(forKey:"brand") as? String
}
init(barand: String, model: String) {
self.brand = barand
self.madel = model
}
}
As we can see this class is confirms the NSCoding protocol so we can save it using below the code.
let car = Car(barand: "Audi", model: "A4")
if self.saveObject(fileName: "myCar", object: car) {
print("saved")
} else {
print("not saved")
}
// Get the saved Car object
if let car = self.getObject(fileName: "myCar") as? Car {
print("my car is: \(car)")
}
We can even save the Array of Car.Read our next Article: Sending data from iPhone to Apple Watch
Excellent tutorial! Works great! Thanks a lot.