Sunday, July 30, 2017

Local or remote user notification

To use the local or remote user notification, first you need to add the reference to the UserNotifications framework.

   @import UserNotifications;

The most important is this code before using the user notification framework - you must get the user consent

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
    
    UNUserNotificationCenter *center = [UNUserNotificationCenter currentNotificationCenter];
    center.delegate = self;

    [center requestAuthorizationWithOptions:UNAuthorizationOptionAlert | UNAuthorizationOptionBadge | UNAuthorizationOptionSound
                         completionHandler:^(BOOL granted, NSError* err) {
                             if (granted) {
                                 NSLog(@"granted notif");
                             }
                             
                         }];
    
    return YES;

}

For the "center.delegate = self" to work, you need to implement this protocol in the AppDelegate class:

    UNUserNotificationCenterDelegate

To schedule a local user notification, please use the following sample code which I found in the Internet:

- (IBAction)schedule_click:(id)sender {
    
    UNMutableNotificationContent *localNotification = [UNMutableNotificationContent new];
    localNotification.userInfo = [NSDictionary dictionaryWithObjectsAndKeys:@"User1",@"Username", nil];
    localNotification.badge = [NSNumber numberWithInt:1];
    
    localNotification.sound = [UNNotificationSound defaultSound];
    
    // load the pre-defined mp3
    //localNotification.sound = [UNNotificationSound soundNamed:@"my.mp3"];
    
    localNotification.categoryIdentifier = @"myReminder";
    localNotification.body = @"Reminder to test";
    
    NSDate *date = [[NSDate date] dateByAddingTimeInterval:60];
    
    NSCalendar *gregorian = [[NSCalendar alloc]initWithCalendarIdentifier:NSCalendarIdentifierGregorian];
    
    /*NSCalendarUnitDay – Will set the repeatInterval to daily */
    NSDateComponents *dateComponents = [gregorian components:NSCalendarUnitDay | NSCalendarUnitHour | NSCalendarUnitMinute | NSCalendarUnitTimeZone fromDate:date];
    
    UNCalendarNotificationTrigger *datetrigger = [UNCalendarNotificationTrigger triggerWithDateMatchingComponents:dateComponents repeats:YES];
    UNNotificationRequest *request = [UNNotificationRequest requestWithIdentifier:@"Some Unique Value"
                                                                          content:localNotification
                                                                          trigger:datetrigger];
    
    UNUserNotificationCenter *center = [UNUserNotificationCenter currentNotificationCenter];
    [center addNotificationRequest:request withCompletionHandler:^(NSError * _Nullable error) {
        NSLog(@"added notif. Error= %@",error);
    }];

}


Say something... text to speech in iOS

In iOS, there is a text to speech framework which is able to say the text that you have typed.

The reference that you need in order to use the text to speech classes:

    @import AVFoundation;

Sample code:

    AVSpeechSynthesizer* speaker = [[AVSpeechSynthesizer alloc] init];
    AVSpeechUtterance* u = [[AVSpeechUtterance alloc] initWithString:@"Good morning. Boss."];

    u.voice = [AVSpeechSynthesisVoice voiceWithLanguage:@"en-US"];
    

    [speaker speakUtterance:u];


To get the list of the supported languages.

    NSArray<AVSpeechSynthesisVoice *> * v  = [AVSpeechSynthesisVoice speechVoices];
    
    AVSpeechSynthesisVoice* v2;
    for (int i = 0; i < v.count; i++) {
        v2 = [v objectAtIndex:i];
        NSLog(@"voice lang id=%@, code=%@", v2.identifier, v2.language);
    }

Please take note that there is duplicate entry for the same language code. This is because it has male and female voices and the identifier to the voice is different (i.e., unique). You need to call voiceWithIentifier method instead of voiceWithLanguage.