Swift 2 NSUserDefaults read Arrays - arrays

i'm updating my app to Swift 2.. lots of errors uff.. anyway i'm trying to read a store array in NSuserDefaults, in swift 1 worked but now i get nil error with EXC_Breakdown. i don't know how to fix that...
this is how i read it:
var DescriptionArray = save.objectForKey("NewsDescriptions")! as! NSArray
this i how i save it (Description is the array):
var SaveDescription = save.setObject(Description, forKey: "NewsDescriptions")
save.synchronize()

Here is an example of how you can store data into NSUserDefault in Swift 2.0. It is very similar to Objective-C concept, only different syntax.
Initialize your NSUserDefault Variable:
let userDefaults = NSUserDefaults.standardUserDefaults()
Initialize what type of data to save: In your case you used objectForKey, even though that should work, it's better to be more specific about your code.
var DescriptionArray = userDefaults.arrayForKey("NewsDescriptions")
Save your data:
userDefaults.setObject(Description, forKey: "NewsDescriptions")
Then you can synchronize to process the saving faster.
userDefaults.synchronize()

Here is an example with Swift 2:
func saveArray(value: NSArray) {
NSUserDefaults.standardUserDefaults().setObject(value, forKey:"NewsDescriptions")
NSUserDefaults.standardUserDefaults().synchronize()
}
func readArray() -> NSArray {
return NSUserDefaults.standardUserDefaults().arrayForKey("NewsDescriptions")!
}

Related

Getting a __NSArray0 from a JWT

I have an api that creates a JWT for a logged in user and when I look at the decoded version of the token on jwt.io I get what I expect.
It shows that the data property is [] and it holds the users data when a user is logged in.
Now I am trying to decode this into swift for my iOS app, but the data in the data property comes back as:
(
)
and the type for this is __NSArray0
I can't loop through it or anything - what is a __NSArray0 and how would decode the token properly?
__NSArray0:
__NSArray means it's an NSArray object. It's the "old Objective-C immutable Array type". That's what gives you after decoding an JSON Array with (NS)JSONSerialization if you don't cast it into a Swift Array.
The 0 at the end is to say it's a specific NSArray, it's an NSArray empty, with no object. Why using that? Because in reality, it's a internal version of NSArray that is optimized for zero elements. So don't mind about it.
Since you have a NSArray, typical print of it, is:
(
)
So just cast it as an Array how its supposed type when non-empty to iterate. If you know it's an array of String, cast is as [String] and iterate over it.
It's the OpenStep format. Did you ever tried to read a PBXCodeProj?
Like more yourApp.xcodeproj/project.pbxproj It's there, you see how are printed NSDictionary, NSArray etc in that Format + comments.
In JSON, it's [] to show it's an Array, but in Objective-C the print is different.
Want to reproduce it?
let emptyNSArray = NSArray()
print("emptyNSArray:\n\(emptyNSArray)")
let castedEmptyAsArray = emptyNSArray as [AnyObject]
print("castedEmptyAsArray:\n\(castedEmptyAsArray)")
let nsArray = NSArray(array: ["Hello", "World", "!"])
print("nsArray:\n\(nsArray)")
let castedAsArray = nsArray as [AnyObject]
print("castedAsArray:\n\(castedAsArray)")
let emptyArrayJSON = Data("[]".utf8)
let decodedEmptyArrayDefault = try! JSONSerialization.jsonObject(with: emptyArrayJSON)
print("decodedEmptyArrayDefault:\n\(decodedEmptyArrayDefault)") //If you don't cast, it's by default a NSArray
let decodedEmptyArrayCasted = try! JSONSerialization.jsonObject(with: emptyArrayJSON) as! [AnyObject]
print("decodedEmptyArrayCasted:\n\(decodedEmptyArrayCasted)")
Output:
$>emptyNSArray:
(
)
$>castedEmptyAsArray:
[]
$>nsArray:
(
Hello,
World,
"!"
)
$>castedAsArray:
[Hello, World, !]
$>decodedEmptyArrayDefault:
(
)
$>decodedEmptyArrayCasted:
[]

Copy array of NSManagedObject objects in Swift 4

