Error while converting nsdata to nsstring - ios

I'm trying to convert NSData to NSString
Here's my code
NSData *Data = [[NSUserDefaults standardUserDefaults] objectForKey:#"phoneNumber"];
NSString *getPhone = [NSString stringWithUTF8String:[Data bytes]];
NSLog(#"%#",getPhone);
And the error I'm getting is
-[__NSCFData rangeOfString:]: unrecognized selector sent to instance
*** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[__NSCFData rangeOfString:]: unrecognized selector sent to instance

Make the following change:
NSString getPhone = [[NSUserDefaults standardUserDefaults] objectForKey:#"phoneNumber"];
NSLog(#"%#",getPhone);
hm, strange issue. you can print out getPhone directly after set user defaults to understand if some other part of code does not modify it. [[NSUserDefaults standardUserDefaults] setObject:myPhoneString forKey:#"phoneNumber"];
So try this:
NSLog(#"%#", myPhoneString); // check current value
[[NSUserDefaults standardUserDefaults] setObject:myPhoneString forKey:#"phoneNumber"];
NSLog(#"%#", [[NSUserDefaults standardUserDefaults] objectForKey:#"phoneNumber"]) // check value after set it.
values should be the same, but also you will need to print this value in another place to test if some other code have not modified it. (I mean in place where you print it NSLog(#"%#",getPhone);)
Alos be sure that you set NSString to the NSUserDefault instead of data because as I see in your example you set NSString and output NSString as well so you don't need NSData in this your case.

NSString * getPhone = [[NSUserDefaults standardUserDefaults]
stringForKey:#"phoneNumber"];

Related

Objective-C : Can't set NSMutableDictionary from NSUserDefaults

I'm trying to retrieve an NSDictionary that was saved to NSUserDefaults. When I log out what I'm trying to retrieve, it displays correctly:
NSLog(#"%#", [[[NSUserDefaults standardUserDefaults] dictionaryForKey:#"userdetails"] mutableCopy]);
However, when I try to assign to a variable, it returns as nil.
NSMutableDictionary *test123 = [[[NSUserDefaults standardUserDefaults] dictionaryForKey:#"userdetails"] mutableCopy];
Any idea why?
Check with my working code,
Save like this,
NSData *data = [NSKeyedArchiver archivedDataWithRootObject:yourMutableDictionary];
[[NSUserDefaults standardUserDefaults] setObject:data forKey:#"currentUser"];
[[NSUserDefaults standardUserDefaults]synchronize];
Get dictionary ,
NSData *dictionaryData = [[NSUserDefaults standardUserDefaults] objectForKey:#"currentUser"];
NSDictionary *tempDict = [NSKeyedUnarchiver unarchiveObjectWithData:dictionaryData];
Maybe you can try it use the following code:
[[NSUserDefaults standardUserDefaults] setObject:(NSDictionary *)yourDictionary forKey:yourkey];

How to store JSON response in string and then store that string locally ios objective c

[enter image description here][1]I get three values from JSON. How do I store those three values in NSString and then store those strings locally i.e on the device?
I tried NSUserDefaults but I'm unable to do it. I've attached the code snippet.
NSData *JSONData = [NSJSONSerialization dataWithJSONObject:responseObject
options:0 // Pass 0 if you don't care about the readability of the generated string
error:&error];
if (! JSONData)
{
NSLog(#"Got an error: %#", error);
} else {
//_branchId = [responseObject valueForKey:#"branchId"];
_branchName = [responseObject valueForKey:#"branchName"];
_branchUri = [responseObject valueForKey:#"branchUri"];
[[NSUserDefaults standardUserDefaults] setObject:_branchId forKey:[responseObject valueForKey:_branchId]];
[[NSUserDefaults standardUserDefaults] setObject:_branchName forKey:#"branchName"];
[[NSUserDefaults standardUserDefaults] setObject:_branchUriStore forKey:#"_branchUri"]; // Here the setobject value remains nil only
[[NSUserDefaults standardUserDefaults] synchronize];
PS: I want to use that stored value in my commonutility also. How to do that as well?
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:[NSString stringWithFormat:#"(__fetchBranchUri)/%#",url]]];
In the else block replace the contents with
[[NSUserDefaults standardUserDefaults] setObject:[responseObject valueForKey:#"branchId"] forKey:#"branchId"];
[[NSUserDefaults standardUserDefaults] setObject:[responseObject valueForKey:#"branchName"] forKey:#"branchName"];
[[NSUserDefaults standardUserDefaults] setObject:[responseObject valueForKey:#"branchUri"] forKey:#"_branchUri"];
[[NSUserDefaults standardUserDefaults] synchronize];
Edit: Explanation
In your code above the object _branchUriStore is not defined, and may be part of your problem (a simple typo?). Below, I have updated and condensed your code to remove another problem with your usage of branchId and so that you might recognize from the style that much of what you were trying to do is fine.
Also note that #rmaddie has provided additional refinements below in the comments.
Okay here is what you should do.
1- convert your JSONData no NSData
2-Save your NSData in the NSUserDefaults/
Hope this helps!

'NSInvalidArgumentException', reason: '*** setObjectForKey: object cannot be nil (key: device_uid)'

I have an error when trying to run the application on my iPhone. I don't understand why I have a nil error in this case
Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: ' setObjectForKey: object cannot be nil (key: device_id)'
First throw call stack: (0x183ce0f48 0x19918bf80 0x183bcc4e0 0x10006f5f0 0x1002b9ca8 0x1002b9c68 0x1002bf710 0x183c981f8 0x183c96060 0x183bc4ca0 0x18f148088 0x1892dcffc 0x1000716a0 0x1999ce8b8)
libc++abi.dylib: terminating with uncaught exception of type NSException
Here is the part of appdelegate.m file concerned by this error :
// Get the users Device Model, Display Name, Token & Version Number
UIDevice *device = [UIDevice currentDevice];
NSUserDefaults *dict = [NSUserDefaults standardUserDefaults];
NSString *identifier = [dict stringForKey:#"identifier"];
NSString *deviceName = device.name;
NSString *deviceModel = device.model;
NSString *deviceSystemVersion = device.systemVersion;
// Prepare the Device Token for Registration (remove spaces and < >)
NSString *deviceToken = [[[[token description]
stringByReplacingOccurrencesOfString:#"<"withString:#""]
stringByReplacingOccurrencesOfString:#">" withString:#""]
stringByReplacingOccurrencesOfString: #" " withString: #""];
NSMutableDictionary *postDatas = [NSMutableDictionary dictionary];
[postDatas setObject:appName forKey:#"app_name"];
[postDatas setObject:appVersion forKey:#"app_version"];
[postDatas setObject:identifier forKey:#"device_uid"];
[postDatas setObject:deviceToken forKey:#"device_token"];
[postDatas setObject:deviceName forKey:#"device_name"];
[postDatas setObject:deviceModel forKey:#"device_model"];
[postDatas setObject:deviceSystemVersion forKey:#"device_version"];
[postDatas setObject:pushBadge forKey:#"push_badge"];
[postDatas setObject:pushAlert forKey:#"push_alert"];
[postDatas setObject:pushSound forKey:#"push_sound"];
Request *request = [Request alloc];
request.delegate = self;
[request postDatas:postDatas withUrl:#"push/iphone/registerdevice/"];
is this method deprecated?
You are getting nil in the identifier. So please check it like this
NSString *identifier = [dict stringForKey:#"identifier"];
if([identifier length] != 0)
[postDatas setObject:identifier forKey:#"device_uid"];
else
[postDatas setObject:#"" forKey:#"device_uid"];
You cannot put nil values into a dictionary. It will crash.
What you really need to investigate: Where do these nil values come from, and what is the appropriate thing to do when you get nil values? That's something only you can decide. Mukesh's answer should you how to store an empty string instead of nil. This avoids the crash. It often is the correct thing to do, but not always. So investigate what your app should do if one of the values is nil, and make it do exactly that.

Modifying NSDictionary in run Time [duplicate]

This question already has answers here:
Mutable Objects inside NSUserDefaults
(4 answers)
Closed 9 years ago.
Please Help me.
I have a plist clothingList.plist
I am accessing it like this in a method
NSString *path=[[NSBundle mainBundle] pathForResource:#"ClothingList" ofType:#"plist"];
//NSDictionary *ClothingAssets ; //Declared globally in .h file
ClothingAssets=[[NSMutableDictionary alloc]initWithContentsOfFile:path];
[[NSUserDefaults standardUserDefaults]setObject:ClothingAssets forKey:#"ClothingAssets"];
[[NSUserDefaults standardUserDefaults] synchronize];
Now I want to modfify a bool value in Clothing Assets Dictionary in another method.
ClothingAssets=[[NSUserDefaults standardUserDefaults] dictionaryForKey:#"ClothingAssets"];
[[[[[[ClothingAssets objectForKey:#"ClothingStore"] objectAtIndex:temp_Store]objectForKey:#"Assets" ]objectForKey:[NSString stringWithFormat:#"%#",temp_AssetType]] objectAtIndex:ii] setValue:#"YES" forKey:#"isLock"] ;
When I run the code For the first time it crashes and Show an error like this:
************ Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: '-[__NSCFDictionary setObject:forKey:]: mutating method sent to immutable object'***
*** First throw call stack:
(0x1fb5012 0x29c5e7e 0x1fb4deb 0x1f7b347 0x3f39bf 0x435d9 0x41f76 0xea5020 0x29d9705 0xab5920 0xab58b8 0xb76671 0xb76bcf 0xb75d38 0xae533f 0xae5552 0xac33aa 0xab4cf8 0x3397df9 0x3397ad0 0x1f2abf5 0x1f2a962 0x1f5bbb6 0x1f5af44 0x1f5ae1b 0x33967e3 0x3396668 0xab265c 0x22ed 0x2225 0x1)
libc++abi.dylib: terminate called throwing an exception******
But When I run the code for second time it is working properly.
please help me.
There are many similar questions. From the exception its evident that you are trying to include a value to an immutable dictionary.
Unwrap the values one at a time and since you are going to edit them always make a mutableCopy
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
NSMutableDictionary *clothingAssets=[[defaults dictionaryForKey:#"ClothingAssets"] mutableCopy];
NSMutableArray *clothingStores = [clothingAssets[#"ClothingStore"] mutableCopy];
NSMutableDictionary *clothingStore = [clothingStores[temp_Store] mutableCopy];
NSMutableDictionary *assets = [clothingStore[#"Assets"]mutableCopy];
NSString *assetTypesKey = [NSString stringWithFormat:#"%#",temp_AssetType];
NSMutableArray *assetTypes = [assets[assetTypesKey]mutableCopy];
NSMutableDictionary *assetType = [assetTypes[i] mutableCopy];
//Value is set
assetType[#"isLock"] = #"YES";
//Now you need to update the values back to the top most level
[assetTypes replaceObjectAtIndex:i withObject:assetType];
assets[assetTypesKey] = assetTypes ;
clothingStore[#"Assets"] = assets;
[clothingStores replaceObjectAtIndex:temp_Store withObject:clothingStore];
clothingAssets[#"ClothingStore"] = clothingStores;
[defaults setObject:clothingAssets forKey:#"ClothingAssets"];
[defaults synchronize];
Nested message sends aside, this is actually rather straightforward. When you see that error, it means you're trying to mutate an immutable object. The runtime throws a tantrum when you try to do that. Instead, do this:
ClothingAssets=[[NSUserDefaults standardUserDefaults] dictionaryForKey:#"ClothingAssets"];
NSDictionary *clothingStore = [ClothingAssets objectForKey:#"ClothingStore"];
NSArray *assets = [clothingStore objectForKey:#"Assets"];
NSDictionary *subAsset = [assets objectAtIndex: temp_Store];
NSArray *subAssetArray = [subAsset objectForKey: [NSString stringWithFormat:#"%#",temp_AssetType];
// At this point I'm afraid I run out of creative ways to describe your storage hierarchy:
NSDictionary *subAssetArraySubDictionary = [subAssetArray objectAtIndex: ii];
NSMutableDictionary *mutableCopy = [subAssetArraySubDictionary mutableCopy];
// And finally, set the value:
// Beware: This uses the string YES instead of a boolean value for YES - you need to remember this
// when accessing it later.
[mutableCopy setValue: #"YES" forKey: #"isLock"];

How to Retrive and Store NSArray from sqlite DB in iOS

I have an array itemQtyArray which i am storing in SQLITE table As:
NSData *toData = [NSKeyedArchiver archivedDataWithRootObject:self.itemQtyArray];
NSString *insertSQL = [NSString stringWithFormat: #"INSERT INTO ORDERTABLE(ITEMDESC,ITEMQTY)VALUES( \"%#\",\"%#\");",dataString2,toData];
and then i am retrieving as :
const void *itemQty = sqlite3_column_text(statement, 2);
NSInteger qtyBytes = sqlite3_column_bytes(statement, 2);
NSData *data2 = [NSData dataWithBytes:itemQty length:qtyBytes];
NSArray *myArrayFromDB = [[NSArray alloc]init];
myArrayFromDB = [NSKeyedUnarchiver unarchiveObjectWithData:data2];
[self.itemQtyArray addObjectsFromArray:myArrayFromDB];
BUt i am getting Exception at line
myArrayFromDB = [NSKeyedUnarchiver unarchiveObjectWithData:data2];
Terminating app due to uncaught exception 'NSInvalidArgumentException', reason:
'-[__NSCFData objectForKey:]: unrecognized selector sent to instance
Please tell what is wrong
NSData *toData = [NSKeyedArchiver archivedDataWithRootObject:array];
instead of this you should pass NSDictionary
NSData *toData = [NSKeyedArchiver archivedDataWithRootObject:dictionary];
or
o convert a generic array to an NSData, you need an archiver! If you know how to feed the NSData, you know how to use NSKeyedArchiver. So:
NSArray* array= ... ;
NSData* data=[NSKeyedArchiver archivedDataWithRootObject:array];
Of course all elements in your array needs to implement NSCoding protocol

Resources