How do I save a swift array? - ios

I am creating an app in Swift that manages tasks based off of priority. I currently place the tasks into an array. Does anybody know how I can save this array so that when I open the app I will still be able to access the data?

Use NSUserDefaults.
Save array:
let defaults = NSUserDefaults.standardUserDefaults()
defaults.setObject(myArray, forKey: "myarray")
defaults.synchronize()
Read array:
myArray = defaults.dataForKey("myarray") as Array

Related

Ambiguous use of 'mutableCopy()' Swift3

I tried to update Swift 3 and I got the following error :
Ambiguous use of 'mutableCopy()'
Before update to swift 3. It runs well.
Swift 2.3
NSUserDefaults.standardUserDefaults().objectForKey("listsavednews")?.mutableCopy() as! NSMutableArray
Swift 3.0
(UserDefaults.standard.object(forKey: "listsavednews")? as AnyObject).mutableCopy() as! NSMutableArray
I found that mutableCopy in Swift3 return Any that doesnt have method mutableCopy() so that it needs to cast to AnyObject.
Any helps thanks.
I dont know why I can't comment.
Thanks all, I'll be using :
UserDefaults.standard.mutableArrayValue(forKey: "listsavednews")
mutableCopy is an Objective-C method from NSObject. There's little reason to use it in Swift 3.
Since you are dealing with UserDefaults and mutableCopy, you must be dealing with either an array or dictionary. Or it could be a string.
The proper way to do this in Swift 3 is to use the proper UserDefaults method to get an array or dictionary. And assign the result to a var. That combination will give you a mutable array or mutable dictionary.
var someArray = UserDefaults.standard.array(forKey: "somekey")
or:
var someDictionary = UserDefaults.standard.dictionary(forKey: "somekey")
In the two above cases, you end up with an optional since there might not be any data for the given key. And you also get a non-specific array or dictionary which isn't ideal. It would be better to cast the result to the appropriate type.
Let's say you have an array of strings and you want an empty array if there is nothing currently in user defaults. You can then do:
var someArray = UserDefaults.standard.array(forKey: "somekey" as? [String]) ?? []
Adjust as necessary if the array contains something other than String.
If you actually have a dictionary, the code would be similar.
var someDictionary = UserDefaults.standard.dictionary(forKey: "somekey") as? [String:String] ?? [:]
If your original object is just a string, then you could do:
var someString = UserDefaults.standard.string(forKey: "somekey") ?? ""

cache array of objects iOS

how can I cache array of objects in iOS using swift 3 ??
I know I can use NSCache for it the only problem is this that I know how to cache a single object but dont know how to cache a whole array of it..
var cachedData = NSCache<NSString, myObject>() // i cant define it like NSCache<NSString, [myObject]>() cause NSCache takes anyobject not Array of AnyObject
//cache.setObject(myObject, forKey: "CachedObject")
anyone can guide how can I do it??

Error : replaceObjectAtIndex:withObject:]: mutating method sent to immutable object