I have an array of NSManagedObject's and I want to copy them to a new array in order to manipulate them and not save the changes after the user is done.
The array:
var origQuestions: [Questions]?
This is how I retreive the data from CoreData:
self.origQuestions = MainDb.sharedInstance.randomQuestions(entity: "Questions", count: self.questionToShow)
This is what I need in Objective-C, but I want to know how to do so in Swift 4:
NSMutableArray *questionsCopy = [[NSMutableArray alloc] initWithArray:self.origQuestions copyItems:YES];
To translate that Objective-C code into Swift you do:
var questionsCopy = NSArray(array: origQuestions, copyItems:true) as! [Questions]
But since you declared origQuestions as optional, it needs to be:
var questionsCopy = origQuestions != nil ? NSArray(array: origQuestions!, copyItems:true) as? [Questions] : nil
Whether that fully works (Objective-C or Swift) with NSManagedObject or not is another question. See How can I duplicate, or copy a Core Data Managed Object? and its Swift answers for code that specifically covers doing deep copies of NSManagedObject instances.

How to save 2d array data permanently using userdefaults.standard

I'm trying to save 2d array data using userdefaults, but i'm getting this error Cannot convert value of type '[[String]]' to expected argument type 'String' here is my code
var tempQuestion2 = [tempQuestion]
if var tempData = UserDefaults.standard.stringArray(forKey: "tempData")
{
tempData.append(tempQuestion2)
tempQuestion2 = tempData
}
UserDefaults.standard.set(tempQuestion2, forKey: "tempData")
tempQuestion is a string array with data like [“9+1=10”, “5+4=9”] and i want tempQuestion2 to be [["9+1=10, "5+4=9"], ["3+4=7", "4+1=5"]] I'm guessing my issue is at UserDefaults.standard.stringArray. My question is different from the link because that question is about dictionary not array of array.
There's no problem saving and loading arrays of arrays to UserDefaults, to save your data use:
UserDefaults.standard.set(tempQuestion2, forKey: "tempData")
To read back (and update) the array of arrays use:
// Assuming tempQuestion is [String]
if var tempData = UserDefaults.standard.array(forKey: "tempData") as? [[String]] {
tempData.append(tempQuestion2)
UserDefaults.standard.set(tempData, forKey: "temp")
}

PFObject Array Sort

I'm using Parse and I have an array of PFObjects called "scorecardData". Each PFObject has a "score" property that is of type Int. I'm trying to sort my array by "score" but I'm getting the following error: "Binary operator '<' cannot be applied to two 'AnyObject?' operands". I'm not sure what I'm doing wrong here. I also tried down casting the objectForKey("score") as! Int but its not letting me do this. Any suggestions? Thanks in advance.
var scorecardData = [PFObject]()
scorecardData.sortInPlace({$0.objectForKey("score") < $1.objectForKey("score")})
You declared scorecardData variable as Array of PFObject. Why are you trying access PFObject property using objectForKey: reserved? Anyway I am not parse expert. But if you declared your array as [PFObject] you can use:
scorecardData.sortInPlace({$0.score < $1.score})
But this won't work unless you subclass PFObject for a more native object-oriented class structure. If you do that remember also to specify:
var scorecardData = [YOUR_NEW_CLASS]()
I strongly recommend subclassing PFObject to make use of all swift type-safe goodies.
But if you want to keep your data structure you can use:
scorecardData.sortInPlace({($0["score"] as! Int) < ($1["score"] as! Int)})
Keep in mind that it's dangerous, and in future avoid it.
If you want to Sort your array of PFOject... You can do this
extension Array where Element:PFObject {
func sort() -> [PFObject] {
return sort { (first, second) -> Bool in
let firstDate = first.objectForKey("time") as! NSDate//objectForKey(Constants.Parse.Fields.User.fullName) as? String
let secondDate = second.objectForKey("time") as! NSDate//objectForKey(Constants.Parse.Fields.User.fullName) as? String
return firstDate.compare(secondDate) == .OrderedAscending
}
}
}
Have you tried doing this?
var query = PFQuery(className:"ScoreCard")
// Sorts the results in ascending order by the score field
query.orderByDescending("score")
query.findObjectsInBackgroundWithBlock {

Swift- using the array in different classes

I have two classes both for different UIViewController, in one of the classes i have 3 arrays, and i have added those arrays to a NSUserdefaults, now i want to call those/use those arrays in the other class, how do i do that?
let userDefaults = NSUserDefaults.standardUserDefaults()
userDefaults.setObject(name, forKey: "ThisContainsName")
userDefaults.setObject(surname, forKey: "ThisContainsSurname")
userDefaults.setObject(money, forKey: "ThisContainsBudget")
userDefaults.synchronize()
Just use arrayForKey to get the arrays:
var yourNames = NSUserDefaults.standardUserDefaults().arrayForKey("ThisContainsName")
var yourSurnames = NSUserDefaults.standardUserDefaults().arrayForKey("ThisContainsSurname")
var yourMoneys = NSUserDefaults.standardUserDefaults().arrayForKey("ThisContainsBudget")

Resources