I'm having an issue saving and retrieving an array in UserDefaults from UIImagePickerControllerImageURL. I can get the array after synchronizing, but I am unable to retrieve it. myArray is empty.
The testImage.image does get the image, no problems there.
func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : Any]) {
let imageURL: URL = info[UIImagePickerControllerImageURL] as! URL
//test that imagepicker is actually getting the image
let imageData: NSData = try! NSData(contentsOf: imageURL)
let cvImage = UIImage(data:imageData as Data)
testImage.image = cvImage
//Save array to UserDefaults and add picked image url to the array
let usD = UserDefaults.standard
var array: NSMutableArray = []
usD.set(array, forKey: "WeatherArray")
array.add(imageURL)
usD.synchronize()
print ("array is \(array)")
let myArray = usD.stringArray(forKey:"WeatherArray") ?? [String]()
print ("myArray is \(myArray)")
picker.dismiss(animated: true, completion: nil)
}
There are many issue here.
- Do not use
NSData
, use Data
.
- Do not use
NSMutableArray
, use a Swift array.
- You can get the
UIImage
directly from the info
dictionary`.
- You can't store URLs in
UserDefaults
.
- You save
array
to UserDefaults
before you update the array with the new URL.
- You create a new array instead of getting the current array from
UserDefaults
.
- You needlessly call
synchronize
.
- You needlessly specify the type for most of your variables.
Here is your code updated to fix all of these issues:
func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : Any]) {
if let image = info[UIImagePickerControllerOriginalImage] as? UIImage {
testImage.image = image
}
if let imageURL = info[UIImagePickerControllerImageURL] as? URL {
//Save array to UserDefaults and add picked image url to the array
let usD = UserDefaults.standard
var urls = usD.stringArray(forKey: "WeatherArray") ?? []
urls.append(imageURL.absoluteString)
usD.set(urls, forKey: "WeatherArray")
}
picker.dismiss(animated: true, completion: nil)
}
Note that this saves an array of strings representing each URL. Later on, when you access these strings, if you want a URL
, you need to use URL(string: arrayElement)
.