User Defaults Attempt to set a non-property-list object - swift

I've got a problem with storing an NSDictionary object with 39 parameters (key and value) into a UserDefault object. The code crashes where I left the comment. self.userDefaults.set(data, forKey: "userData")
This is the error I'm getting:
[User Defaults] Attempt to set a non-property-list object {
city = "";
country = "";
cover = "default.png";
date = "2019-10-02";
description = "";
email = "hashdoge#outlook.com";
"email_comment" = 0;
"email_like" = 0;
"email_new_friend" = 0;
"email_newsletter" = 1;
facebook = "";
"first_name" = "";
follower = 3;
following = 2;
gender = 0;
gplus = "";
idu = 42;
image = "default.png";
ip = "";
"last_name" = "";
lastfm = "";
likes = 3;
"login_token" = "<null>";
"logout_time" = 0;
myspace = "";
notificationc = 1;
notificationd = 1;
notificationf = 1;
notificationl = 1;
offline = 0;
online = 1570879800;
password = "$2y$107675ze1wZ/riJgQ2e";
private = 0;
salted = "$2y$10$GKUmSJGcq932DMJGMA8791RIO";
soundcloud = "";
suspended = 0;
totaltracks = 0;
tumblr = "";
twitter = "";
username = HashDoge;
vimeo = "";
website = "";
youtube = "";} as an NSUserDefaults/CFPreferences value for key userData
Here is the code that I'm trying to make work
Code:
func callApigetLoginResponse(){
FTIndicator.showProgressWithmessage("", userInteractionEnable: false)
let parameters = ["useremail":txtEmail.text!,"password":txtPassword.text!]
SignInGet.ApiGetSignIn(parameters: parameters as NSDictionary) { (Result, Error) in
// print(Result!)
if Error != nil{
print(Error!)
}else{
let dataDict:NSDictionary = Result as! NSDictionary
if (dataDict["success"]as! Int == 1){
let loginResponse = dataDict["userlogin"] as! NSArray
let data = loginResponse[0] as! NSDictionary
let uid = data["idu"] as! String
self.sendTokenaApi(uid: uid)
self.userDefaults.set(uid, forKey: "id")
self.userDefaults.set(data, forKey: "userData") // code crashes here
self.userDefaults.synchronize()
let updateUserInfo = UpdateUserInfoUtl()
updateUserInfo.callApigetUserDataResponse()
self.pushToHomeController()
}else if (dataDict["success"]as! Int == 0) {
let message = dataDict["userlogin"] as! String
FTIndicator.showInfo(withMessage: message)
}
}
}
}

I fixed it. The problem was the "< n u l l >" in the login_token.
I made it as an empty string "" in the database and it worked.

Related

Parse Alamofire result swift

I'm very lost parsing the following response from an AF request – let json = result as! NSDictionary – in Swift:
{
errors = (
);
get = statistics;
parameters = {
country = germany;
};
response = (
{
cases = {
"1M_pop" = 14303;
active = 317167;
critical = 4179;
new = "+15161";
recovered = 863300;
total = 1200006;
};
continent = Europe;
country = Germany;
day = "2020-12-08";
deaths = {
"1M_pop" = 233;
new = "+380";
total = 19539;
};
population = 83900328;
tests = {
"1M_pop" = 347331;
total = 29141172;
};
time = "2020-12-08T09:15:08+00:00";
}
);
results = 1;
}
Any idea how to get the actual case numbers, i.e. for example the number of new cases?
So far I have tried the following (error throwing) approach:
if let responseDict = result as? NSDictionary {
if let data = responseDict.value(forKey: "response") as?
[NSDictionary] {
// Get case numbers
guard let cases = data[0]["cases"] else { return }
guard let casesPerOneMil = cases[0] as! Int else { return }
print(casesPerOneMil)
}
}
Basically don't use NS... collection types in Swift at all, use native types.
And don't use value(forKey, use key subscription.
And you have to conditional downcast Any to the expected concrete type.
There is another mistake: The object for cases is a dictionary, note the {} and you have to get the value for casesPerOneMil with key subscription, too
if let responseDict = result as? [String:Any],
let dataArray = responseDict["response"] as? [[String:Any]],
let firstDataItem = dataArray.first {
// Get case numbers
guard let cases = firstDataItem["cases"] as? [String:Any] else { return }
guard let casesPerOneMil = cases["1M_pop"] as? Int else { return }
print(casesPerOneMil)
}
}

