Reading Data from Today Extension (NSUserDefaults) works on Simulator but not in Device - nsuserdefaults

I managed to read data in a Today Extensions from the companion app with code like
NSUserDefaults *defaults = [[NSUserDefaults alloc] initWithSuiteName:#"group.cdm.TodayExtensionSharingDefaults"];
NSData *encodedObject = [defaults objectForKey:#"DataContactList"];
CV_DataContactList *object = [NSKeyedUnarchiver unarchiveObjectWithData:encodedObject];
with the corresponding writing code in the companion app
NSUserDefaults *defaults = [[NSUserDefaults alloc] initWithSuiteName:#"group.cdm.TodayExtensionSharingDefaults"];
NSData *encodedObject = [NSKeyedArchiver archivedDataWithRootObject:self];
[defaults setObject:encodedObject forKey:#"DataContactList"];
[defaults synchronize];
I created the app group and added in the Capabilities of both target (extension and companion app).
All is working fine in the simulator and data are passed as soon as the companion app changes them.
But when I run the extension on the device it cannot read any data. I got the
<Warning>: *** -[NSKeyedUnarchiver initForReadingWithData:]: data is NULL on the console log.
I tried to also generate provisioning profiles, with right appid and app group, from scratch but it didn't solve.
I appreciate any help. Thanks!

Try adding the class file where you save your data in TodayExtension target > Build Phases > Compile Sources. You have add only the .m files in it.
For example:
If the data saved file is MyData.m check if that file is presented in Target of your project and today extn target.
If this doesn't work and any of you have already found the solution please add it so it will be helpful later.

Related

iOS app localization

I want to localize my app. Should I create a new app in itunesconnect for each country or there is a way to automatically detect the country where user is? Actually my app is game based on Unity3d - is it possible to do it on Unity3d?
Before Unity starts write these lines to pass the current language into unity
NSUserDefaults* defs = [NSUserDefaults standardUserDefaults];
NSArray* languages = [defs objectForKey:#"AppleLanguages"];
NSString* preferredLang = [languages objectAtIndex:0];
[[NSUserDefaults standardUserDefaults] setObject: preferredLang forKey: #"language"];
[[NSUserDefaults standardUserDefaults] synchronize];
Definitely don't create a new app for each locale. iOS apps are localizable and iTunes Connect allows you to enter different metadata for each language.
You dont need to make a new app for each language. Try following a guide like SmoothLocalize's tutorial or This one.
Then you'll have a Localizable.strings file you need to translate. I usually use SmoothLocalize.com as my translation services, because its cheap and super easy, but you can look around for others or even try to find individual translators yourself.

creating in-app settings for iPad applications

I want to create in-app settings for my iPad application. There are different alerts for different groups, so the user can select which alerts he/she wants in the application. I am putting a custom button which will look like checkbox so when user will click it, it will be highlighted.
Can anyone tell me where can I store the settings, do I need to save settings in keychain or somewhere else? Is there any tutorial for doing that?
I've found NSUserDefaults very helpful for stuff like this. Basically you do this to store values:
NSUserDefaults* defaults= [NSUserDefaults standardUserDefaults];
[defaults setBool:yourBool forKey:#"yourBoolKey"];
[defaults setInteger:yourInteger forKey:#"yourIntegerKey"];
[defaults synchronize];
And to get values:
NSUserDefaults* defaults= [NSUserDefaults standardUserDefaults];
yourBool= [defaults boolForKey:#"yourBoolKey"];
yourInteger= [defaults integerForKey:#"yourIntegerKey"];
To have default settings when the app first launches, you could just check a bool with the key #"AppHasStoredSettings" or something like that, which will be NO the first time, set your default settings, and then set it to YES.
The best thing would probably be a plist, which, in reality is a structured XML file with keys and values, but Apple abstracts most of that for you pretty well with some nice settings tools. Here's a few things to peruse to get a handle on the idea:
NSUserDefaults
User Defaults Programming Topics
Information about property list files
Luke put some helpful code, but look at these too for more examples and ways to use all the tools available.

Reading pList through NSUserDefaults

If i have values saved in pList Files. Now can i retrieve them using
[NSUserDefaults standardUserDefaults] stringForKey:#"Field_Name"]
Taimur
The NSUserDefaults are not the same as your plist files. I am assuming that you are trying to use default settings in your app? Here is what you do
On first launch, read all the values from the plist. You can see this by looking for a flag in NSUserDefaults (see step 3)
Write default values to NSUserDefaults.
Set a flag in NSUserDefaults that the app has been opened.

saving NSUserDefaults finished

I have noticed that the saving of NSUserDefaults takes a while.
How can I check if it has finished saving?
for example I do:
NSMutableArray *uld = [NSMutableArray arrayWithArray:[[NSUserDefaults standardUserDefaults] arrayForKey:#"testdata"]];
[uld addObject:teststring];
[[NSUserDefaults standardUserDefaults] setObject:uld forKey:#"testdata"];
You normally don't have to worry about NSUserDefaults it will store changes whenever there is time, if you need to make sure a changes has been written to disk call - (BOOL) synchronise, it will return YES if the defaults were correctly written to disc.
See the NSUserDefaults reference page at Apple
Usually, the synchronize process is asynchronous and normally people don't care about when it is saved into file system. But if you want to control you can call syncrhonize method to call it synchronously.
The thing is that, the NSUserDefaults will save your data to memory, and then in some time, it will save into the file system. However, you always deal with the interface level, so the data in memory or in file system doesn't have any difference

Is it possible to load/save the whole structure of plist in setting bundle using NSUserDefaults

I know it can use NSDictionary to load and save whole plist file on iphone document directory with its structure.
But is it possible to load/save the whole structure of plist in setting bundle using NSUserDefaults?
I'm pretty sure the following works for saving arrays in NSUserDefaults so it should work fine for a NSDictionary
[[NSUserDefaults standardUserDefaults] setObject:dictionary forKey:#"Dictionary"];
Hope that helps