Unable to save data in NSUserDefaults with crash with Signal SIGABRT - ios

I am trying to save NSData in NSUserDefaults in a loop, but I'm constantly getting an error.
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
NSString *index = [NSString stringWithFormat:#"alltweetsoftrend%d", i];
[defaults setObject:tweetData forKey:index];
[defaults synchronize];
Where i is index of the loop, it means key is not null in any case. I have also checked my NSData(tweetData) and this also is not null. I am just getting this error in saving.

There's nothing inherently wrong with your code. There's a slight chance the NSData is too large to store, but I wouldn't really expect a SIGABRT in that case. The most likely issue is that the NSData was created with [NSData dataWithBytesNoCopy:length:] and the buffer that the NSData pointed to was deallocated. There could be other issues that cause the problem as well, such as using a shared NSData global variable between threads, incorrect typecasting from CFDataRefs, etc, etc.
Try writing a different NSData and see if it works. For example:
NSData *tweetData = [NSData dataWithBytes:"Hello" length:6];. I bet that works, so the problem has to do with how your tweetData was created and sent into this code.

Related

Save char array to NSPasteBoard

I need to save unsigned char array to NSPasteBoard and then read it. How I can do it? I tried to save it to NSString, but this working only with ASCII codes.
Try this:
char myChars[] = "This is a test";
NSData *charsData = [NSData dataWithBytes:myChars length:strlen(myChars)];
[[NSPasteboard generalPasteboard] clearContents];
[[NSPasteboard generalPasteboard] setData:charsData forType:NSPasteboardTypeString];
NSData *data = [[NSPasteboard generalPasteboard] dataForType:NSPasteboardTypeString];
char myChars2[data.length];
[data getBytes:myChars2 length:data.length];
NSLog(#"%s", myChars2);
The question is a bit unclear. Do your application use pasteboard to communicate with other apps or just to store data between launches?
1. Your application needs to store binary data for itself between launches.
I suggest you to use NSUserDefaults for that purpose. As it said in docs, it's a database so you may achieve data even in next application launch.
static const NSString *kCharsDefaultsKey = #"kCharsDefaultsKey";
- (void)saveChars:(unsigned char *)chars length:(size_t)length
{
NSData *data = [NSData dataWithBytes:chars length:length];
NSUserDefaults *defaults = [NSUserDefaults standartDefaults];
[defaults setValue:data forKey:kCharsDefaultsKey];
[defaults synchronize];
}
- (void)getChars:(unsigned char *)chars length:(size_t)length
{
NSUserDefaults *defaults = [NSUserDefaults standartDefaults];
NSData *data = [default valueForKey:kCharsDefaultsKey];
if(data)
{
[data getBytes:chars];
}
}
2. Your application needs to push data between some apps.
The pasteboard-mechanism can be a way to establish this kind of communication. But I strongly recommend you to choose another way. You can't be sure there isn't another data inside the pasteboard.
- (void)someMethod
{
NSPasteboard *pasteboard = [NSPasteboard generalPasteboard];
NSArray *contents = [pasteboard readObjectsForClasses:#[[NSData class]] options: nil];
// how should you distinguish which object contains your chars and which doesn't?
}
I would rather recommend you to use NSConnection.
Also please take a look at this great article.

Where to store Dictionary data in iOS

I am developing iPhone app,i have one doubt
I have an NSMutableDictionary which contains data in this format
dict at 0th index:
"ProductId":"77386",
"ProductImage":"http://static.abcd.com/images/product/large/design_gallery_slide_green - Copy (2).jpg",
"Productshortname":"Apple iPhone 5c 16GB",
"categorycode":null,
"categoryid":8,
"categoryimage":"",
"categoryshortname":"",
"favorite":"0",
"price":"31500",
"productnameinUrl":"apple-iphone-5c-16gb",
"storecount":"10"
dict at 1st index:
"ProductId":"11386",
"ProductImage":"http://static.abcd.com/images/product/large/design_gallery_slide_green - Copy (2).jpg",
"Productshortname":"Apple iPhone 5s 16GB",
"categorycode":null,
"categoryid":8,
"categoryimage":"",
"categoryshortname":"",
"favorite":"1",
"price":"31500",
"productnameinUrl":"apple-iphone-5s-16gb",
"storecount":"18"
dict at 2nd index:
"ProductId":"31386",
"ProductImage":"http://static.abcd.com/images/product/large/design_gallery_slide_green - Copy (2).jpg",
"Productshortname":"Apple iPhone 4s 16GB",
"categorycode":null,
"categoryid":8,
"categoryimage":"",
"categoryshortname":"",
"favorite":"1",
"price":"31500",
"productnameinUrl":"apple-iphone-4s-16gb",
"storecount":"38"
and so on...
What i want to do is, i want to store this dictionary indexes some where in my directory and i want to fetch it after some time or even after closing and opening the app after few times.
where should i store this kind of data ? is there any storage for strong this kind of data?
Please help and thanks in advance !!
You can store the data in NSUserdefaults and can access any time and anywhere as you want
yourdict;//Your NSDictionary Object That contains the data to store
[[NSUserDefaults standardUserDefaults] setObject:yourdict forKey:#"dict"];
[[NSUserDefaults standardUserDefaults] synchronize];
At the time of retrieval of data,
dict = [[NSUserDefaults standardUserDefaults] objectForKey:#"dict"];
You've already chosen an approved answer but I'll throw my thoughts in anyway.
This information looks like it could get large.
The user defaults isn't designed for large chunks of data. It's really meant for small bits of information, such as boolean preferences etc etc, not to be treated as an easy-to-use database.
Some problems with the user defaults:
The defaults file is read and parsed when you launch your app, regardless of whether you need your information from it at that time or not. This is because other parts of your app also use it for storing their bits of info too.
The entire defaults file needs to be parsed in order for you to retrieve anything, even if you just want a single entry.
You don't choose when the defaults file is parsed. You can't do any smart threading if it becomes huge (say you put 1000 products in there)
I'd recommend either writing the dictionary to it's own plist using NSDictionary's writeToFile: and reading using initWithContentsOfFile: (this still suffers from point #2 above)
OR
Using CoreData/sqlite to write the information to a real database.
NSDictionary methods: https://developer.apple.com/library/mac/documentation/Cocoa/Reference/Foundation/Classes/NSDictionary_Class/Reference/Reference.html#//apple_ref/occ/instm/NSDictionary/writeToFile:atomically:
An other option (And better in my experience) is to use - NSCoder, this option is great as you can use an Object with normal properties to access your data, which make your code more readable.
You can read about it here - NSCoding / NSKeyed​Archiver by NSHipster
An here is the reference - NSCoder docs
NSDictionary has a writeToFile: method which will do it for you.
NSDicationary writeToFile:Atomically:
use NSUserDefault and save your data like this in array
Here you can use this in anyway in your application for store value of NSUserDefaults.
// --- Saving
NSUserDefaults *prefs = [NSUserDefaults standardUserDefaults];
// saving an NSString
[prefs setObject:#"TextToSave" forKey:#"keyToLookupString"];
// saving an NSInteger
[prefs setInteger:42 forKey:#"integerKey"];
// saving a Double
[prefs setDouble:3.1415 forKey:#"doubleKey"];
// saving a Float
[prefs setFloat:1.2345678 forKey:#"floatKey"];
// This is suggested to synch prefs, but is not needed (I didn't put it in my tut)
[prefs synchronize];
Here you can use this in anyway in your application for get value of NSUserDefaults.
// --- Retrieving
NSUserDefaults *prefs = [NSUserDefaults standardUserDefaults];
// getting an NSString
NSString *myString = [prefs stringForKey:#"keyToLookupString"];
// getting an NSInteger
NSInteger myInt = [prefs integerForKey:#"integerKey"];
// getting an Float
float myFloat = [prefs floatForKey:#"floatKey"];
Thanks & Cheers ..
Looks like there can be more amount of data, so the best approach is to use core data to handle this scenario.
You can check few tutorials on how to use core data - Link1 , Link2
There are advantage of using core data over NSUserDefault and file system, as those load all the data at once and you might face some issue in performance.
You can also check following links which will illustrate you performance of different mechanism used to store data - PerformanceLinks1 PerformanceLinks2
try this
NSMutableDictionary *dictionary = [NSMutableDictionary dictionaryWithObjectsAndKeys:
#"audio.caf",#"pictureAudioKey",
#"audio.m4a",#"englishAudioKey",
#"audio2.m4a",#"spanishAudioKey",
#"audio3.m4a",#"frenchAudioKey",
#"audio4.m4a",#"germanAudioKey",
#"audio5.m4a",#"italianAudioKey",
#"audio6.m4a",#"chineseAudioKey",
#"image.jpg",#"photoimagekey",
#"name.txt", #"identity",
#"imagename.txt",#"numberkey",nil];
NSArray *documentPaths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [documentPaths objectAtIndex:0];
NSString *dictionaryPath = [documentsDirectory stringByAppendingPathComponent:[[self imageNameTextField]text]];
dictionaryPath =[dictionaryPath stringByAppendingFormat:#"dicitonary" ] ;
NSDictionary *savedDictionary = dictionary;
NSLog(#"The Save file is:%#", savedDictionary);
[savedDictionary writeToFile:dictionaryPath atomically:YES];

`[NSUserDefaults standardUserDefaults]` returns nil

I want to save some user preferences, but
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
just returns nil.
iOS-Developper Library says, that this should return the existing shared defaults object or create one if none exists... What am I missing?
I also use Appirater and there all this stuff seems also not to work...
This code gets called when the user pushes a button...
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
int index = ([defaults integerForKey:#"BackgroundColorSpecifier"]+ 1)%self.backgroundColors.count;
[defaults setInteger:index forKey:#"BackgroundColorSpecifier"];
[defaults synchronize];
This gets called in application: didFinishLaunchingWithOptions:
NSUserDefaults *standardDefaults = [NSUserDefaults standardUserDefaults];
[standardDefaults registerDefaults:#{#"BackgroundColorSpecifier": #0}];
[standardDefaults synchronize];
When I debug this code snippets the green "position-indicator" jumps around in a very strange manner...
I don't have any clue, whats going on... Please help!
This is far more likely to be a problem with the debugger than anything else, particularly with your other issues. I've seen similar things in my own projects but don't have a reliable way of clearing it out other than the usual restart / clean options.
NSLogs will usually give more consistent results than the debugger if the debugger is having an off day.
NSUserDefaults isn't broken. We'd have heard about it by now.
you can use this function to log you userDefaults dic
- (void)logCache
{
NSDictionary * dic = [[NSBundle mainBundle] infoDictionary];
NSString *bundleId = [dic objectForKey: #"CFBundleIdentifier"];
NSUserDefaults *appUserDefaults = [[NSUserDefaults alloc] init];
NSDictionary *cacheDic = [appUserDefaults persistentDomainForName: bundleId];
NsLog(#"cacheDic::%#",cacheDic);
}

What else do I need to save a variable into disc?

I'me trying to save a variable into hard drive to load it on my app startup. I do the following:
paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
documentsDirectory = [paths objectAtIndex:0];
votesFile = [documentsDirectory stringByAppendingPathComponent:#"votes.dat"];
Yet, this is creating no file, at least that I can see. When I try to do this:
[votes writeToFile:votesFile atomically:YES]; //votes!=nil
and then
votes = [[NSMutableDictionary alloc] initWithContentsOfFile: votesFile];
it does nothing for me, votes == nil
What am I missing here?
If you are using a NSDictionary with NSStrings as keys, and NSNumbers as values, those classes are compatible with Archiving and Unarchiving pattern, so you can use NSUserDefaults to store your data, and load it the next time you run the application.
To save your data:
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
[defaults setObject:yourVotesDictionary forKey:aKey];
[defaults synchronize]; //This is very important when you finish saving all your data.
To load your data:
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
NSMutableDictionary *votes = [defaults objectForKey:yourNSString];
As you can see, NSUserDefaults is a dictionary, and it behaves like that.
Hope it helps,
have a good day.
There can be various errors using writeToFile:atomically: which is why it returns a BOOL. You should have something like:
if(![votes writeToFile:votesFile atomically:YES]) {
NSLog(#"An error occurred");
}
If you are getting an error there you have an issue with your NSDictionary.

How can I add core data to a utility application

Ive made a simple ios utility application in xcode (version 4.4.1) but Ive realised that I need to store one integer in persistent memory. As far as I know using core data is the best way to achieve this.
Ive added the core data framework to my app but I dont know the code that I need to add for it to work.
Could someone please help
Thanks
If you just need to store/retrieve an integer, NSUserDefaults should be the way to go.
Saving
NSUserDefaults *prefs = [NSUserDefaults standardUserDefaults];
// saving an NSInteger
[prefs setInteger:42 forKey:#"integerKey"];
// This is suggested to synch prefs, but is not needed (I didn't put it in my tut)
[prefs synchronize];
Retrieving
NSUserDefaults *prefs = [NSUserDefaults standardUserDefaults];
// getting an NSInteger
NSInteger myInt = [prefs integerForKey:#"integerKey"];
Reference:
http://www.icodeblog.com/2008/10/03/iphone-programming-tutorial-savingretrieving-data-using-nsuserdefaults/

Resources