SwiftUI - Include Relationship info in FetchRequest

I have an Expense entity with a one-to-many relationship to an Accounts Entity.
My current fetch request is as follows:
let request = NSFetchRequest<NSFetchRequestResult>(entityName: Expenses.entity().name ?? "Expenses")
request.predicate = predicate
request.returnsObjectsAsFaults = false
request.resultType = .dictionaryResultType
let expression = NSExpressionDescription()
// check operations list from apple or nshipster in nsexpressions
expression.expression = NSExpression(forFunction: "noindex:", arguments:[NSExpression(forKeyPath: "originAccounts.isCredit")])
expression.name = "checkIsCredit"
expression.expressionResultType = .booleanAttributeType // might be another
let expression1 = NSExpressionDescription()
expression1.expression = NSExpression(forFunction: "noindex:", arguments:[NSExpression(forKeyPath: "id")])
expression1.name = "checkExpenses"
expression.expressionResultType = .UUIDAttributeType
request.propertiesToFetch = [expression,expression1]
context.perform {
do {
let results = try request.execute()
print(results)
My Predicate is:
predicate: NSPredicate(format: "expenseDate >= %# AND expenseDate < %#", datesView.prevMonthPayStart as NSDate, datesView.nextPaydate as NSDate)
When I print the results I get
[{
expenseAccount = "Test Account";
expenseCategory = "Test Category";
expenseCost = 123;
expenseDate = "2020-11-12 05:00:00 +0000";
expenseIsPaid = 1;
expenseName = Test;
expenseType = "One-time";
id = "AFB5EB0E-20A2-47EA-8F36-22D07571C213";
shouldDupe = 1;
}, {
expenseAccount = "Test Account";
expenseCategory = "Test Category";
expenseCost = 23;
expenseDate = "2020-11-13 05:00:00 +0000";
expenseIsPaid = 0;
expenseName = "Test Recurring";
expenseType = Monthly;
id = "5CFB5E58-4377-40DA-9C6A-AF8027ACEC60";
shouldDupe = 1;
}]
I understand that I won't see attributes that are nil, but I want to get an attribute through originAccounts relationship. Is this possible? Specifically I want to get the value of originAccounts.isCredit. Here is an example object for reference.
<Expenses: 0x60000321af80> (entity: Expenses; id: 0xa7ab05bb9341bf4a <x-coredata://ED302202-3018-445F-8FFE-DD2E85219E64/Expenses/p1>; data: {
expenseAccount = "Test Account";
expenseCategory = "Test Category";
expenseCost = 123;
expenseDate = "2020-11-12 05:00:00 +0000";
expenseId = nil;
expenseIsPaid = 1;
expenseName = Test;
expenseType = "One-time";
id = "AFB5EB0E-20A2-47EA-8F36-22D07571C213";
lastMonthlyExpenseID = nil;
nextMonthlyExpenseID = nil;
originAccounts = "0xa7ab05bb9341bf4e <x-coredata://ED302202-3018-445F-8FFE-DD2E85219E64/Accounts/p1>";
originCategories = nil;
shouldDupe = 1;
})
Could you try NSExpressions, you won't make a fetch, therefore you'll be mutch efficient.
let fetchRequest = NSFetchRequest<NSFetchRequestResult>(entityName: "yourEntity")
fetchRequest.predicate = NSPredicate(format: "yourPredicate")
fetchRequest.resultType = .dictionaryResultType
fetchRequest.returnsObjectsAsFaults = false
let expression = NSExpressionDescription()
// check operations list from apple or nshipster in nsexpressions
expression.expression = NSExpression(forFunction: "yourOperation", arguments:[NSExpression(forKeyPath: "Expenses.originAccounts.isCredit")])
expression.name = "yourName"
expression.expressionResultType = .decimalAttributeType // might be another
fetchRequest.propertiesToFetch = [expression]
do {
let results = try viewContext.fetch(fetchRequest)
print(results)
} catch {
print("Failed to fetch aggregates")
}
}