My applicaiton crashes with the exception mentioned in the title. Please find below my explanation :
tried to store array values using NSUserDefaults in my TableViewController as under :
func didDismissContentViewController(controller:ContentViewController,pageIndex:Int) { //You're passed in the contentViewController here, use relevant data to update your model. NSLog("Inside delegate method ..\n") var currentIdx = pageIndex
NSLog("Value of index edited \(pageIndex)")
NSLog("Current edited value is : \(controller.myTextView.text)")
**pageContent.replaceObjectAtIndex(pageIndex, withObject: controller.myTextView.text)**
**//pageCotent is defined as an NSMutableArray only...**
NSUserDefaults.standardUserDefaults().setObject(pageContent as NSMutableArray, forKey: "PageValues")
NSUserDefaults.standardUserDefaults().synchronize()
}
Retrieval is done as under : if var storedPageContent = NSUserDefaults.standardUserDefaults().objectForKey("PageValues") as? NSMutableArray{ pageContent = storedPageContent
While I am able to store, retrieve and display the updated page values in their respective pages, subsequent transition back and forth between the tableviewcontroller and content view controller throws the below error:
015-12-21 00:51:46.592 PageApp[3943:203948] * Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: '-[__NSCFArray replaceObjectAtIndex:withObject:]: mutating method sent to immutable object' * First throw call stack:
I tried commenting out the store to NSUserDefault, and the applicaiton does not crash, whereas using the NSUserDefault to store values, causes this to happen, So the error appears when I store it in NSUserDefaults and then retrieve it and assign it to array.
any help on this will be appreciated.Exchange data between uitah
The arrays returned from NSUserDefaults are immutable, so you will need to make a mutable copy of the array and then re-set the array in NSUserDefaults, once you've modified it.
I don't know Swift well enough to give you a code example, but this is how it would be done in Objective-C:
NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefauts];
NSMutableArray *pageContent = [[userDefaults objectForKey:#"PageValues"] mutableCopy];
[pageContent replaceObjectAtIndex:pageIndex withObject:controller.myTextView.text];
[userDefaults setObject:pageContent forKey:#"PageValues"];
I ran into exactly the same problem yesterday. Apparently if you get an array object using NSUserDefaults it acts like an NSArray even if you specify it to be NSMutableArray.
So the way I solved this problem was using this way (Objective-C). Once I had passed it to another NSMutableArray I was able to add / remove objects from it.
NSArray *favArrayTemp = [[NSUserDefaults standardUserDefaults] objectForKey:#"MyFavServers"];
NSMutableArray favArray = [[NSMutableArray alloc] initWithArray:favArrayTemp];
I think the issue is even though you are assigning values retrieved from NSUserDefaults to a NSMutableArray, it is not actually creating a NSMutableArray as you expected. Can you try initialising a new NSMutableArray with the objects fetched from NSUserDefaults?
In Objective-C, it will be like
NSMutableArray *pageContent = [[NSMutableArray alloc] initWithObjects:object1,nil];
where object1 is the value fetched from NSUserDefaults. Sorry I did not know Swift
Use Swift native types.
Cast the type retrieved from NSUserDefaults to a native Swift collection type as var then it's mutable.
var pageContent = [String]()
...
let userDefaults = NSUserDefaults.standardUserDefauts()
pageContent = userDefaults["PageValues"] as! [String]
Replacing is pretty easy, too.
pageContent[pageIndex] = controller.myTextView.text
Side note: The forced unwrapping while reading the value from NSUserDefaults assumes that the key/value pair has been registered properly. Then the unwrapping is safe.
Thank you for the response. I made changes as suggested by you and it worked. Let me share it below:
// As mentioned by you, since NSUserDefault always expects an NS Array, I did the storing as under :
NSLog("I am inside the bactktomonths ..\n")
//Defined an NS Array to copy the Mutable array to Immutable array
var storedArray = NSArray()
storedArray = pageArray!
NSUserDefaults.standardUserDefaults().setObject(storedArray , forKey: "PageValues")
NSUserDefaults.standardUserDefaults().synchronize()
}
// Retrieval.
if (NSUserDefaults.standardUserDefaults().objectForKey("PageValues") != nil){
pageContent = NSUserDefaults.standardUserDefaults().objectForKey("PageValues")?.mutableCopy() as NSMutableArray
// I am not sure If I need to execute the below code, but I have left it as suggested and it works currently !
NSUserDefaults.standardUserDefaults().setObject(pageContent, forKey: "PageValues")
Thanks

How to create an NSDictionary and Write and Read the information from a NSUserDefaults object in swift

I want to store 3 variables all of type Int for a game (gameLevel,time,clicks). I want to save the values of these variables in one UIViewController at the end of the game, and pass it to another UIViewController that will present the gameScore (using UILabel).
Should I use an NSDictionary object for this task? and how do I create an NSUserDefaults object and pass it the NSDictionary?
Save the values in NSUserDefaults when game ends
NSUserDefaults.standardUserDefaults().setInteger(gameLevel, forKey: "gameLevelKey")
NSUserDefaults.standardUserDefaults().setInteger(time, forKey: "timeKey")
NSUserDefaults.standardUserDefaults().setInteger(clicks, forKey: "clicksKey")
NSUserDefaults.standardUserDefaults().synchronize()
Get the saved values from NSUserDefaults in other view controller
let gameLevel = NSUserDefaults.standardUserDefaults().integerForKey("gameLevelKey")
let time = NSUserDefaults.standardUserDefaults().integerForKey("timeKey")
let clicks = NSUserDefaults.standardUserDefaults().integerForKey("clicksKey")
NSUserDefaults is like database where you can save values using setXXX method and retrieve values using the xxxForKey method

Saving NSMutableArray with NSUserDefaults in Swift Returns Nil

I have a NSMutableArray. Here is how I save it with NSUserDefaults:
var defaults = NSUserDefaults.standardUserDefaults()
defaults.setObject(downloadedFile as NSMutableArray, forKey: "myKey")
And here how I retrieve it:
var downloadedFilesFromUserDefaults:NSMutableArray = defaults.objectForKey("myKey") as NSMutableArray
take look at this and try to save you array like this! as this worked perfectly!
var arr:NSMutableArray = NSMutableArray(objects: "ASD","aSd")
NSUserDefaults.standardUserDefaults().setObject(arr, forKey: "Array")
NSUserDefaults.standardUserDefaults().synchronize()
on button click
NSLog("%#", NSUserDefaults.standardUserDefaults().objectForKey("Array") as NSMutableArray)
It looks like swift somehow release my object i needed to make sure that my object is not nil.

Resources