feat: Initial clean release of CHM
一些检查失败了
automerge / automerge (push) Has been cancelled
react-native-android-build-apk / AssembleRelease (push) Has been cancelled
Build macOS M1 / Main (push) Has been cancelled
Joplin Continuous Integration / Main (macos-15-intel) (push) Has been cancelled
Joplin Continuous Integration / Main (ubuntu-22.04) (push) Has been cancelled
Joplin Continuous Integration / Main (ubuntu-22.04-arm) (push) Has been cancelled
Joplin Continuous Integration / Main (windows-11-vs2026-arm) (push) Has been cancelled
Joplin Continuous Integration / Main (windows-2025) (push) Has been cancelled
Joplin Continuous Integration / ServerDockerImage (ubuntu-22.04) (push) Has been cancelled
Joplin Continuous Integration / ServerDockerImage (ubuntu-22.04-arm) (push) Has been cancelled
Joplin UI tests / Main (ubuntu-22.04) (push) Has been cancelled
Joplin UI tests / Main (windows-2025) (push) Has been cancelled
Joplin UI tests / Mobile (push) Has been cancelled
Close stale issues / ProcessStaleIssues (push) Has been cancelled
一些检查失败了
automerge / automerge (push) Has been cancelled
react-native-android-build-apk / AssembleRelease (push) Has been cancelled
Build macOS M1 / Main (push) Has been cancelled
Joplin Continuous Integration / Main (macos-15-intel) (push) Has been cancelled
Joplin Continuous Integration / Main (ubuntu-22.04) (push) Has been cancelled
Joplin Continuous Integration / Main (ubuntu-22.04-arm) (push) Has been cancelled
Joplin Continuous Integration / Main (windows-11-vs2026-arm) (push) Has been cancelled
Joplin Continuous Integration / Main (windows-2025) (push) Has been cancelled
Joplin Continuous Integration / ServerDockerImage (ubuntu-22.04) (push) Has been cancelled
Joplin Continuous Integration / ServerDockerImage (ubuntu-22.04-arm) (push) Has been cancelled
Joplin UI tests / Main (ubuntu-22.04) (push) Has been cancelled
Joplin UI tests / Main (windows-2025) (push) Has been cancelled
Joplin UI tests / Mobile (push) Has been cancelled
Close stale issues / ProcessStaleIssues (push) Has been cancelled
这个提交包含在:
@@ -0,0 +1,9 @@
|
||||
#import <React/RCTBridgeModule.h>
|
||||
#import <React/RCTEventEmitter.h>
|
||||
|
||||
#import <UserNotifications/UserNotifications.h>
|
||||
|
||||
@interface RnAlarmNotification : RCTEventEmitter <RCTBridgeModule>
|
||||
+ (void)didReceiveNotificationResponse:(UNNotificationResponse *)response API_AVAILABLE(ios(10.0));
|
||||
+ (void)didReceiveNotification:(UNNotification *)notification API_AVAILABLE(ios(10.0));
|
||||
@end
|
||||
@@ -0,0 +1,794 @@
|
||||
#import "RnAlarmNotification.h"
|
||||
|
||||
#import <UserNotifications/UserNotifications.h>
|
||||
|
||||
#import <React/RCTBridge.h>
|
||||
#import <React/RCTConvert.h>
|
||||
#import <React/RCTEventDispatcher.h>
|
||||
#import <React/RCTUtils.h>
|
||||
#import <AudioToolbox/AudioToolbox.h>
|
||||
#import <AVFoundation/AVFoundation.h>
|
||||
|
||||
static NSString *const kLocalNotificationReceived = @"LocalNotificationReceived";
|
||||
static NSString *const kLocalNotificationDismissed = @"LocalNotificationDismissed";
|
||||
|
||||
static AVAudioPlayer *player;
|
||||
static id _sharedInstance = nil;
|
||||
|
||||
@implementation RnAlarmNotification
|
||||
|
||||
+(instancetype)sharedInstance {
|
||||
static dispatch_once_t p;
|
||||
dispatch_once(&p, ^{
|
||||
_sharedInstance = [[self alloc] init];
|
||||
});
|
||||
return _sharedInstance;
|
||||
}
|
||||
|
||||
API_AVAILABLE(ios(10.0))
|
||||
static NSDictionary *RCTFormatUNNotification(UNNotification *notification) {
|
||||
NSMutableDictionary *formattedNotification = [NSMutableDictionary dictionary];
|
||||
UNNotificationContent *content = notification.request.content;
|
||||
|
||||
formattedNotification[@"id"] = notification.request.identifier;
|
||||
formattedNotification[@"data"] = RCTNullIfNil([content.userInfo objectForKey:@"data"]);
|
||||
|
||||
return formattedNotification;
|
||||
}
|
||||
|
||||
static NSDateComponents *parseDate(NSString *dateString) {
|
||||
NSArray *fire_date = [dateString componentsSeparatedByString:@" "];
|
||||
NSString *date = fire_date[0];
|
||||
NSString *time = fire_date[1];
|
||||
|
||||
NSArray *splitDate = [date componentsSeparatedByString:@"-"];
|
||||
NSArray *splitHour = [time componentsSeparatedByString:@":"];
|
||||
|
||||
NSString *strNumDay = splitDate[0];
|
||||
NSString *strNumMonth = splitDate[1];
|
||||
NSString *strNumYear = splitDate[2];
|
||||
|
||||
NSString *strNumHour = splitHour[0];
|
||||
NSString *strNumMinute = splitHour[1];
|
||||
NSString *strNumSecond = splitHour[2];
|
||||
|
||||
// Configure the trigger for date
|
||||
NSDateComponents *fireDate = [[NSDateComponents alloc] init];
|
||||
fireDate.day = [strNumDay intValue];
|
||||
fireDate.month = [strNumMonth intValue];
|
||||
fireDate.year = [strNumYear intValue];
|
||||
fireDate.hour = [strNumHour intValue];
|
||||
fireDate.minute = [strNumMinute intValue];
|
||||
fireDate.second = [strNumSecond intValue];
|
||||
fireDate.timeZone = [NSTimeZone defaultTimeZone];
|
||||
|
||||
return fireDate;
|
||||
}
|
||||
|
||||
static NSDateComponents *dateToComponents(NSDate *date) {
|
||||
NSDateComponents *fireDate = [[NSDateComponents alloc] init];
|
||||
|
||||
NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
|
||||
|
||||
[formatter setDateFormat:@"yyyy"];
|
||||
NSString *year = [formatter stringFromDate:date];
|
||||
|
||||
[formatter setDateFormat:@"MM"];
|
||||
NSString *month = [formatter stringFromDate:date];
|
||||
|
||||
[formatter setDateFormat:@"dd"];
|
||||
NSString *day = [formatter stringFromDate:date];
|
||||
|
||||
[formatter setDateFormat:@"HH"];
|
||||
NSString *hour = [formatter stringFromDate:date];
|
||||
|
||||
[formatter setDateFormat:@"mm"];
|
||||
NSString *minute = [formatter stringFromDate:date];
|
||||
|
||||
[formatter setDateFormat:@"ss"];
|
||||
NSString *second = [formatter stringFromDate:date];
|
||||
|
||||
fireDate.day = [day intValue];
|
||||
fireDate.month = [month intValue];
|
||||
fireDate.year = [year intValue];
|
||||
fireDate.hour = [hour intValue];
|
||||
fireDate.minute = [minute intValue];
|
||||
fireDate.second = [second intValue];
|
||||
fireDate.timeZone = [NSTimeZone defaultTimeZone];
|
||||
|
||||
return fireDate;
|
||||
}
|
||||
|
||||
static NSString *stringify(NSDictionary *notification) {
|
||||
NSError *error;
|
||||
NSData *jsonData = [NSJSONSerialization dataWithJSONObject:notification options:0 error:&error];
|
||||
|
||||
if (! jsonData) {
|
||||
NSLog(@"Got an error: %@", error);
|
||||
return @"bad json";
|
||||
} else {
|
||||
NSString * jsonString = [[NSString alloc] initWithData:jsonData encoding:NSUTF8StringEncoding];
|
||||
|
||||
return jsonString;
|
||||
}
|
||||
}
|
||||
|
||||
- (dispatch_queue_t)methodQueue {
|
||||
return dispatch_get_main_queue();
|
||||
}
|
||||
|
||||
RCT_EXPORT_MODULE(RNAlarmNotification);
|
||||
|
||||
+ (void)vibratePhone {
|
||||
NSLog(@"vibratePhone %@", @"here");
|
||||
if([[UIDevice currentDevice].model isEqualToString:@"iPhone"]) {
|
||||
AudioServicesPlaySystemSound(kSystemSoundID_Vibrate);
|
||||
} else {
|
||||
AudioServicesPlayAlertSound(kSystemSoundID_Vibrate);
|
||||
}
|
||||
}
|
||||
|
||||
+ (void) didReceiveNotification:(UNNotification *)notification API_AVAILABLE(ios(10.0)){
|
||||
NSLog(@"content: %@", notification.request.content.userInfo);
|
||||
NSLog(@"alarm id: %@", notification.request.identifier);
|
||||
|
||||
NSNumber *vibrate = [notification.request.content.userInfo objectForKey:@"vibrate"];
|
||||
NSLog(@"vibrate: %@", vibrate);
|
||||
|
||||
NSNumber *sound = [notification.request.content.userInfo objectForKey:@"sound"];
|
||||
|
||||
if([vibrate isEqualToNumber: [NSNumber numberWithInt: 1]]){
|
||||
NSLog(@"do vibrate now");
|
||||
[RnAlarmNotification vibratePhone];
|
||||
}
|
||||
|
||||
if([sound isEqualToNumber: [NSNumber numberWithInt: 1]]){
|
||||
[RnAlarmNotification playSound:notification];
|
||||
}
|
||||
|
||||
NSString *scheduleType = [notification.request.content.userInfo objectForKey:@"schedule_type"];
|
||||
if([scheduleType isEqualToString:@"repeat"]){
|
||||
[RnAlarmNotification repeatAlarm:notification];
|
||||
}
|
||||
}
|
||||
|
||||
+ (void)didReceiveNotificationResponse:(UNNotificationResponse *)response
|
||||
API_AVAILABLE(ios(10.0)) {
|
||||
NSLog(@"show notification");
|
||||
[[UIApplication sharedApplication] setIdleTimerDisabled:NO];
|
||||
if ([response.notification.request.content.categoryIdentifier isEqualToString:@"CUSTOM_ACTIONS"]) {
|
||||
if ([response.actionIdentifier isEqualToString:@"SNOOZE_ACTION"]) {
|
||||
[RnAlarmNotification snoozeAlarm:response.notification];
|
||||
} else if ([response.actionIdentifier isEqualToString:@"DISMISS_ACTION"]) {
|
||||
NSLog(@"do dismiss");
|
||||
[RnAlarmNotification stopSound];
|
||||
|
||||
NSMutableDictionary *notification = [NSMutableDictionary dictionary];
|
||||
notification[@"id"] = response.notification.request.identifier;
|
||||
|
||||
[[NSNotificationCenter defaultCenter] postNotificationName:kLocalNotificationDismissed
|
||||
object:self
|
||||
userInfo:notification];
|
||||
}
|
||||
}
|
||||
|
||||
// send notification
|
||||
[[NSNotificationCenter defaultCenter] postNotificationName:kLocalNotificationReceived
|
||||
object:self
|
||||
userInfo:RCTFormatUNNotification(response.notification)];
|
||||
}
|
||||
|
||||
- (void)startObserving {
|
||||
// receive notification
|
||||
[[NSNotificationCenter defaultCenter] addObserver:self
|
||||
selector:@selector(handleLocalNotificationReceived:) name:kLocalNotificationReceived
|
||||
object:nil];
|
||||
|
||||
// dismiss notification
|
||||
[[NSNotificationCenter defaultCenter] addObserver:self
|
||||
selector:@selector(handleLocalNotificationDismissed:) name:kLocalNotificationDismissed
|
||||
object:nil];
|
||||
}
|
||||
|
||||
- (NSArray<NSString *> *)supportedEvents {
|
||||
return @[@"OnNotificationOpened", @"OnNotificationDismissed"];
|
||||
}
|
||||
|
||||
- (void)handleLocalNotificationReceived:(NSNotification *)notification {
|
||||
// send to js
|
||||
[self sendEventWithName:@"OnNotificationOpened" body: stringify(notification.userInfo)];
|
||||
}
|
||||
|
||||
- (void)handleLocalNotificationDismissed:(NSNotification *)notification {
|
||||
// send to js
|
||||
[self sendEventWithName:@"OnNotificationDismissed" body: stringify(notification.userInfo)];
|
||||
}
|
||||
|
||||
- (void)stopObserving {
|
||||
[[NSNotificationCenter defaultCenter] removeObserver:self];
|
||||
}
|
||||
|
||||
+ (void)playSound:(UNNotification *)notification API_AVAILABLE(ios(10.0)){
|
||||
@try {
|
||||
NSString *soundName = [notification.request.content.userInfo objectForKey:@"sound_name"];
|
||||
NSNumber *loopSound = [notification.request.content.userInfo objectForKey:@"loop_sound"];
|
||||
NSString *volume = [notification.request.content.userInfo objectForKey:@"volume"];
|
||||
|
||||
NSLog(@"do play sound now: %@", soundName);
|
||||
NSLog(@"loop sound: %@", loopSound);
|
||||
NSLog(@"volume sound: %@", volume);
|
||||
|
||||
// AVAudioSession *session = [AVAudioSession sharedInstance];
|
||||
// [session setCategory:AVAudioSessionCategoryPlayback
|
||||
// withOptions:AVAudioSessionCategoryOptionMixWithOthers
|
||||
// error:nil];
|
||||
// [session setActive:true error:nil];
|
||||
//[session setMode:AVAudioSessionModeDefault error:nil]; // optional
|
||||
|
||||
// NSError *playerError = nil;
|
||||
|
||||
// if([RnAlarmNotification checkStringIsNotEmpty:soundName]){
|
||||
// NSLog(@"soundName: %@", soundName);
|
||||
//
|
||||
// NSString *path = [[[NSBundle mainBundle] resourcePath] stringByAppendingPathComponent:soundName];
|
||||
//
|
||||
// NSString* soundPathEscaped = [path stringByAddingPercentEncodingWithAllowedCharacters:[NSCharacterSet URLQueryAllowedCharacterSet]];
|
||||
// NSURL *soundUri = [NSURL URLWithString:soundPathEscaped];
|
||||
//
|
||||
// NSLog(@"sound path: %@", soundUri);
|
||||
//
|
||||
// if(player){
|
||||
// [player stop];
|
||||
// player = nil;
|
||||
// }
|
||||
//
|
||||
// player = [[AVAudioPlayer alloc] initWithContentsOfURL:soundUri
|
||||
// error:&playerError];
|
||||
//
|
||||
// if(playerError) {
|
||||
// NSLog(@"[AppDelegate] audioPlayerError: %@", playerError);
|
||||
// } else if (player){
|
||||
// @synchronized(self){
|
||||
// player.delegate = (id<AVAudioPlayerDelegate>)self;;
|
||||
// player.enableRate = YES;
|
||||
// [player prepareToPlay];
|
||||
//
|
||||
// NSLog(@"sound volume: %@", RCTNullIfNil(volume));
|
||||
// // set volume
|
||||
// player.volume = [volume floatValue];
|
||||
//
|
||||
// NSLog(@"sound loop: %@", loopSound);
|
||||
// // enable/disable loop
|
||||
// if ([loopSound isEqualToNumber: [NSNumber numberWithInt: 1]]) {
|
||||
// player.numberOfLoops = -1;
|
||||
// } else {
|
||||
// player.numberOfLoops = 0;
|
||||
// }
|
||||
//
|
||||
// [player play];
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
} @catch(NSException *exception){
|
||||
NSLog(@"%@", exception.reason);
|
||||
}
|
||||
}
|
||||
|
||||
+ (void)stopSound {
|
||||
@try {
|
||||
if (player) {
|
||||
[player stop];
|
||||
player.currentTime = 0;
|
||||
}
|
||||
} @catch(NSException *exception){
|
||||
NSLog(@"%@", exception.reason);
|
||||
}
|
||||
}
|
||||
|
||||
+ (void)repeatAlarm:(UNNotification *)notification API_AVAILABLE(ios(10.0)) {
|
||||
[RnAlarmNotification stopSound];
|
||||
|
||||
@try {
|
||||
if (@available(iOS 10.0, *)) {
|
||||
UNNotificationContent *contentInfo = notification.request.content;
|
||||
UNMutableNotificationContent* content = [[UNMutableNotificationContent alloc] init];
|
||||
|
||||
content.title = contentInfo.title;
|
||||
content.body = contentInfo.body;
|
||||
|
||||
NSString *scheduleType = [contentInfo.userInfo objectForKey:@"schedule_type"];
|
||||
NSLog(@"schedule type: %@", scheduleType);
|
||||
|
||||
NSNumber *has_button = [contentInfo.userInfo objectForKey:@"has_button"];
|
||||
|
||||
// set buttons
|
||||
if([has_button isEqualToNumber: [NSNumber numberWithInt: 1]]){
|
||||
content.categoryIdentifier = @"CUSTOM_ACTIONS";
|
||||
}
|
||||
|
||||
// set alarm date
|
||||
NSString *fire_date = [contentInfo.userInfo objectForKey:@"fire_date"];
|
||||
|
||||
NSDateComponents *fireDate = parseDate(fire_date);
|
||||
|
||||
NSString *repeat_interval = [contentInfo.userInfo objectForKey:@"repeat_interval"];
|
||||
NSNumber *interval_value = [contentInfo.userInfo objectForKey:@"interval_value"];
|
||||
NSLog(@"schedule repeat interval %@", repeat_interval);
|
||||
|
||||
if([repeat_interval isEqualToString:@"minutely"]){
|
||||
fireDate.minute = fireDate.minute + [interval_value intValue];
|
||||
} else if([repeat_interval isEqualToString:@"hourly"]) {
|
||||
fireDate.hour = fireDate.hour + [interval_value intValue];
|
||||
} else if([repeat_interval isEqualToString:@"daily"]) {
|
||||
fireDate.day = fireDate.day + 1;
|
||||
} else if([repeat_interval isEqualToString:@"weekly"]) {
|
||||
fireDate.weekday = fireDate.weekday + 1;
|
||||
}
|
||||
|
||||
NSLog(@"------ next fire date: %@", fireDate);
|
||||
|
||||
// date to string
|
||||
NSCalendar *gregorianCalendar = [[NSCalendar alloc] initWithCalendarIdentifier:NSCalendarIdentifierGregorian];
|
||||
NSDate *dateString = [gregorianCalendar dateFromComponents:fireDate];
|
||||
NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
|
||||
[formatter setDateFormat:@"dd-MM-yyyy HH:mm:ss"];
|
||||
NSString *stringFromDate = [formatter stringFromDate:dateString];
|
||||
NSLog(@"%@", stringFromDate);
|
||||
|
||||
UNCalendarNotificationTrigger* trigger = [UNCalendarNotificationTrigger triggerWithDateMatchingComponents:fireDate repeats:NO];
|
||||
|
||||
// alarm id
|
||||
NSString *alarmId = [contentInfo.userInfo objectForKey:@"alarmId"];
|
||||
|
||||
NSString *soundName = [contentInfo.userInfo objectForKey:@"sound_name"];
|
||||
NSNumber *playSound = [contentInfo.userInfo objectForKey:@"sound"];
|
||||
|
||||
content.userInfo = @{
|
||||
@"alarmId": alarmId,
|
||||
@"sound": playSound,
|
||||
@"vibrate": [contentInfo.userInfo objectForKey:@"vibrate"],
|
||||
@"data": [contentInfo.userInfo objectForKey:@"data"],
|
||||
@"fire_date": stringFromDate,
|
||||
@"sound_name": soundName,
|
||||
@"loop_sound": [contentInfo.userInfo objectForKey:@"loop_sound"],
|
||||
@"volume": [contentInfo.userInfo objectForKey:@"volume"],
|
||||
@"has_button": [contentInfo.userInfo objectForKey:@"has_button"],
|
||||
@"schedule_type": [contentInfo.userInfo objectForKey:@"schedule_type"],
|
||||
@"repeat_interval": [contentInfo.userInfo objectForKey:@"repeat_interval"],
|
||||
@"interval_value": [contentInfo.userInfo objectForKey:@"interval_value"],
|
||||
@"snooze_interval": [contentInfo.userInfo objectForKey:@"snooze_interval"]
|
||||
};
|
||||
|
||||
if([playSound isEqualToNumber: [NSNumber numberWithInt: 1]]) {
|
||||
BOOL notEmpty = [RnAlarmNotification checkStringIsNotEmpty:soundName];
|
||||
if(notEmpty != YES){
|
||||
content.sound = UNNotificationSound.defaultSound;
|
||||
} else {
|
||||
content.sound = [UNNotificationSound soundNamed:soundName];
|
||||
}
|
||||
}
|
||||
|
||||
// Create the request object.
|
||||
UNNotificationRequest* request = [UNNotificationRequest requestWithIdentifier:alarmId content:content trigger:trigger];
|
||||
|
||||
UNUserNotificationCenter* center = [UNUserNotificationCenter currentNotificationCenter];
|
||||
|
||||
[center addNotificationRequest:request withCompletionHandler:^(NSError * _Nullable error) {
|
||||
if (error != nil) {
|
||||
NSLog(@"error: %@", error.localizedDescription);
|
||||
}
|
||||
}];
|
||||
|
||||
NSDictionary *alarm = [NSDictionary dictionaryWithObjectsAndKeys: alarmId, @"id", nil];
|
||||
NSLog(@"repeat alarm: %@", alarm);
|
||||
} else {
|
||||
// Fallback on earlier versions
|
||||
}
|
||||
} @catch(NSException *exception){
|
||||
NSLog(@"error: %@", exception.reason);
|
||||
}
|
||||
}
|
||||
|
||||
+ (void)snoozeAlarm:(UNNotification *)notification API_AVAILABLE(ios(10.0)) {
|
||||
NSLog(@"do snooze");
|
||||
[RnAlarmNotification stopSound];
|
||||
|
||||
@try {
|
||||
if (@available(iOS 10.0, *)) {
|
||||
UNNotificationContent *contentInfo = notification.request.content;
|
||||
UNMutableNotificationContent* content = [[UNMutableNotificationContent alloc] init];
|
||||
|
||||
content.title = contentInfo.title;
|
||||
content.body = contentInfo.body;
|
||||
|
||||
NSNumber *has_button = [contentInfo.userInfo objectForKey:@"has_button"];
|
||||
NSNumber *snooze_interval = [contentInfo.userInfo objectForKey:@"snooze_interval"];
|
||||
|
||||
// set buttons
|
||||
if([has_button isEqualToNumber: [NSNumber numberWithInt: 1]]){
|
||||
content.categoryIdentifier = @"CUSTOM_ACTIONS";
|
||||
}
|
||||
|
||||
// set alarm date
|
||||
int interval = [snooze_interval intValue];
|
||||
NSTimeInterval snoozeInterval = interval * 60;
|
||||
|
||||
NSDate *now = [NSDate date];
|
||||
NSDate *newDate = [now dateByAddingTimeInterval:snoozeInterval];
|
||||
NSLog(@"new fire date after snooze: %@", newDate);
|
||||
|
||||
NSDateComponents *newFireDate = dateToComponents(newDate);
|
||||
|
||||
UNCalendarNotificationTrigger* trigger = [UNCalendarNotificationTrigger triggerWithDateMatchingComponents:newFireDate repeats:NO];
|
||||
|
||||
NSString *alarmId = [NSString stringWithFormat: @"%ld", (long) NSDate.date.timeIntervalSince1970];
|
||||
|
||||
NSString *soundName = [contentInfo.userInfo objectForKey:@"sound_name"];
|
||||
NSNumber *playSound = [contentInfo.userInfo objectForKey:@"sound"];
|
||||
|
||||
content.userInfo = @{
|
||||
@"alarmId": alarmId,
|
||||
@"sound": playSound,
|
||||
@"vibrate": [contentInfo.userInfo objectForKey:@"vibrate"],
|
||||
@"data": [contentInfo.userInfo objectForKey:@"data"],
|
||||
@"fire_date": [contentInfo.userInfo objectForKey:@"fire_date"],
|
||||
@"sound_name": soundName,
|
||||
@"loop_sound": [contentInfo.userInfo objectForKey:@"loop_sound"],
|
||||
@"volume": [contentInfo.userInfo objectForKey:@"volume"],
|
||||
@"has_button": [contentInfo.userInfo objectForKey:@"has_button"],
|
||||
@"schedule_type": [contentInfo.userInfo objectForKey:@"schedule_type"],
|
||||
@"repeat_interval": [contentInfo.userInfo objectForKey:@"repeat_interval"],
|
||||
@"interval_value": [contentInfo.userInfo objectForKey:@"interval_value"],
|
||||
@"snooze_interval": [contentInfo.userInfo objectForKey:@"snooze_interval"]
|
||||
};
|
||||
|
||||
if([playSound isEqualToNumber: [NSNumber numberWithInt: 1]]) {
|
||||
BOOL notEmpty = [RnAlarmNotification checkStringIsNotEmpty:soundName];
|
||||
if(notEmpty != YES){
|
||||
NSLog(@"use default sound");
|
||||
content.sound = UNNotificationSound.defaultSound;
|
||||
} else {
|
||||
content.sound = [UNNotificationSound soundNamed:soundName];
|
||||
}
|
||||
}
|
||||
|
||||
// Create the request object.
|
||||
UNNotificationRequest* request = [UNNotificationRequest requestWithIdentifier:alarmId content:content trigger:trigger];
|
||||
|
||||
UNUserNotificationCenter* center = [UNUserNotificationCenter currentNotificationCenter];
|
||||
|
||||
[center addNotificationRequest:request withCompletionHandler:^(NSError * _Nullable error) {
|
||||
if (error != nil) {
|
||||
NSLog(@"error: %@", error.localizedDescription);
|
||||
}
|
||||
}];
|
||||
|
||||
NSDictionary *alarm = [NSDictionary dictionaryWithObjectsAndKeys: alarmId, @"id", nil];
|
||||
NSLog(@"snooze alarm: %@", alarm);
|
||||
} else {
|
||||
// Fallback on earlier versions
|
||||
}
|
||||
} @catch(NSException *exception){
|
||||
NSLog(@"error: %@", exception.reason);
|
||||
}
|
||||
}
|
||||
|
||||
+ (BOOL) checkStringIsNotEmpty:(NSString*)string {
|
||||
if (string == (id)[NSNull null] || string.length == 0) return NO;
|
||||
return YES;
|
||||
}
|
||||
|
||||
RCT_EXPORT_METHOD(scheduleAlarm: (NSDictionary *)details resolver:(RCTPromiseResolveBlock)resolve rejecter:(RCTPromiseRejectBlock)reject){
|
||||
@try {
|
||||
if (@available(iOS 10.0, *)) {
|
||||
UNMutableNotificationContent* content = [[UNMutableNotificationContent alloc] init];
|
||||
|
||||
content.title = [NSString localizedUserNotificationStringForKey:details[@"title"] arguments:nil];
|
||||
content.body = [NSString localizedUserNotificationStringForKey:details[@"message"] arguments:nil];
|
||||
|
||||
// set buttons
|
||||
if([details[@"has_button"] isEqualToNumber: [NSNumber numberWithInt: 1]]){
|
||||
content.categoryIdentifier = @"CUSTOM_ACTIONS";
|
||||
}
|
||||
|
||||
// set alarm date
|
||||
NSDateComponents *fireDate = parseDate(details[@"fire_date"]);
|
||||
|
||||
UNCalendarNotificationTrigger* trigger = [UNCalendarNotificationTrigger triggerWithDateMatchingComponents:fireDate repeats:NO];
|
||||
|
||||
// alarm id
|
||||
NSString *alarmId = [NSString stringWithFormat: @"%ld", (long) NSDate.date.timeIntervalSince1970];
|
||||
|
||||
NSString *volume = [details[@"volume"] stringValue];
|
||||
|
||||
content.userInfo = @{
|
||||
@"alarmId": alarmId,
|
||||
@"sound": details[@"play_sound"],
|
||||
@"vibrate": details[@"vibrate"],
|
||||
@"data": details[@"data"],
|
||||
@"fire_date": details[@"fire_date"],
|
||||
@"sound_name": details[@"sound_name"],
|
||||
@"loop_sound": details[@"loop_sound"],
|
||||
@"volume": volume,
|
||||
@"has_button": details[@"has_button"],
|
||||
@"schedule_type": details[@"schedule_type"],
|
||||
@"repeat_interval": details[@"repeat_interval"],
|
||||
@"interval_value": details[@"interval_value"],
|
||||
@"snooze_interval": details[@"snooze_interval"]
|
||||
};
|
||||
|
||||
if([details[@"play_sound"] isEqualToNumber: [NSNumber numberWithInt: 1]]) {
|
||||
BOOL notEmpty = [RnAlarmNotification checkStringIsNotEmpty:details[@"sound_name"]];
|
||||
if(notEmpty != YES){
|
||||
content.sound = UNNotificationSound.defaultSound;
|
||||
} else {
|
||||
content.sound = [UNNotificationSound soundNamed:details[@"sound_name"]];
|
||||
}
|
||||
}
|
||||
|
||||
// Create the request object.
|
||||
UNNotificationRequest* request = [UNNotificationRequest requestWithIdentifier:alarmId content:content trigger:trigger];
|
||||
|
||||
UNUserNotificationCenter* center = [UNUserNotificationCenter currentNotificationCenter];
|
||||
|
||||
[center addNotificationRequest:request withCompletionHandler:^(NSError * _Nullable error) {
|
||||
if (error != nil) {
|
||||
NSLog(@"error: %@", error.localizedDescription);
|
||||
reject(@"error", nil, error);
|
||||
}
|
||||
}];
|
||||
|
||||
NSDictionary *alarm = [NSDictionary dictionaryWithObjectsAndKeys: alarmId, @"id", nil];
|
||||
|
||||
resolve(alarm);
|
||||
} else {
|
||||
// Fallback on earlier versions
|
||||
}
|
||||
} @catch(NSException *exception){
|
||||
NSLog(@"%@", exception.reason);
|
||||
NSMutableDictionary * info = [NSMutableDictionary dictionary];
|
||||
[info setValue:exception.name forKey:@"ExceptionName"];
|
||||
[info setValue:exception.reason forKey:@"ExceptionReason"];
|
||||
[info setValue:exception.callStackSymbols forKey:@"ExceptionCallStackSymbols"];
|
||||
[info setValue:exception.userInfo forKey:@"ExceptionUserInfo"];
|
||||
|
||||
NSError *error = [[NSError alloc] initWithDomain:exception.name code:0 userInfo:info];
|
||||
reject(@"error", nil, error);
|
||||
}
|
||||
}
|
||||
|
||||
RCT_EXPORT_METHOD(sendNotification: (NSDictionary *)details) {
|
||||
@try {
|
||||
NSLog(@"send notification now");
|
||||
if (@available(iOS 10.0, *)) {
|
||||
UNMutableNotificationContent* content = [[UNMutableNotificationContent alloc] init];
|
||||
content.title = [NSString localizedUserNotificationStringForKey:details[@"title"] arguments:nil];
|
||||
content.body = [NSString localizedUserNotificationStringForKey:details[@"message"] arguments:nil];
|
||||
|
||||
// set buttons
|
||||
if([details[@"has_button"] isEqualToNumber: [NSNumber numberWithInt: 1]]){
|
||||
content.categoryIdentifier = @"CUSTOM_ACTIONS";
|
||||
}
|
||||
|
||||
// alarm id
|
||||
NSString *alarmId = [NSString stringWithFormat: @"%ld", (long) NSDate.date.timeIntervalSince1970];
|
||||
|
||||
NSString *volume = [details[@"volume"] stringValue];
|
||||
|
||||
content.userInfo = @{
|
||||
@"alarmId": alarmId,
|
||||
@"sound": details[@"play_sound"],
|
||||
@"vibrate": details[@"vibrate"],
|
||||
@"data": details[@"data"],
|
||||
@"sound_name": details[@"sound_name"],
|
||||
@"loop_sound": details[@"loop_sound"],
|
||||
@"volume": volume,
|
||||
@"schedule_type": @"once"
|
||||
};
|
||||
|
||||
if([details[@"play_sound"] isEqualToNumber: [NSNumber numberWithInt: 1]]) {
|
||||
BOOL notEmpty = [RnAlarmNotification checkStringIsNotEmpty:details[@"sound_name"]];
|
||||
if(notEmpty != YES){
|
||||
content.sound = UNNotificationSound.defaultSound;
|
||||
} else {
|
||||
content.sound = [UNNotificationSound soundNamed:details[@"sound_name"]];
|
||||
}
|
||||
}
|
||||
|
||||
// Create the request object.
|
||||
UNNotificationRequest* request = [UNNotificationRequest requestWithIdentifier:alarmId content:content trigger:nil];
|
||||
|
||||
UNUserNotificationCenter* center = [UNUserNotificationCenter currentNotificationCenter];
|
||||
|
||||
[center addNotificationRequest:request withCompletionHandler:^(NSError * _Nullable error) { }];
|
||||
} else {
|
||||
// Fallback on earlier versions
|
||||
}
|
||||
} @catch(NSException *exception){
|
||||
NSLog(@"error: %@", exception.reason);
|
||||
}
|
||||
}
|
||||
|
||||
RCT_EXPORT_METHOD(deleteAlarm: (NSInteger *)id){
|
||||
NSLog(@"delete alarm: %li", (long) id);
|
||||
if (@available(iOS 10.0, *)) {
|
||||
UNUserNotificationCenter *center = [UNUserNotificationCenter currentNotificationCenter];
|
||||
NSArray *array = [NSArray arrayWithObjects:[NSString stringWithFormat:@"%li", (long)id], nil];
|
||||
[center removePendingNotificationRequestsWithIdentifiers:array];
|
||||
} else {
|
||||
// Fallback on earlier versions
|
||||
}
|
||||
}
|
||||
|
||||
RCT_EXPORT_METHOD(deleteRepeatingAlarm: (NSInteger *)id){
|
||||
NSLog(@"delete alarm: %li", (long) id);
|
||||
if (@available(iOS 10.0, *)) {
|
||||
UNUserNotificationCenter *center = [UNUserNotificationCenter currentNotificationCenter];
|
||||
NSArray *array = [NSArray arrayWithObjects:[NSString stringWithFormat:@"%li", (long)id], nil];
|
||||
[center removePendingNotificationRequestsWithIdentifiers:array];
|
||||
} else {
|
||||
// Fallback on earlier versions
|
||||
}
|
||||
}
|
||||
|
||||
RCT_EXPORT_METHOD(stopAlarmSound){
|
||||
NSLog(@"stop alarm sound");
|
||||
[RnAlarmNotification stopSound];
|
||||
}
|
||||
|
||||
RCT_EXPORT_METHOD(removeFiredNotification: (NSInteger)id){
|
||||
NSLog(@"remove fired notification: %li", (long) id);
|
||||
if (@available(iOS 10.0, *)) {
|
||||
UNUserNotificationCenter *center = [UNUserNotificationCenter currentNotificationCenter];
|
||||
NSArray *array = [NSArray arrayWithObjects:[NSString stringWithFormat:@"%li", (long)id], nil];
|
||||
[center removeDeliveredNotificationsWithIdentifiers:array];
|
||||
} else {
|
||||
// Fallback on earlier versions
|
||||
}
|
||||
}
|
||||
|
||||
RCT_EXPORT_METHOD(removeAllFiredNotifications){
|
||||
NSLog(@"remove all notifications");
|
||||
if (@available(iOS 10.0, *)) {
|
||||
if ([UNUserNotificationCenter class]) {
|
||||
UNUserNotificationCenter *center = [UNUserNotificationCenter currentNotificationCenter];
|
||||
[center removeAllDeliveredNotifications];
|
||||
}
|
||||
} else {
|
||||
// Fallback on earlier versions
|
||||
}
|
||||
}
|
||||
|
||||
API_AVAILABLE(ios(10.0))
|
||||
static NSDictionary *RCTFormatUNNotificationRequest(UNNotificationRequest *request)
|
||||
{
|
||||
NSMutableDictionary *formattedNotification = [NSMutableDictionary dictionary];
|
||||
UNNotificationContent *content = request.content;
|
||||
|
||||
NSDateComponents *fireDate = parseDate(content.userInfo[@"fire_date"]);
|
||||
|
||||
formattedNotification[@"id"] = request.identifier;
|
||||
formattedNotification[@"day"] = [NSString stringWithFormat:@"%li", (long)fireDate.day];
|
||||
formattedNotification[@"month"] = [NSString stringWithFormat:@"%li", (long)fireDate.month];
|
||||
formattedNotification[@"year"] = [NSString stringWithFormat:@"%li", (long)fireDate.year];
|
||||
formattedNotification[@"hour"] = [NSString stringWithFormat:@"%li", (long)fireDate.hour];
|
||||
formattedNotification[@"minute"] =[NSString stringWithFormat:@"%li", (long)fireDate.minute];
|
||||
formattedNotification[@"second"] = [NSString stringWithFormat:@"%li", (long)fireDate.second];
|
||||
|
||||
return formattedNotification;
|
||||
}
|
||||
|
||||
RCT_EXPORT_METHOD(getScheduledAlarms: (RCTPromiseResolveBlock)resolve rejecter:(RCTPromiseRejectBlock)reject){
|
||||
NSLog(@"get all notifications");
|
||||
if (@available(iOS 10.0, *)) {
|
||||
UNUserNotificationCenter *center = [UNUserNotificationCenter currentNotificationCenter];
|
||||
|
||||
[center getPendingNotificationRequestsWithCompletionHandler:^(NSArray<UNNotificationRequest *> * _Nonnull requests) {
|
||||
NSLog(@"count%lu",(unsigned long)requests.count);
|
||||
|
||||
NSMutableArray<NSDictionary *> *formattedNotifications = [NSMutableArray new];
|
||||
|
||||
for (UNNotificationRequest *request in requests) {
|
||||
[formattedNotifications addObject:RCTFormatUNNotificationRequest(request)];
|
||||
}
|
||||
resolve(formattedNotifications);
|
||||
}];
|
||||
} else {
|
||||
resolve(nil);
|
||||
}
|
||||
}
|
||||
|
||||
RCT_EXPORT_METHOD(requestPermissions:(NSDictionary *)permissions
|
||||
resolver:(RCTPromiseResolveBlock)resolve
|
||||
rejecter:(RCTPromiseRejectBlock)reject) {
|
||||
if (RCTRunningInAppExtension()) {
|
||||
reject(@"E_UNABLE_TO_REQUEST_PERMISSIONS", nil, RCTErrorWithMessage(@"Requesting push notifications is currently unavailable in an app extension"));
|
||||
return;
|
||||
}
|
||||
|
||||
UIUserNotificationType types = UIUserNotificationTypeNone;
|
||||
if (permissions) {
|
||||
if ([RCTConvert BOOL:permissions[@"alert"]]) {
|
||||
types |= UIUserNotificationTypeAlert;
|
||||
}
|
||||
if ([RCTConvert BOOL:permissions[@"badge"]]) {
|
||||
types |= UIUserNotificationTypeBadge;
|
||||
}
|
||||
if ([RCTConvert BOOL:permissions[@"sound"]]) {
|
||||
types |= UIUserNotificationTypeSound;
|
||||
}
|
||||
} else {
|
||||
types = UIUserNotificationTypeAlert | UIUserNotificationTypeBadge | UIUserNotificationTypeSound;
|
||||
}
|
||||
|
||||
if (@available(iOS 10.0, *)) {
|
||||
UNNotificationCategory* generalCategory = [UNNotificationCategory
|
||||
categoryWithIdentifier:@"GENERAL"
|
||||
actions:@[]
|
||||
intentIdentifiers:@[]
|
||||
options:UNNotificationCategoryOptionCustomDismissAction];
|
||||
|
||||
UNNotificationAction* snoozeAction = [UNNotificationAction
|
||||
actionWithIdentifier:@"SNOOZE_ACTION"
|
||||
title:@"SNOOZE"
|
||||
options:UNNotificationActionOptionNone];
|
||||
|
||||
UNNotificationAction* stopAction = [UNNotificationAction
|
||||
actionWithIdentifier:@"DISMISS_ACTION"
|
||||
title:@"DISMISS"
|
||||
options:UNNotificationActionOptionForeground];
|
||||
|
||||
UNNotificationCategory* customCategory = [UNNotificationCategory
|
||||
categoryWithIdentifier:@"CUSTOM_ACTIONS"
|
||||
actions:@[snoozeAction, stopAction]
|
||||
intentIdentifiers:@[]
|
||||
options:UNNotificationCategoryOptionNone];
|
||||
|
||||
UNUserNotificationCenter* center = [UNUserNotificationCenter currentNotificationCenter];
|
||||
|
||||
[center setNotificationCategories:[NSSet setWithObjects:generalCategory, customCategory, nil]];
|
||||
|
||||
[center requestAuthorizationWithOptions:(UNAuthorizationOptionAlert + UIUserNotificationTypeBadge + UNAuthorizationOptionSound) completionHandler:^(BOOL granted, NSError *_Nullable error) {
|
||||
|
||||
if (error != NULL) {
|
||||
reject(@"-1", @"Error - Push authorization request failed.", error);
|
||||
} else {
|
||||
dispatch_async(dispatch_get_main_queue(), ^(void){
|
||||
[RCTSharedApplication() registerForRemoteNotifications];
|
||||
});
|
||||
[UNUserNotificationCenter.currentNotificationCenter getNotificationSettingsWithCompletionHandler:^(UNNotificationSettings * _Nonnull settings) {
|
||||
resolve(RCTPromiseResolveValueForUNNotificationSettings(settings));
|
||||
}];
|
||||
}
|
||||
}];
|
||||
} else {
|
||||
// Fallback on earlier versions
|
||||
resolve(nil);
|
||||
}
|
||||
}
|
||||
|
||||
RCT_EXPORT_METHOD(checkPermissions:(RCTResponseSenderBlock)callback) {
|
||||
if (RCTRunningInAppExtension()) {
|
||||
callback(@[RCTSettingsDictForUNNotificationSettings(NO, NO, NO, NO, NO)]);
|
||||
return;
|
||||
}
|
||||
|
||||
if (@available(iOS 10.0, *)) {
|
||||
[UNUserNotificationCenter.currentNotificationCenter getNotificationSettingsWithCompletionHandler:^(UNNotificationSettings * _Nonnull settings) {
|
||||
callback(@[RCTPromiseResolveValueForUNNotificationSettings(settings)]);
|
||||
}];
|
||||
} else {
|
||||
// Fallback on earlier versions
|
||||
}
|
||||
}
|
||||
|
||||
API_AVAILABLE(ios(10.0))
|
||||
static inline NSDictionary *RCTPromiseResolveValueForUNNotificationSettings(UNNotificationSettings* _Nonnull settings) {
|
||||
return RCTSettingsDictForUNNotificationSettings(settings.alertSetting == UNNotificationSettingEnabled, settings.badgeSetting == UNNotificationSettingEnabled, settings.soundSetting == UNNotificationSettingEnabled, settings.lockScreenSetting == UNNotificationSettingEnabled, settings.notificationCenterSetting == UNNotificationSettingEnabled);
|
||||
}
|
||||
|
||||
static inline NSDictionary *RCTSettingsDictForUNNotificationSettings(BOOL alert, BOOL badge, BOOL sound, BOOL lockScreen, BOOL notificationCenter) {
|
||||
return @{@"alert": @(alert), @"badge": @(badge), @"sound": @(sound), @"lockScreen": @(lockScreen), @"notificationCenter": @(notificationCenter)};
|
||||
}
|
||||
|
||||
@end
|
||||
@@ -0,0 +1,290 @@
|
||||
// !$*UTF8*$!
|
||||
{
|
||||
archiveVersion = 1;
|
||||
classes = {
|
||||
};
|
||||
objectVersion = 46;
|
||||
objects = {
|
||||
|
||||
/* Begin PBXBuildFile section */
|
||||
8D0B4EFD24DC22BA00A18E45 /* RnAlarmNotification.m in Sources */ = {isa = PBXBuildFile; fileRef = 8D0B4EFB24DC22B900A18E45 /* RnAlarmNotification.m */; };
|
||||
/* End PBXBuildFile section */
|
||||
|
||||
/* Begin PBXCopyFilesBuildPhase section */
|
||||
58B511D91A9E6C8500147676 /* CopyFiles */ = {
|
||||
isa = PBXCopyFilesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
dstPath = "include/$(PRODUCT_NAME)";
|
||||
dstSubfolderSpec = 16;
|
||||
files = (
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
/* End PBXCopyFilesBuildPhase section */
|
||||
|
||||
/* Begin PBXFileReference section */
|
||||
134814201AA4EA6300B7C361 /* libRnAlarmNotification.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libRnAlarmNotification.a; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
8D0B4EFB24DC22B900A18E45 /* RnAlarmNotification.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RnAlarmNotification.m; sourceTree = "<group>"; };
|
||||
8D0B4EFC24DC22B900A18E45 /* RnAlarmNotification.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RnAlarmNotification.h; sourceTree = "<group>"; };
|
||||
/* End PBXFileReference section */
|
||||
|
||||
/* Begin PBXFrameworksBuildPhase section */
|
||||
58B511D81A9E6C8500147676 /* Frameworks */ = {
|
||||
isa = PBXFrameworksBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
/* End PBXFrameworksBuildPhase section */
|
||||
|
||||
/* Begin PBXGroup section */
|
||||
134814211AA4EA7D00B7C361 /* Products */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
134814201AA4EA6300B7C361 /* libRnAlarmNotification.a */,
|
||||
);
|
||||
name = Products;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
58B511D21A9E6C8500147676 = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
134814211AA4EA7D00B7C361 /* Products */,
|
||||
8D0B4EFC24DC22B900A18E45 /* RnAlarmNotification.h */,
|
||||
8D0B4EFB24DC22B900A18E45 /* RnAlarmNotification.m */,
|
||||
);
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
/* End PBXGroup section */
|
||||
|
||||
/* Begin PBXNativeTarget section */
|
||||
58B511DA1A9E6C8500147676 /* RnAlarmNotification */ = {
|
||||
isa = PBXNativeTarget;
|
||||
buildConfigurationList = 58B511EF1A9E6C8500147676 /* Build configuration list for PBXNativeTarget "RnAlarmNotification" */;
|
||||
buildPhases = (
|
||||
58B511D71A9E6C8500147676 /* Sources */,
|
||||
58B511D81A9E6C8500147676 /* Frameworks */,
|
||||
58B511D91A9E6C8500147676 /* CopyFiles */,
|
||||
);
|
||||
buildRules = (
|
||||
);
|
||||
dependencies = (
|
||||
);
|
||||
name = RnAlarmNotification;
|
||||
productName = RCTDataManager;
|
||||
productReference = 134814201AA4EA6300B7C361 /* libRnAlarmNotification.a */;
|
||||
productType = "com.apple.product-type.library.static";
|
||||
};
|
||||
/* End PBXNativeTarget section */
|
||||
|
||||
/* Begin PBXProject section */
|
||||
58B511D31A9E6C8500147676 /* Project object */ = {
|
||||
isa = PBXProject;
|
||||
attributes = {
|
||||
LastUpgradeCheck = 0920;
|
||||
ORGANIZATIONNAME = Facebook;
|
||||
TargetAttributes = {
|
||||
58B511DA1A9E6C8500147676 = {
|
||||
CreatedOnToolsVersion = 6.1.1;
|
||||
};
|
||||
};
|
||||
};
|
||||
buildConfigurationList = 58B511D61A9E6C8500147676 /* Build configuration list for PBXProject "RnAlarmNotification" */;
|
||||
compatibilityVersion = "Xcode 3.2";
|
||||
developmentRegion = en;
|
||||
hasScannedForEncodings = 0;
|
||||
knownRegions = (
|
||||
en,
|
||||
Base,
|
||||
);
|
||||
mainGroup = 58B511D21A9E6C8500147676;
|
||||
productRefGroup = 58B511D21A9E6C8500147676;
|
||||
projectDirPath = "";
|
||||
projectRoot = "";
|
||||
targets = (
|
||||
58B511DA1A9E6C8500147676 /* RnAlarmNotification */,
|
||||
);
|
||||
};
|
||||
/* End PBXProject section */
|
||||
|
||||
/* Begin PBXSourcesBuildPhase section */
|
||||
58B511D71A9E6C8500147676 /* Sources */ = {
|
||||
isa = PBXSourcesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
8D0B4EFD24DC22BA00A18E45 /* RnAlarmNotification.m in Sources */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
/* End PBXSourcesBuildPhase section */
|
||||
|
||||
/* Begin XCBuildConfiguration section */
|
||||
58B511ED1A9E6C8500147676 /* Debug */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
ALWAYS_SEARCH_USER_PATHS = NO;
|
||||
CLANG_ANALYZER_NONNULL = YES;
|
||||
CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
|
||||
CLANG_CXX_LIBRARY = "libc++";
|
||||
CLANG_ENABLE_MODULES = YES;
|
||||
CLANG_ENABLE_OBJC_ARC = YES;
|
||||
CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
|
||||
CLANG_WARN_BOOL_CONVERSION = YES;
|
||||
CLANG_WARN_COMMA = YES;
|
||||
CLANG_WARN_CONSTANT_CONVERSION = YES;
|
||||
CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
|
||||
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
|
||||
CLANG_WARN_EMPTY_BODY = YES;
|
||||
CLANG_WARN_ENUM_CONVERSION = YES;
|
||||
CLANG_WARN_INFINITE_RECURSION = YES;
|
||||
CLANG_WARN_INT_CONVERSION = YES;
|
||||
CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
|
||||
CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
|
||||
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
|
||||
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
|
||||
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
|
||||
CLANG_WARN_STRICT_PROTOTYPES = YES;
|
||||
CLANG_WARN_SUSPICIOUS_MOVE = YES;
|
||||
CLANG_WARN_UNREACHABLE_CODE = YES;
|
||||
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
|
||||
COPY_PHASE_STRIP = NO;
|
||||
ENABLE_STRICT_OBJC_MSGSEND = YES;
|
||||
ENABLE_TESTABILITY = YES;
|
||||
GCC_C_LANGUAGE_STANDARD = gnu99;
|
||||
GCC_DYNAMIC_NO_PIC = NO;
|
||||
GCC_NO_COMMON_BLOCKS = YES;
|
||||
GCC_OPTIMIZATION_LEVEL = 0;
|
||||
GCC_PREPROCESSOR_DEFINITIONS = (
|
||||
"DEBUG=1",
|
||||
"$(inherited)",
|
||||
);
|
||||
GCC_SYMBOLS_PRIVATE_EXTERN = NO;
|
||||
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
|
||||
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
|
||||
GCC_WARN_UNDECLARED_SELECTOR = YES;
|
||||
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
|
||||
GCC_WARN_UNUSED_FUNCTION = YES;
|
||||
GCC_WARN_UNUSED_VARIABLE = YES;
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 9.0;
|
||||
LD_RUNPATH_SEARCH_PATHS = "/usr/lib/swift $(inherited)";
|
||||
LIBRARY_SEARCH_PATHS = (
|
||||
"\"$(TOOLCHAIN_DIR)/usr/lib/swift/$(PLATFORM_NAME)\"",
|
||||
"\"$(TOOLCHAIN_DIR)/usr/lib/swift-5.0/$(PLATFORM_NAME)\"",
|
||||
"\"$(inherited)\"",
|
||||
);
|
||||
MTL_ENABLE_DEBUG_INFO = YES;
|
||||
ONLY_ACTIVE_ARCH = YES;
|
||||
SDKROOT = iphoneos;
|
||||
};
|
||||
name = Debug;
|
||||
};
|
||||
58B511EE1A9E6C8500147676 /* Release */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
ALWAYS_SEARCH_USER_PATHS = NO;
|
||||
CLANG_ANALYZER_NONNULL = YES;
|
||||
CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
|
||||
CLANG_CXX_LIBRARY = "libc++";
|
||||
CLANG_ENABLE_MODULES = YES;
|
||||
CLANG_ENABLE_OBJC_ARC = YES;
|
||||
CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
|
||||
CLANG_WARN_BOOL_CONVERSION = YES;
|
||||
CLANG_WARN_COMMA = YES;
|
||||
CLANG_WARN_CONSTANT_CONVERSION = YES;
|
||||
CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
|
||||
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
|
||||
CLANG_WARN_EMPTY_BODY = YES;
|
||||
CLANG_WARN_ENUM_CONVERSION = YES;
|
||||
CLANG_WARN_INFINITE_RECURSION = YES;
|
||||
CLANG_WARN_INT_CONVERSION = YES;
|
||||
CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
|
||||
CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
|
||||
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
|
||||
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
|
||||
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
|
||||
CLANG_WARN_STRICT_PROTOTYPES = YES;
|
||||
CLANG_WARN_SUSPICIOUS_MOVE = YES;
|
||||
CLANG_WARN_UNREACHABLE_CODE = YES;
|
||||
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
|
||||
COPY_PHASE_STRIP = YES;
|
||||
ENABLE_NS_ASSERTIONS = NO;
|
||||
ENABLE_STRICT_OBJC_MSGSEND = YES;
|
||||
GCC_C_LANGUAGE_STANDARD = gnu99;
|
||||
GCC_NO_COMMON_BLOCKS = YES;
|
||||
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
|
||||
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
|
||||
GCC_WARN_UNDECLARED_SELECTOR = YES;
|
||||
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
|
||||
GCC_WARN_UNUSED_FUNCTION = YES;
|
||||
GCC_WARN_UNUSED_VARIABLE = YES;
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 9.0;
|
||||
LD_RUNPATH_SEARCH_PATHS = "/usr/lib/swift $(inherited)";
|
||||
LIBRARY_SEARCH_PATHS = (
|
||||
"\"$(TOOLCHAIN_DIR)/usr/lib/swift/$(PLATFORM_NAME)\"",
|
||||
"\"$(TOOLCHAIN_DIR)/usr/lib/swift-5.0/$(PLATFORM_NAME)\"",
|
||||
"\"$(inherited)\"",
|
||||
);
|
||||
MTL_ENABLE_DEBUG_INFO = NO;
|
||||
SDKROOT = iphoneos;
|
||||
VALIDATE_PRODUCT = YES;
|
||||
};
|
||||
name = Release;
|
||||
};
|
||||
58B511F01A9E6C8500147676 /* Debug */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
HEADER_SEARCH_PATHS = (
|
||||
"$(inherited)",
|
||||
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include,
|
||||
"$(SRCROOT)/../../../React/**",
|
||||
"$(SRCROOT)/../../react-native/React/**",
|
||||
);
|
||||
LIBRARY_SEARCH_PATHS = "$(inherited)";
|
||||
OTHER_LDFLAGS = "-ObjC";
|
||||
PRODUCT_NAME = RnAlarmNotification;
|
||||
SKIP_INSTALL = YES;
|
||||
};
|
||||
name = Debug;
|
||||
};
|
||||
58B511F11A9E6C8500147676 /* Release */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
HEADER_SEARCH_PATHS = (
|
||||
"$(inherited)",
|
||||
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include,
|
||||
"$(SRCROOT)/../../../React/**",
|
||||
"$(SRCROOT)/../../react-native/React/**",
|
||||
);
|
||||
LIBRARY_SEARCH_PATHS = "$(inherited)";
|
||||
OTHER_LDFLAGS = "-ObjC";
|
||||
PRODUCT_NAME = RnAlarmNotification;
|
||||
SKIP_INSTALL = YES;
|
||||
};
|
||||
name = Release;
|
||||
};
|
||||
/* End XCBuildConfiguration section */
|
||||
|
||||
/* Begin XCConfigurationList section */
|
||||
58B511D61A9E6C8500147676 /* Build configuration list for PBXProject "RnAlarmNotification" */ = {
|
||||
isa = XCConfigurationList;
|
||||
buildConfigurations = (
|
||||
58B511ED1A9E6C8500147676 /* Debug */,
|
||||
58B511EE1A9E6C8500147676 /* Release */,
|
||||
);
|
||||
defaultConfigurationIsVisible = 0;
|
||||
defaultConfigurationName = Release;
|
||||
};
|
||||
58B511EF1A9E6C8500147676 /* Build configuration list for PBXNativeTarget "RnAlarmNotification" */ = {
|
||||
isa = XCConfigurationList;
|
||||
buildConfigurations = (
|
||||
58B511F01A9E6C8500147676 /* Debug */,
|
||||
58B511F11A9E6C8500147676 /* Release */,
|
||||
);
|
||||
defaultConfigurationIsVisible = 0;
|
||||
defaultConfigurationName = Release;
|
||||
};
|
||||
/* End XCConfigurationList section */
|
||||
};
|
||||
rootObject = 58B511D31A9E6C8500147676 /* Project object */;
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<Workspace
|
||||
version = "1.0">
|
||||
<FileRef
|
||||
location = "group:RnAlarmNotification.xcodeproj">
|
||||
</FileRef>
|
||||
</Workspace>
|
||||
@@ -0,0 +1,8 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>IDEDidComputeMac32BitWarning</key>
|
||||
<true/>
|
||||
</dict>
|
||||
</plist>
|
||||
在新工单中引用
屏蔽一个用户