How to convert datas in Swift from NSArray to Dictionary?

I need convert NSArray to Dictionary, but don't know how can I do it.
After fetch request I have result in NSArray. This my request:
var results: NSArray = []
func fetchUpdateAttendee() {
let fetchRequest = NSFetchRequest<NSFetchRequestResult>(entityName: "Attendee")
let predicate = NSPredicate(format: "needUpdate != false")
fetchRequest.predicate = predicate
results = try! DBWorker.context.fetch(fetchRequest) as NSArray
results.forEach { result in
print(result)
}
var results: NSArray = []
print(results) give me
<Attendee: 0x60c000097750> (entity: Attendee; id: 0x60c000422200 <x-coredata:///Attendee/t9E88E2EE-9258-4FAE-AF80-9B036838C6D631> ; data: {
address = "1411 E 31st St";
affiliation = "";
attendeeType = nil;
city = Aguanga;
degree = MD;
email = "";
fax = "";
firstName = Oliver1212;
fullStateLicense = "";
id = nil;
lastName = Aalami;
meeting = nil;
needUpdate = 1;
phone = "";
signature = nil;
signatureTimeStamp = nil;
specialty = Surgery;
state = CA;
stateLicense = "";
status = nil;
timeStamp = nil;
zip = 92536;
})
I need to put these datas to: let dic4Attendee: [String: Any] = [:]
This is a Core Data NSManagedObject subclass, so the code is supposed to be
var results = [Attendee]()
func fetchUpdateAttendee() {
let fetchRequest = NSFetchRequest<Attendee>(entityName: "Attendee")
let predicate = NSPredicate(format: "needUpdate == TRUE")
fetchRequest.predicate = predicate
do {
results = try DBWorker.context.fetch(fetchRequest)
results.forEach { result in
print(result)
}
} catch { print(error) }
}
never use NSArray to represent an array of NSManagedObject subclass.
Add a property dictionaryRepresentation in the Attendee class and return the key value pairs you need for example
var dictionaryRepresentation : [String:Any] {
return ["address" : address,
"affiliation" : affiliation,
"city" : city
// and so on
]
}
then map the array
let mappedArray = results.map{ $0.dictionaryRepresentation }

Condition checking on NSMutableDictionary

