How to add custom notification in iOS Custom Keyboard? - ios

I have added Custom Keyboard extension inside my app and running perfect.
I have added NSNotification in my keyboard extension class like this:
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(changeKeyboardColor) name:#"keyboard_color" object:nil];
Now I am calling this notification from my view controller class like this:
[[NSNotificationCenter defaultCenter] postNotificationName:#"keyboard_color" object:self];
Now I have added my notification selector method in my keyboard extension class like this:
-(void)changeKeyboardColor{
}
But it is not working. I am testing in simulator and I don't know How to test keyboard extension in simulator.
Thanks.

Create App Group from developer.apple.com
Group name must be like group.XXXXX
Enable App Group if it's disable for both app id and extension app id.
Update to existing provisioning profiles if it's look Invalid!
Go to Target and mention group name which you have created
Go to Keyboard extension and mention same group name
Now you done with all required settings.
In your project store value in NSUserDefaults
let userd: NSUserDefaults = NSUserDefaults(suiteName: "group.XXXXX")!
userd.setObject("test11", forKey: "key")
userd.synchronize()
//Objective-C
NSUserDefaults *userd = [[NSUserDefaults alloc]initWithSuiteName:#"group.XXXXX"];
[userd setObject:#"test11" forKey:#"key"];//set the object you want to share
[userd synchronize];
For retrieving NSUserDefaults value in Extension class
let userd: NSUserDefaults = NSUserDefaults(suiteName: "group.XXXXX")!
print(userd.objectForKey("key"))
// Objective-C
NSUserDefaults *userd = [[NSUserDefaults alloc]initWithSuiteName:#"group.XXXXX"];
NSLog(#"%#",[userd objectForKey:#"key"]);
Happy Coding!

The method for a notification should take a single parameter, the triggering notification:
-(void)changeKeyboardColorNotice: (NSNotification *) theNotice
{
NSLog(#"In %s", __PRETTY_FUNCTION__);
}
And you need to add a colon to the selector:
[[NSNotificationCenter defaultCenter] addObserver:self
selector: #selector(changeKeyboardColorNotice:)
name: #"keyboard_color"
object: nil];

Related

Save data from textField into a file when the application has closed or terminated

In my application has a view controller named "Home" with a textField.
I read about applicationDidEnterBackground and applicationWillTerminate methods in the AppDelegate file.
I know how to create, save, read data from a file.
My question is, How I can get an NSString from the "Home" viewController (that there store the textField data) to the AppDelegate applicationDidEnterBackground method and do there all my things with that data?
You could use NSNotificationCenter to register for a notification in your view controller that fires off whenever you enter applicationDidEnterBackground or applicationWillTerminate.
So in either of those methods you put something like
[[NSNotificationCenter defaultCenter] postNotificationName:#"someDescriptiveName" object:self userInfo:#{#"key" : #"value"}];
userInfo expects an NSDicitonary and you can pass it any type of object in there, in your case you dont need to pass anything from here back to your viewcontroller, your just using it as a means to let your view controller know the app is closing.
In your view controller you would register for that notification with something like this
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(methodToCall:) name:#"someDescriptiveName" object:nil];
Then whenever your appDelegate post that notification, your view controller which is registered to listen for it would fire off "methodToCall" which can be a method you right to do anything and it takes in an nsnotification which then lets you access the nsdicitonary its carrying.
- (void)methodToCall:(NSNotification *)notif{
NSLog(#"methodToCall fired with data %#",[[notif userInfo]valueForKey:#"key"]);}
You can do this with the help of this inside your controller:
-(id)init
{
if((self = [super init]))
{
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(appDidEnterBackground:)
name:UIApplicationDidEnterBackgroundNotification
object:[UIApplication sharedApplication]];
}
return self;
}
-(void)appDidEnterBackground:(NSNotification *)note {
NSLog(#"appDidEnterBackground");
}
you can also use applicationWillTerminate in place of UIApplicationDidEnterBackgroundNotification

Refreshing a Today extension view

I created a today extension for my iOS App. My app is fetching new datas in background and saving it into a shared database in the app group.
How I can make (if it's possible) the extension to update it's view when background fetches of the main app are performed ? If it's not possible, how I can make something equivalent (like regularly updating the extension to check for new datas in the shared database).
You can use shared NSUserDefaults and observer it.
In your app:
After you update database, execute the below:
NSUserDefaults *userDefaults = [[NSUserDefaults alloc] initWithSuiteName:#"group.yourcompany.sharedDefaults"];
[userDefaults setObject:[NSDate date] forKey:#"updatedDate"];
[userDefaults synchronize];
In your Today Widget:
add a observer in viewDidLoad:
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(userDefaultsDidChange:)
name:NSUserDefaultsDidChangeNotification
object:nil];
then
- (void)userDefaultsDidChange:(NSNotification *)notification {
// check updatedDate and update widget UI
}
refer: http://www.glimsoft.com/06/28/ios-8-today-extension-tutorial/
The system create the ViewController every time, but your singleton-instance in your today widget code keep living during a long period.

Continuously update app extension

I have created an app extension for the notification center which actually works fine except for I am not able to update its UILabel continuously. The reason I need to do this is because my app has a constantly changing data set which I want to show in the extension.
I have tried using NSUserDefaultsDidChangeNotificationfor updating the data in the extension but it's not working. Here is my code:
Registering for change notification (Extension)
- (void)viewDidLoad
{
[super viewDidLoad];
...
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(userDefaultsDidChange:)
name:NSUserDefaultsDidChangeNotification
object:nil];
}
- (void)userDefaultsDidChange:(NSNotification *)notification
{
NSUserDefaults *defaults = [[NSUserDefaults alloc] initWithSuiteName:#"group.company.app"];
//update label
}
Sending data to extension
- (void)updateData
{
NSUserDefaults *sharedDefaults = [[NSUserDefaults alloc] initWithSuiteName:#"group.company.app"];
[sharedDefaults setInteger:seconds forKey:#"seconds"];
...
[sharedDefaults synchronize];
}
I have App Groups correctly set up in both the main app and the extension who are both accessing the same group.
Does anybody know why this is not working or if there is another method to do this?
Thanks a lot!
I'm facing the same issue in my WatchKit app and NSUserDefaultsDidChangeNotification does indeed not get triggered in the extension for the shared NSUserDefaults.
The best solution I've found is a library called MMWormhole which uses
CFNotificationCenter Darwin Notifications to achieve this.

Change iOS Language without Restarting the app only with Images(around 300)

I am working on a app with 300 images(no text) and trying to change the language with button click and without restarting.
- (IBAction)changeArab:(id)sender {
NSArray* languages = [NSArray arrayWithObjects:#"en", #"fr", nil];
[[NSUserDefaults standardUserDefaults] setObject:languages forKey:#"AppleLanguages"];
}
I am able to change the language when i am restarting the app with the code above.
I localized all the images with the required language, is there anyway where i can reload the view once the language is change or change the app one the fly.
Yes, you can change it without restarting app.
You have to use NSNotificationCenter.
- (void)viewDidLoad
{
[super viewDidLoad];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(localeChanged:)
name:NSCurrentLocaleDidChangeNotification
object:nil];
}
- (void)localeChanged:(NSNotification *)notif
{
// the user changed the locale
//code to update views or data set.
}
If you have not localized your app in that way. Then Add Custom Observer to Notification Center and when user change language in your custom settings view then it will generate local notification which will be captured by application did receive notification and from that you can load all your view's again.

App does not update textfield from settings bundle but it does update settings from the app

Hi if i change the required field in the application, then log out and log into settings, the settings have been updated perfectly.
However if i then proceed to change the settings and then open the application once more the textfield has not changed.
how do i get the textfield to automatically update from the settings bundle and not just one way
this is the code i am using in the view did load
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
self.textField1.text = [defaults objectForKey:#"user_name"];
[defaults synchronize];
Answered
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(updateMytex:) name:UIApplicationWillEnterForegroundNotification object:nil];
I used notification center to call my updateMytex method.

Resources