I have NSMutableDictionary with (key,value) pairs.For JournalId the key is "journalId".I just want to check whether my dictionary contains specific "journalId", for eg, 29. If it exists, need to print the corresponding title and userId.
eg.
{
journalId = 28;
title = Creed;
userId = 105; } {
journalId = 29;
title = Fg;
userId = 105; } {
journalId = 30;
title = Dhh;
userId = 105; }
I want to check in my dictionary whether it has journalId value = 28.
if (dictValues["journalId"] == 28){
print(dictValues["title"]
}
The above method shows error.
Thanks in advance.
guard dictValues["journalId"] as! Int == 28 else {
print("key Not found")
return // exit the function
}
let title = dictValues["title"] as! String
print("\(title)")
Try this:
if let journalId = dictValues["journalId"] as? Int, journalId == 28 {
print(dictValues["title"])
}
NSDictionary subsctiption returns an object of type AnyObject?.
This code should resolve your problem
if (dictValues["journalId"] as? Int == 28) {
print(dictValues["title"])
}

How do I property dissect/disseminate a Dictionary with an Array?

I'm trying to disseminate the response of a NSJSONSerialization:
let responseDict = NSJSONSerialization.JSONObjectWithData(data, options: NSJSONReadingOptions.MutableContainers, error: &jsonError) as NSDictionary
So far, I have a good output which I want to dissect/disseminate:
(lldb) po responseDict
{
photos = {
page = 1;
pages = 1333;
perpage = 100;
photo = (
{
farm = 4;
"height_m" = 243;
"height_s" = 117;
"height_sq" = 75;
"height_t" = 49;
id = 15148883617;
isfamily = 0;
isfriend = 0;
ispublic = 1;
owner = "48531100#N04";
secret = fb6596ca90;
server = 3926;
title = "An Exceptional Roman Orichalcum Sestertius of Nero (54-68 C.E.), a Magnificent Depiction of the Temple of Janus on the Reverse";
"url_m" = "https://farm4.staticflickr.com/3926/15148883617_fb6596ca90.jpg";
"url_s" = "https://farm4.staticflickr.com/3926/15148883617_fb6596ca90_m.jpg";
"url_sq" = "https://farm4.staticflickr.com/3926/15148883617_fb6596ca90_s.jpg";
"url_t" = "https://farm4.staticflickr.com/3926/15148883617_fb6596ca90_t.jpg";
"width_m" = 500;
"width_s" = 240;
"width_sq" = 75;
"width_t" = 100;
},
...
...
The problem is doing the dissemination.
Here's the contents of "photos" key (rather ugly compared to the ObjC counterpart):
(lldb) po responseDict["photos"]
(instance_type = Builtin.RawPointer = 0x00007fce90ec74e0 -> 0x0000000105a910e0 (void *)0x0000000105a91220: __NSDictionaryM)
{
instance_type = 0x00007fce90ec74e0 -> 0x0000000105a910e0 (void *)0x0000000105a91220: __NSDictionaryM
}
This line produces a fatal (dynamic cast) crash:
let myPhotos = responseDict["photos"] as NSArray
Here's an ObjC equivalent (that works):
jsonDict[#"photos"][#"photo"];
Compare that to the following Swift equivalent that gives me an error (even though I had downcast it to NSDictionary):
(lldb) po responseDict["photos"]["photo"]
error: <EXPR>:1:1: error: 'AnyObject?' does not have a member named 'subscript'
responseDict["photos"]["photo"]
Question: How do I properly dissect a dictionary (or any collection) in Swift as I can in Objective-C?
I managed to get down to the individual dictionary:
let myPhotos = responseDict["photos"] as? NSDictionary
let photos = myPhotos!["photo"] as? NSArray
let myPhoto:AnyObject = photos![0]
println(myPhoto)
Here's the output:
{
farm = 4;
"height_m" = 500;
"height_s" = 240;
"height_sq" = 75;
"height_t" = 100;
id = 15150188169;
isfamily = 0;
isfriend = 0;
ispublic = 1;
owner = "87355413#N02";
secret = e9cfed5225;
server = 3905;
title = "Miss 18mths wearing Music Box pinafore in grey denim (18-24mths). Trimmed with aqua/pink ric rac, and \"bow\" button.";
"url_m" = "https://farm4.staticflickr.com/3905/15150188169_e9cfed5225.jpg";
"url_s" = "https://farm4.staticflickr.com/3905/15150188169_e9cfed5225_m.jpg";
"url_sq" = "https://farm4.staticflickr.com/3905/15150188169_e9cfed5225_s.jpg";
"url_t" = "https://farm4.staticflickr.com/3905/15150188169_e9cfed5225_t.jpg";
"width_m" = 375;
"width_s" = 180;
"width_sq" = 75;
"width_t" = 75;
}
And to test it further:
let myPhoto = myPhotoInfo["url_m"] as String
Produces:
https://farm4.staticflickr.com/3920/15333895891_956d072454.jpg
From the Objective-C code that works it appears that responseDict["photos"] is not an NSArray, it is NSDictionary. This should work:
let myPhotos = responseDict["photos"] as? NSDictionary
let photo = myPhotos!["photo"]