├── index.d.ts
├── android
├── src
│ └── main
│ │ ├── assets
│ │ ├── keys.mp3
│ │ └── popcorn.mp3
│ │ ├── java
│ │ └── com
│ │ │ └── liang
│ │ │ ├── RNAlarmConstants.java
│ │ │ ├── RNAlarmPackage.java
│ │ │ ├── RNALarmCeiver.java
│ │ │ └── RNAlarmModule.java
│ │ └── AndroidManifest.xml
└── build.gradle
├── index.js
├── ios
├── RNAlarm.xcworkspace
│ └── contents.xcworkspacedata
├── RNAlarm.h
├── RNAlarm.podspec
├── RNAlarm.xcodeproj
│ └── project.pbxproj
└── RNAlarm.m
├── package.json
├── LICENSE
└── README.md
/index.d.ts:
--------------------------------------------------------------------------------
1 | import { NativeModulesStatic } from 'react-native';
2 |
3 | export declare const { RNAlarm } : NativeModulesStatic;
--------------------------------------------------------------------------------
/android/src/main/assets/keys.mp3:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/smartliang/react-native-alarm/HEAD/android/src/main/assets/keys.mp3
--------------------------------------------------------------------------------
/android/src/main/assets/popcorn.mp3:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/smartliang/react-native-alarm/HEAD/android/src/main/assets/popcorn.mp3
--------------------------------------------------------------------------------
/index.js:
--------------------------------------------------------------------------------
1 |
2 | import { NativeModules } from 'react-native';
3 |
4 | const { RNAlarm } = NativeModules;
5 |
6 | export default RNAlarm;
7 |
--------------------------------------------------------------------------------
/ios/RNAlarm.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 | // !$*UTF8*$!
2 |
3 |
5 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/ios/RNAlarm.h:
--------------------------------------------------------------------------------
1 |
2 | #if __has_include("RCTBridgeModule.h")
3 | #import "RCTBridgeModule.h"
4 | #else
5 | #import
6 | #endif
7 | @import UserNotifications;
8 | @import UIKit;
9 |
10 | @interface RNAlarm : NSObject
11 | //-(void)playSound();
12 | @end
13 |
14 |
--------------------------------------------------------------------------------
/android/src/main/java/com/liang/RNAlarmConstants.java:
--------------------------------------------------------------------------------
1 | package com.liang;
2 |
3 | /**
4 | * Created by GBLiang on 9/22/2017.
5 | */
6 |
7 | public class RNAlarmConstants {
8 | public final static String REACT_NATIVE_ALARM = "REACT_NATIVE_ALARM";
9 | public final static String REACT_NATIVE_ALARM_TITLE = "title";
10 | public final static String REACT_NATIVE_ALARM_MUSIC_URI = "musicUri";
11 | }
12 |
--------------------------------------------------------------------------------
/android/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "react-native-alarm",
3 | "version": "1.2.1",
4 | "description": "",
5 | "main": "index.js",
6 | "scripts": {
7 | "test": "echo \"Error: no test specified\" && exit 1"
8 | },
9 | "keywords": [
10 | "react-native"
11 | ],
12 | "author": "gbliang@outlook.com",
13 | "license": "MIT",
14 | "repository": {
15 | "type": "git",
16 | "url": "git+https://github.com/smartliang/react-native-alarm.git"
17 | },
18 | "peerDependencies": {
19 | "react-native": "^0.47.0"
20 | },
21 | "types": "index.d.ts"
22 | }
23 |
--------------------------------------------------------------------------------
/ios/RNAlarm.podspec:
--------------------------------------------------------------------------------
1 |
2 | Pod::Spec.new do |s|
3 | s.name = "RNAlarm"
4 | s.version = "1.0.0"
5 | s.summary = "RNAlarm"
6 | s.description = <<-DESC
7 | RNAlarm
8 | DESC
9 | s.homepage = ""
10 | s.license = "MIT"
11 | # s.license = { :type => "MIT", :file => "FILE_LICENSE" }
12 | s.author = { "author" => "author@domain.cn" }
13 | s.platform = :ios, "7.0"
14 | s.source = { :git => "https://github.com/author/RNAlarm.git", :tag => "master" }
15 | s.source_files = "RNAlarm/**/*.{h,m}"
16 | s.requires_arc = true
17 |
18 |
19 | s.dependency "React"
20 | #s.dependency "others"
21 |
22 | end
23 |
24 |
--------------------------------------------------------------------------------
/android/build.gradle:
--------------------------------------------------------------------------------
1 |
2 | buildscript {
3 | repositories {
4 | jcenter()
5 | }
6 |
7 | dependencies {
8 | classpath 'com.android.tools.build:gradle:1.3.1'
9 | }
10 | }
11 |
12 | apply plugin: 'com.android.library'
13 |
14 | android {
15 | compileSdkVersion 23
16 | buildToolsVersion "25.0.0"
17 |
18 | defaultConfig {
19 | minSdkVersion 16
20 | targetSdkVersion 22
21 | versionCode 1
22 | versionName "1.0"
23 | }
24 | lintOptions {
25 | abortOnError false
26 | }
27 | }
28 |
29 | repositories {
30 | mavenCentral()
31 | }
32 |
33 | dependencies {
34 | compile 'com.facebook.react:react-native:+'
35 | }
36 |
--------------------------------------------------------------------------------
/android/src/main/java/com/liang/RNAlarmPackage.java:
--------------------------------------------------------------------------------
1 |
2 | package com.liang;
3 |
4 | import java.util.Arrays;
5 | import java.util.Collections;
6 | import java.util.List;
7 |
8 | import com.facebook.react.ReactPackage;
9 | import com.facebook.react.bridge.NativeModule;
10 | import com.facebook.react.bridge.ReactApplicationContext;
11 | import com.facebook.react.uimanager.ViewManager;
12 | import com.facebook.react.bridge.JavaScriptModule;
13 | public class RNAlarmPackage implements ReactPackage {
14 | @Override
15 | public List createNativeModules(ReactApplicationContext reactContext) {
16 | return Arrays.asList(new RNAlarmModule(reactContext));
17 | }
18 |
19 | // Deprecated from RN 0.47
20 | public List> createJSModules() {
21 | return Collections.emptyList();
22 | }
23 |
24 | @Override
25 | public List createViewManagers(ReactApplicationContext reactContext) {
26 | return Collections.emptyList();
27 | }
28 | }
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2017 liang guo bin
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 |
2 | # react-native-alarm
3 |
4 | ## Getting started
5 |
6 | `$ npm install react-native-alarm --save`
7 |
8 | ### Mostly automatic installation
9 |
10 | `$ react-native link react-native-alarm`
11 |
12 | ### Manual installation
13 |
14 |
15 | #### iOS
16 |
17 | 1. In XCode, in the project navigator, right click `Libraries` ➜ `Add Files to [your project's name]`
18 | 2. Go to `node_modules` ➜ `react-native-alarm` and add `RNAlarm.xcodeproj`
19 | 3. In XCode, in the project navigator, select your project. Add `libRNAlarm.a` to your project's `Build Phases` ➜ `Link Binary With Libraries`
20 | 4. Run your project (`Cmd+R`)<
21 |
22 | #### Android
23 |
24 | 1. Open up `android/app/src/main/java/[...]/MainActivity.java`
25 | - Add `import com.liang.RNAlarmPackage;` to the imports at the top of the file
26 | - Add `new RNAlarmPackage()` to the list returned by the `getPackages()` method
27 | 2. Append the following lines to `android/settings.gradle`:
28 | ```
29 | include ':react-native-alarm'
30 | project(':react-native-alarm').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-alarm/android')
31 | ```
32 | 3. Insert the following lines inside the dependencies block in `android/app/build.gradle`:
33 | ```
34 | compile project(':react-native-alarm')
35 | ```
36 |
37 |
38 | ## Usage
39 | ```javascript
40 | import RNAlarm from 'react-native-alarm';
41 |
42 | // TODO: What to do with the module?
43 | RNAlarm.setAlarm('Meeting',
44 | 'Meeting with customer',
45 | '',
46 | '',
47 | () => {
48 | // Success callback function
49 | },
50 | () => {
51 | // Fail callback function
52 | });
53 | ```
54 |
55 |
--------------------------------------------------------------------------------
/android/src/main/java/com/liang/RNALarmCeiver.java:
--------------------------------------------------------------------------------
1 | package com.liang;
2 |
3 | import android.app.AlertDialog;
4 | import android.app.Notification;
5 | import android.app.NotificationManager;
6 | import android.app.PendingIntent;
7 | import android.content.BroadcastReceiver;
8 | import android.content.Context;
9 | import android.content.DialogInterface;
10 | import android.content.Intent;
11 | import android.graphics.drawable.Drawable;
12 | import android.media.MediaPlayer;
13 | import android.media.RingtoneManager;
14 | import android.net.Uri;
15 | import android.os.CountDownTimer;
16 | import android.os.Vibrator;
17 | import android.view.WindowManager;
18 | import android.widget.Toast;
19 |
20 | import com.facebook.common.util.UriUtil;
21 |
22 | import java.io.IOException;
23 |
24 | import static android.content.Context.NOTIFICATION_SERVICE;
25 |
26 | /**
27 | * Created by GBLiang on 9/22/2017.
28 | */
29 |
30 | public class RNALarmCeiver extends BroadcastReceiver {
31 |
32 | static MediaPlayer player = new MediaPlayer();
33 |
34 |
35 |
36 | @Override
37 | public void onReceive(Context context, Intent intent) {
38 |
39 | if(intent.getExtras().getBoolean("stopNotification")) {
40 | if (player.isPlaying()) {
41 | player.stop();
42 | player.reset();
43 | }
44 | }
45 | else {
46 |
47 | Uri uri;
48 | String title = intent.getStringExtra(RNAlarmConstants.REACT_NATIVE_ALARM_TITLE);
49 | String musicUri = intent.getStringExtra(RNAlarmConstants.REACT_NATIVE_ALARM_MUSIC_URI);
50 | if (musicUri == null || "".equals(musicUri)) {
51 | uri = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_ALARM);
52 | } else {
53 | uri = UriUtil.parseUriOrNull(musicUri);
54 | }
55 |
56 |
57 | //Toast.makeText(context,title,Toast.LENGTH_SHORT).show();
58 |
59 | // AlertDialog.Builder normalDialog =
60 | // new AlertDialog.Builder(context);
61 | // normalDialog.setTitle(title);
62 | // normalDialog.setNegativeButton("关闭",
63 | // new DialogInterface.OnClickListener() {
64 | // @Override
65 | // public void onClick(DialogInterface dialog, int which) {
66 | // dialog.dismiss();
67 | // player.stop();
68 | // }
69 | // });
70 | //
71 | // AlertDialog dialog = normalDialog.create();
72 | // dialog.getWindow()
73 | // .setType(WindowManager.LayoutParams.TYPE_SYSTEM_ALERT);
74 | // dialog.show();
75 |
76 | PendingIntent pi = PendingIntent.getActivity(context, 100, intent, PendingIntent.FLAG_CANCEL_CURRENT);
77 |
78 | Notification.Builder notificationBuilder = new Notification.Builder(context)
79 | .setSmallIcon(android.R.drawable.sym_def_app_icon)//设置小图标
80 | .setVibrate(new long[]{0,6000})
81 | .setContentTitle(title)
82 | .setContentText("闹钟");
83 |
84 |
85 | Notification notification = notificationBuilder.build();
86 | notificationBuilder.setDefaults(Notification.DEFAULT_ALL);
87 | notificationBuilder.setFullScreenIntent(pi, true);
88 | notificationBuilder.setDeleteIntent(createOnDismissedIntent(context));
89 | notificationBuilder.setAutoCancel(true);
90 | NotificationManager notificationManager = (NotificationManager) context.getSystemService(NOTIFICATION_SERVICE);
91 | notificationManager.notify(0, notification);
92 |
93 |
94 | try {
95 | player.setDataSource(context, uri);
96 | player.setLooping(true);
97 | player.prepareAsync();
98 | player.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
99 | @Override
100 | public void onPrepared(MediaPlayer mp) {
101 | player.start();
102 | new CountDownTimer(50000, 10000) {
103 | public void onTick(long millisUntilFinished) {
104 |
105 | }
106 |
107 | public void onFinish() {
108 | if (player.isPlaying()) {
109 | player.stop();
110 | player.reset();
111 | }
112 | }
113 | }.start();
114 | }
115 | });
116 |
117 | } catch (IOException e) {
118 | uri = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_ALARM);
119 | //e.printStackTrace();
120 | }
121 |
122 | if (musicUri != null && !"".equals(musicUri)) {
123 | try {
124 |
125 | player.setDataSource(context, uri);
126 | player.setLooping(true);
127 | player.prepareAsync();
128 | player.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
129 | @Override
130 | public void onPrepared(MediaPlayer mp) {
131 | player.start();
132 | new CountDownTimer(50000, 10000) {
133 | public void onTick(long millisUntilFinished) {
134 |
135 | }
136 |
137 | public void onFinish() {
138 | if (player.isPlaying()) {
139 | player.stop();
140 | player.reset();
141 | }
142 | }
143 | }.start();
144 | }
145 | });
146 | } catch (IOException e) {
147 | e.printStackTrace();
148 | }
149 | }
150 | }
151 | }
152 |
153 | private PendingIntent createOnDismissedIntent(Context context) {
154 | Intent intent = new Intent(RNAlarmConstants.REACT_NATIVE_ALARM);
155 | intent.putExtra("stopNotification", true);
156 | PendingIntent pendingIntent =
157 | PendingIntent.getBroadcast(context,1, intent, 0);
158 | return pendingIntent;
159 | }
160 |
161 | }
162 |
--------------------------------------------------------------------------------
/android/src/main/java/com/liang/RNAlarmModule.java:
--------------------------------------------------------------------------------
1 |
2 | package com.liang;
3 |
4 | import android.app.AlarmManager;
5 | import android.app.PendingIntent;
6 | import android.content.Context;
7 | import android.content.Intent;
8 | import android.content.SharedPreferences;
9 | import android.content.res.AssetFileDescriptor;
10 | import android.media.MediaPlayer;
11 | import android.support.annotation.Nullable;
12 | import android.support.v4.content.WakefulBroadcastReceiver;
13 | import android.text.format.DateFormat;
14 | import android.util.Log;
15 | import android.util.TimeUtils;
16 |
17 | import com.facebook.react.bridge.Promise;
18 | import com.facebook.react.bridge.ReactApplicationContext;
19 | import com.facebook.react.bridge.ReactContextBaseJavaModule;
20 | import com.facebook.react.bridge.ReactMethod;
21 | import com.facebook.react.bridge.Callback;
22 | import com.facebook.react.uimanager.IllegalViewOperationException;
23 |
24 | import java.io.Console;
25 | import java.text.SimpleDateFormat;
26 | import java.util.Calendar;
27 | import java.util.Date;
28 |
29 | import static android.R.attr.track;
30 | import static android.R.attr.type;
31 |
32 | public class RNAlarmModule extends ReactContextBaseJavaModule {
33 |
34 | private final ReactApplicationContext reactContext;
35 | private SharedPreferences sharedPreferences;
36 |
37 | public RNAlarmModule(ReactApplicationContext reactContext) {
38 | super(reactContext);
39 | this.reactContext = reactContext;
40 | this.sharedPreferences = reactContext.getSharedPreferences(getName(),Context.MODE_PRIVATE);
41 | }
42 |
43 | @Override
44 | public String getName() {
45 | return "RNAlarm";
46 | }
47 |
48 | public Boolean getAlarmStatus(String triggerTime){
49 | String value = sharedPreferences.getString(triggerTime, null);
50 | if (value == null)
51 | return null;
52 | else {
53 | return value == "error" ? false : true;
54 | }
55 | }
56 |
57 | public void setAlarm1(String triggerTime, String value){
58 | SharedPreferences.Editor editor = sharedPreferences.edit();
59 | editor.putString(triggerTime,value);
60 | editor.commit();
61 | }
62 |
63 | @ReactMethod
64 | public void playTipSound(String fileName){
65 | MediaPlayer mp = new MediaPlayer();
66 | try {
67 | if (mp.isPlaying()) {
68 | mp.stop();
69 | }
70 | if(mp!=null){
71 | mp.release();
72 | mp = new MediaPlayer();
73 | }
74 | AssetFileDescriptor descriptor = reactContext.getResources().getAssets().openFd(fileName + ".mp3");
75 | mp.setDataSource(descriptor.getFileDescriptor(), descriptor.getStartOffset(),
76 | descriptor.getLength());
77 | mp.prepare();
78 | mp.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
79 | @Override
80 | public void onPrepared(MediaPlayer mp) {
81 | mp.setLooping(false);
82 | mp.start();
83 | }
84 | });
85 | }catch(Exception ex){
86 | ex.printStackTrace();
87 | }
88 |
89 | }
90 |
91 | @ReactMethod
92 | public void initAlarm(@Nullable Callback successCallback){
93 | if(successCallback != null) {
94 | successCallback.invoke(true);
95 | }
96 | }
97 |
98 | @ReactMethod
99 | public void clearAlarm(){
100 | SharedPreferences sharedPreferences = reactContext.getSharedPreferences(getName(),Context.MODE_PRIVATE);
101 | SharedPreferences.Editor editor = sharedPreferences.edit();
102 | editor.clear();
103 | }
104 |
105 | @ReactMethod
106 | public void setAlarm(String triggerTime, String title, @Nullable String isRetry, @Nullable String musicUri, @Nullable Callback successCallback, @Nullable Callback errorCallback) {
107 | try {
108 | Boolean alarmStatus = getAlarmStatus(triggerTime);
109 | if(isRetry != null && !isRetry.isEmpty())
110 | setAlarm1(triggerTime,null);
111 |
112 | if (alarmStatus != null)
113 | {
114 | if (alarmStatus) {
115 | successCallback.invoke();
116 | return;
117 | }else {
118 | errorCallback.invoke();
119 | return;
120 | }
121 | }
122 |
123 | AlarmManager alarmManager = (AlarmManager) reactContext.getSystemService(Context.ALARM_SERVICE);
124 | Intent intent = new Intent(RNAlarmConstants.REACT_NATIVE_ALARM);
125 | intent.putExtra(RNAlarmConstants.REACT_NATIVE_ALARM_TITLE,title);
126 | intent.putExtra(RNAlarmConstants.REACT_NATIVE_ALARM_MUSIC_URI, musicUri);
127 | PendingIntent pendingIntent = PendingIntent.getBroadcast(reactContext, type, intent, PendingIntent.FLAG_UPDATE_CURRENT);
128 |
129 | SimpleDateFormat formatter = new SimpleDateFormat("dd/MM/yyyy hh:mm:ss");
130 |
131 | long triggerTimeMillis = Long.parseLong(triggerTime);
132 | Calendar originalTimeCal = Calendar.getInstance();
133 | originalTimeCal.setTimeInMillis(triggerTimeMillis);
134 | Log.w("originalTimeCal",formatter.format(originalTimeCal.getTime()));
135 |
136 | Calendar currentTimeCal = Calendar.getInstance();
137 | currentTimeCal.setTime(new Date());
138 | Log.w("currentTimeCal",formatter.format(currentTimeCal.getTime()));
139 |
140 | //compare alarm and currentTime
141 | if (triggerTimeMillis - currentTimeCal.getTimeInMillis() > 0)
142 | {
143 | Calendar calendar = Calendar.getInstance();
144 | calendar.setTimeInMillis(triggerTimeMillis);
145 | formatter.format(calendar.getTime());
146 |
147 |
148 | alarmManager.setExact(AlarmManager.RTC_WAKEUP, triggerTimeMillis, pendingIntent);
149 | setAlarm1(triggerTime,triggerTime);
150 |
151 | successCallback.invoke();
152 | return;
153 |
154 | }else {
155 | setAlarm1(triggerTime, "error");
156 | if (errorCallback != null) {
157 | // -1 闹钟时间设置不能在当前时间之前
158 | errorCallback.invoke("-1");
159 | return;
160 | }
161 | }
162 |
163 | } catch (IllegalViewOperationException e) {
164 | if(errorCallback == null ){
165 | System.out.print(e.toString());
166 | }else{
167 | setAlarm1(triggerTime,"error");
168 | errorCallback.invoke(e.getMessage());
169 | }
170 | } catch (NumberFormatException e) {
171 | if(errorCallback == null ){
172 | System.out.print(e.toString());
173 | }else{
174 | setAlarm1(triggerTime,"error");
175 | errorCallback.invoke(e.getMessage());
176 | }
177 | }
178 | }
179 |
180 | // @ReactMethod
181 | // public void setAlarm(String triggerTime, String title, @Nullable String musicUri, Promise promise) {
182 | // try {
183 | // AlarmManager alarmManager = (AlarmManager) reactContext.getSystemService(Context.ALARM_SERVICE);
184 | // Intent intent = new Intent(RNAlarmConstants.REACT_NATIVE_ALARM);
185 | // intent.putExtra(RNAlarmConstants.REACT_NATIVE_ALARM_TITLE,title);
186 | // intent.putExtra(RNAlarmConstants.REACT_NATIVE_ALARM_MUSIC_URI, musicUri);
187 | // PendingIntent pendingIntent = PendingIntent.getBroadcast(reactContext, type, intent, PendingIntent.FLAG_UPDATE_CURRENT);
188 | //
189 | // long startTime = Long.parseLong(triggerTime);
190 | // alarmManager.setExact(AlarmManager.RTC_WAKEUP, startTime, pendingIntent);
191 | // promise.resolve(0);
192 | // } catch (IllegalViewOperationException e) {
193 | // promise.reject(e);
194 | // } catch (NumberFormatException e) {
195 | // promise.reject(e);
196 | // }
197 | // }
198 | }
--------------------------------------------------------------------------------
/ios/RNAlarm.xcodeproj/project.pbxproj:
--------------------------------------------------------------------------------
1 | // !$*UTF8*$!
2 | {
3 | archiveVersion = 1;
4 | classes = {
5 | };
6 | objectVersion = 46;
7 | objects = {
8 |
9 | /* Begin PBXBuildFile section */
10 | B3E7B58A1CC2AC0600A0062D /* RNAlarm.m in Sources */ = {isa = PBXBuildFile; fileRef = B3E7B5891CC2AC0600A0062D /* RNAlarm.m */; };
11 | /* End PBXBuildFile section */
12 |
13 | /* Begin PBXCopyFilesBuildPhase section */
14 | 58B511D91A9E6C8500147676 /* CopyFiles */ = {
15 | isa = PBXCopyFilesBuildPhase;
16 | buildActionMask = 2147483647;
17 | dstPath = "include/$(PRODUCT_NAME)";
18 | dstSubfolderSpec = 16;
19 | files = (
20 | );
21 | runOnlyForDeploymentPostprocessing = 0;
22 | };
23 | /* End PBXCopyFilesBuildPhase section */
24 |
25 | /* Begin PBXFileReference section */
26 | 134814201AA4EA6300B7C361 /* libRNAlarm.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libRNAlarm.a; sourceTree = BUILT_PRODUCTS_DIR; };
27 | B3E7B5881CC2AC0600A0062D /* RNAlarm.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RNAlarm.h; sourceTree = ""; };
28 | B3E7B5891CC2AC0600A0062D /* RNAlarm.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RNAlarm.m; sourceTree = ""; };
29 | /* End PBXFileReference section */
30 |
31 | /* Begin PBXFrameworksBuildPhase section */
32 | 58B511D81A9E6C8500147676 /* Frameworks */ = {
33 | isa = PBXFrameworksBuildPhase;
34 | buildActionMask = 2147483647;
35 | files = (
36 | );
37 | runOnlyForDeploymentPostprocessing = 0;
38 | };
39 | /* End PBXFrameworksBuildPhase section */
40 |
41 | /* Begin PBXGroup section */
42 | 134814211AA4EA7D00B7C361 /* Products */ = {
43 | isa = PBXGroup;
44 | children = (
45 | 134814201AA4EA6300B7C361 /* libRNAlarm.a */,
46 | );
47 | name = Products;
48 | sourceTree = "";
49 | };
50 | 58B511D21A9E6C8500147676 = {
51 | isa = PBXGroup;
52 | children = (
53 | B3E7B5881CC2AC0600A0062D /* RNAlarm.h */,
54 | B3E7B5891CC2AC0600A0062D /* RNAlarm.m */,
55 | 134814211AA4EA7D00B7C361 /* Products */,
56 | );
57 | sourceTree = "";
58 | };
59 | /* End PBXGroup section */
60 |
61 | /* Begin PBXNativeTarget section */
62 | 58B511DA1A9E6C8500147676 /* RNAlarm */ = {
63 | isa = PBXNativeTarget;
64 | buildConfigurationList = 58B511EF1A9E6C8500147676 /* Build configuration list for PBXNativeTarget "RNAlarm" */;
65 | buildPhases = (
66 | 58B511D71A9E6C8500147676 /* Sources */,
67 | 58B511D81A9E6C8500147676 /* Frameworks */,
68 | 58B511D91A9E6C8500147676 /* CopyFiles */,
69 | );
70 | buildRules = (
71 | );
72 | dependencies = (
73 | );
74 | name = RNAlarm;
75 | productName = RCTDataManager;
76 | productReference = 134814201AA4EA6300B7C361 /* libRNAlarm.a */;
77 | productType = "com.apple.product-type.library.static";
78 | };
79 | /* End PBXNativeTarget section */
80 |
81 | /* Begin PBXProject section */
82 | 58B511D31A9E6C8500147676 /* Project object */ = {
83 | isa = PBXProject;
84 | attributes = {
85 | LastUpgradeCheck = 0830;
86 | ORGANIZATIONNAME = Facebook;
87 | TargetAttributes = {
88 | 58B511DA1A9E6C8500147676 = {
89 | CreatedOnToolsVersion = 6.1.1;
90 | };
91 | };
92 | };
93 | buildConfigurationList = 58B511D61A9E6C8500147676 /* Build configuration list for PBXProject "RNAlarm" */;
94 | compatibilityVersion = "Xcode 3.2";
95 | developmentRegion = English;
96 | hasScannedForEncodings = 0;
97 | knownRegions = (
98 | en,
99 | );
100 | mainGroup = 58B511D21A9E6C8500147676;
101 | productRefGroup = 58B511D21A9E6C8500147676;
102 | projectDirPath = "";
103 | projectRoot = "";
104 | targets = (
105 | 58B511DA1A9E6C8500147676 /* RNAlarm */,
106 | );
107 | };
108 | /* End PBXProject section */
109 |
110 | /* Begin PBXSourcesBuildPhase section */
111 | 58B511D71A9E6C8500147676 /* Sources */ = {
112 | isa = PBXSourcesBuildPhase;
113 | buildActionMask = 2147483647;
114 | files = (
115 | B3E7B58A1CC2AC0600A0062D /* RNAlarm.m in Sources */,
116 | );
117 | runOnlyForDeploymentPostprocessing = 0;
118 | };
119 | /* End PBXSourcesBuildPhase section */
120 |
121 | /* Begin XCBuildConfiguration section */
122 | 58B511ED1A9E6C8500147676 /* Debug */ = {
123 | isa = XCBuildConfiguration;
124 | buildSettings = {
125 | ALWAYS_SEARCH_USER_PATHS = NO;
126 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
127 | CLANG_CXX_LIBRARY = "libc++";
128 | CLANG_ENABLE_MODULES = YES;
129 | CLANG_ENABLE_OBJC_ARC = YES;
130 | CLANG_WARN_BOOL_CONVERSION = YES;
131 | CLANG_WARN_CONSTANT_CONVERSION = YES;
132 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
133 | CLANG_WARN_EMPTY_BODY = YES;
134 | CLANG_WARN_ENUM_CONVERSION = YES;
135 | CLANG_WARN_INFINITE_RECURSION = YES;
136 | CLANG_WARN_INT_CONVERSION = YES;
137 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
138 | CLANG_WARN_SUSPICIOUS_MOVE = YES;
139 | CLANG_WARN_UNREACHABLE_CODE = YES;
140 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
141 | COPY_PHASE_STRIP = NO;
142 | ENABLE_STRICT_OBJC_MSGSEND = YES;
143 | ENABLE_TESTABILITY = YES;
144 | GCC_C_LANGUAGE_STANDARD = gnu99;
145 | GCC_DYNAMIC_NO_PIC = NO;
146 | GCC_NO_COMMON_BLOCKS = YES;
147 | GCC_OPTIMIZATION_LEVEL = 0;
148 | GCC_PREPROCESSOR_DEFINITIONS = (
149 | "DEBUG=1",
150 | "$(inherited)",
151 | );
152 | GCC_SYMBOLS_PRIVATE_EXTERN = NO;
153 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
154 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
155 | GCC_WARN_UNDECLARED_SELECTOR = YES;
156 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
157 | GCC_WARN_UNUSED_FUNCTION = YES;
158 | GCC_WARN_UNUSED_VARIABLE = YES;
159 | IPHONEOS_DEPLOYMENT_TARGET = 8.0;
160 | MTL_ENABLE_DEBUG_INFO = YES;
161 | ONLY_ACTIVE_ARCH = YES;
162 | SDKROOT = iphoneos;
163 | };
164 | name = Debug;
165 | };
166 | 58B511EE1A9E6C8500147676 /* Release */ = {
167 | isa = XCBuildConfiguration;
168 | buildSettings = {
169 | ALWAYS_SEARCH_USER_PATHS = NO;
170 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
171 | CLANG_CXX_LIBRARY = "libc++";
172 | CLANG_ENABLE_MODULES = YES;
173 | CLANG_ENABLE_OBJC_ARC = YES;
174 | CLANG_WARN_BOOL_CONVERSION = YES;
175 | CLANG_WARN_CONSTANT_CONVERSION = YES;
176 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
177 | CLANG_WARN_EMPTY_BODY = YES;
178 | CLANG_WARN_ENUM_CONVERSION = YES;
179 | CLANG_WARN_INFINITE_RECURSION = YES;
180 | CLANG_WARN_INT_CONVERSION = YES;
181 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
182 | CLANG_WARN_SUSPICIOUS_MOVE = YES;
183 | CLANG_WARN_UNREACHABLE_CODE = YES;
184 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
185 | COPY_PHASE_STRIP = YES;
186 | ENABLE_NS_ASSERTIONS = NO;
187 | ENABLE_STRICT_OBJC_MSGSEND = YES;
188 | GCC_C_LANGUAGE_STANDARD = gnu99;
189 | GCC_NO_COMMON_BLOCKS = YES;
190 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
191 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
192 | GCC_WARN_UNDECLARED_SELECTOR = YES;
193 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
194 | GCC_WARN_UNUSED_FUNCTION = YES;
195 | GCC_WARN_UNUSED_VARIABLE = YES;
196 | IPHONEOS_DEPLOYMENT_TARGET = 8.0;
197 | MTL_ENABLE_DEBUG_INFO = NO;
198 | SDKROOT = iphoneos;
199 | VALIDATE_PRODUCT = YES;
200 | };
201 | name = Release;
202 | };
203 | 58B511F01A9E6C8500147676 /* Debug */ = {
204 | isa = XCBuildConfiguration;
205 | buildSettings = {
206 | HEADER_SEARCH_PATHS = (
207 | "$(inherited)",
208 | /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include,
209 | "$(SRCROOT)/../../../React/**",
210 | "$(SRCROOT)/../../react-native/React/**",
211 | );
212 | LIBRARY_SEARCH_PATHS = "$(inherited)";
213 | OTHER_LDFLAGS = "-ObjC";
214 | PRODUCT_NAME = RNAlarm;
215 | SKIP_INSTALL = YES;
216 | };
217 | name = Debug;
218 | };
219 | 58B511F11A9E6C8500147676 /* Release */ = {
220 | isa = XCBuildConfiguration;
221 | buildSettings = {
222 | HEADER_SEARCH_PATHS = (
223 | "$(inherited)",
224 | /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include,
225 | "$(SRCROOT)/../../../React/**",
226 | "$(SRCROOT)/../../react-native/React/**",
227 | );
228 | LIBRARY_SEARCH_PATHS = "$(inherited)";
229 | OTHER_LDFLAGS = "-ObjC";
230 | PRODUCT_NAME = RNAlarm;
231 | SKIP_INSTALL = YES;
232 | };
233 | name = Release;
234 | };
235 | /* End XCBuildConfiguration section */
236 |
237 | /* Begin XCConfigurationList section */
238 | 58B511D61A9E6C8500147676 /* Build configuration list for PBXProject "RNAlarm" */ = {
239 | isa = XCConfigurationList;
240 | buildConfigurations = (
241 | 58B511ED1A9E6C8500147676 /* Debug */,
242 | 58B511EE1A9E6C8500147676 /* Release */,
243 | );
244 | defaultConfigurationIsVisible = 0;
245 | defaultConfigurationName = Release;
246 | };
247 | 58B511EF1A9E6C8500147676 /* Build configuration list for PBXNativeTarget "RNAlarm" */ = {
248 | isa = XCConfigurationList;
249 | buildConfigurations = (
250 | 58B511F01A9E6C8500147676 /* Debug */,
251 | 58B511F11A9E6C8500147676 /* Release */,
252 | );
253 | defaultConfigurationIsVisible = 0;
254 | defaultConfigurationName = Release;
255 | };
256 | /* End XCConfigurationList section */
257 | };
258 | rootObject = 58B511D31A9E6C8500147676 /* Project object */;
259 | }
260 |
--------------------------------------------------------------------------------
/ios/RNAlarm.m:
--------------------------------------------------------------------------------
1 |
2 | #import "RNAlarm.h"
3 | #import
4 | #import
5 |
6 | @implementation RNAlarm
7 | //AVAudioPlayer *audioPlay;
8 |
9 | -(void) setAlarm: (NSString *) triggerTime andStatus: (NSString * ) status{
10 | NSUserDefaults *userDefault = [NSUserDefaults standardUserDefaults];
11 | [userDefault setObject:status forKey:triggerTime];
12 | [userDefault synchronize];
13 | }
14 |
15 |
16 | -(int) getAlarmStatus: (NSString *) triggerTime{
17 | NSUserDefaults *userDefault = [NSUserDefaults standardUserDefaults];
18 | NSString *strStatus = [userDefault objectForKey:triggerTime];
19 |
20 | if (strStatus == nil) {
21 | return -1;
22 | }else{
23 | return [strStatus isEqualToString:@"error"] ? NO : YES;
24 | }
25 | }
26 |
27 | //- (void)userNotificationCenter:(UNUserNotificationCenter *)center willPresentNotification:(UNNotification *)notification withCompletionHandler:(void (^)(UNNotificationPresentationOptions))completionHandler{
28 | // completionHandler(UNNotificationPresentationOptionAlert | UNNotificationPresentationOptionSound);
29 | // AVAudioSession *session = [AVAudioSession sharedInstance];
30 | // [session setCategory:AVAudioSessionCategoryPlayback error:nil];
31 | // [session setActive:YES error:nil];
32 | //
33 | // NSURL *fileURL = [NSURL fileURLWithPath:@"/Library/Ringtones/Constellation.m4r"];
34 | // audioPlay = [[AVAudioPlayer alloc] initWithContentsOfURL:fileURL error:nil];
35 | // audioPlay.numberOfLoops = -1;
36 | // [audioPlay play];
37 |
38 |
39 | //}
40 | -(void)userNotificationCenter:(UNUserNotificationCenter *)center willPresentNotification:(UNNotification *)notification withCompletionHandler:(void (^)(UNNotificationPresentationOptions))completionHandler{
41 |
42 | completionHandler(UNNotificationPresentationOptionAlert | UNNotificationPresentationOptionSound);
43 |
44 | AudioServicesPlayAlertSoundWithCompletion(kSystemSoundID_Vibrate, nil);
45 | }
46 |
47 | -(void)userNotificationCenter:(UNUserNotificationCenter *)center didReceiveNotificationResponse:(UNNotificationResponse *)response withCompletionHandler:(void (^)())completionHandler{
48 | // if(response.actionIdentifier == @"clear.repeat.action") {
49 |
50 | NSString *categoryIdentifier = response.notification.request.content.categoryIdentifier;
51 | NSString *identifier1 = [categoryIdentifier stringByAppendingString:@"1"];
52 | NSString *identifier2 = [categoryIdentifier stringByAppendingString:@"2"];
53 | NSString *identifier3 = [categoryIdentifier stringByAppendingString:@"3"];
54 |
55 | [center removePendingNotificationRequestsWithIdentifiers:@[identifier1,identifier2,identifier3]];
56 | [center removeDeliveredNotificationsWithIdentifiers:@[identifier1,identifier2,identifier3]];
57 | //[audioPlay stop];
58 | //[center removeAllPendingNotificationRequests];
59 | //}
60 |
61 | completionHandler();
62 | }
63 | //-(void)playSound() {
64 | //// NSString *soundFilePath = [NSString stringWithFormat:@"%@/Constellation.m4r", [[NSBundle mainBundle] resourcePath]];
65 | //// NSURL *fileURL =[[NSURL alloc] initFileURLWithPath:soundFilePath];
66 | // NSURL *from = [NSURL fileURLWithPath:@"/Library/Ringtones/Constellation.m4r"];
67 | // AVAudioPlayer *audioPlay = [[AVAudioPlayer alloc] initWithContentsOfURL:fileURL error:nil];
68 | // audioPlay.numberOfLoops = -1;
69 | // [audioPlay play];
70 | //}
71 | - (dispatch_queue_t)methodQueue
72 | {
73 | return dispatch_get_main_queue();
74 | }
75 | RCT_EXPORT_MODULE()
76 |
77 | // Thanks, AshFurrow
78 | static const unsigned componentFlags = (NSCalendarUnitYear| NSCalendarUnitMonth | NSCalendarUnitDay | NSCalendarUnitWeekday | NSCalendarUnitHour | NSCalendarUnitMinute | NSCalendarUnitSecond | NSCalendarUnitWeekday | NSCalendarUnitWeekdayOrdinal);
79 |
80 | RCT_EXPORT_METHOD(playTipSound: (NSString*) fileName){
81 |
82 | NSString *soundPath = [[NSBundle mainBundle] pathForResource:fileName ofType:@"m4r"];
83 | SystemSoundID soundID = 0;
84 | NSURL *url = [NSURL fileURLWithPath:soundPath];
85 | AudioServicesCreateSystemSoundID(CFBridgingRetain(url), &soundID);
86 | AudioServicesPlaySystemSound (soundID);
87 | }
88 |
89 | RCT_EXPORT_METHOD(clearAlarm){
90 | NSUserDefaults *userDefault = [NSUserDefaults standardUserDefaults];
91 | NSDictionary *dic = [userDefault dictionaryRepresentation];
92 | for (id key in dic) {
93 | [userDefault removeObjectForKey:key];
94 | }
95 | [userDefault synchronize];
96 | [[UIApplication sharedApplication] setApplicationIconBadgeNumber:0];
97 | [[UIApplication sharedApplication] cancelAllLocalNotifications];
98 | }
99 |
100 |
101 |
102 | RCT_EXPORT_METHOD(initAlarm: successCallback:(RCTResponseSenderBlock)callback){
103 |
104 | UNUserNotificationCenter *rCenter = UNUserNotificationCenter.currentNotificationCenter;
105 | [rCenter requestAuthorizationWithOptions:(UNAuthorizationOptionAlert | UNAuthorizationOptionSound)
106 | completionHandler:^(BOOL granted, NSError * _Nullable error){
107 | // Enable or disable based on authorization
108 | if (granted == YES) {
109 | NSArray *result = [NSArray arrayWithObjects:[NSNumber numberWithBool:NO], nil];
110 | if(successCallback != nil){
111 | result = [NSArray arrayWithObjects:[NSNumber numberWithBool:YES], nil];
112 | }
113 | callback(result);
114 | }
115 | }];
116 | }
117 |
118 | RCT_EXPORT_METHOD(setAlarm:(NSString *)triggerTime
119 | title:(NSString *)title
120 | isRetry:(NSString *)isRetry
121 | musicUri:(NSString *)musicUri
122 | successCallback:(RCTResponseSenderBlock)successCallback
123 | errorCallback:(RCTResponseSenderBlock)errorCallback){
124 | @try
125 | {
126 | // NSURL *url = [NSURL URLWithString:@"Clock-alarm:"];
127 | // if ([[UIApplication sharedApplication] canOpenURL:url]) {
128 | // [[UIApplication sharedApplication] openURL:url options:@{} completionHandler:nil];
129 | // }
130 |
131 | //得到闹钟在本机中的设置状态,-1为没有此闹钟
132 | int alarmStatus = [self getAlarmStatus:triggerTime];
133 | //强制设置闹钟,更新本机闹钟状态为nil
134 | if (isRetry != nil && ![isRetry isEqual: @""]) {
135 | [self setAlarm:triggerTime andStatus:nil];
136 | }
137 |
138 | bool isSettedAlarm = [NSNumber numberWithInt:alarmStatus].boolValue;
139 | //闹钟已经设定过了,并且是设置失败了,不再设置此闹钟,直接退出此次设置
140 | if (alarmStatus != -1)
141 | {
142 | //闹钟已经设置过了,不再重复设置
143 | if (isSettedAlarm) {
144 | NSArray *result = [NSArray arrayWithObjects:@"0", nil];
145 | if(successCallback != nil){
146 | successCallback(result);
147 | return;
148 | }
149 | }
150 | else
151 | {
152 | NSArray *result = [NSArray arrayWithObjects:@"0",nil];
153 | if(errorCallback != nil) {
154 | errorCallback(result);
155 | return;
156 | }
157 | }
158 | }
159 |
160 | UNUserNotificationCenter *rCenter = UNUserNotificationCenter.currentNotificationCenter;
161 | [rCenter requestAuthorizationWithOptions:(UNAuthorizationOptionAlert | UNAuthorizationOptionSound)
162 | completionHandler:^(BOOL granted, NSError * _Nullable error){
163 | // Enable or disable based on authorization
164 | }];
165 |
166 |
167 | UNMutableNotificationContent *content = [[UNMutableNotificationContent alloc] init];
168 | //content.title = [NSString localizedUserNotificationStringForKey:@"RNALarm" arguments:nil];
169 | content.body = [NSString localizedUserNotificationStringForKey:title arguments:nil];
170 | //content.categoryIdentifier = @"RNAlarmCategory";
171 | content.categoryIdentifier = triggerTime;
172 |
173 | musicUri = @"Constellation.m4r";
174 | if(musicUri == nil) {
175 | content.sound = [UNNotificationSound defaultSound];
176 | }else {
177 | NSFileManager *fileManage = NSFileManager.defaultManager;
178 |
179 | NSURL *libraryUrl = [[fileManage URLsForDirectory:NSLibraryDirectory inDomains:NSUserDomainMask] objectAtIndex:0];
180 | NSURL *soundDirUrl = [libraryUrl URLByAppendingPathComponent:@"Sounds"];
181 | [fileManage createDirectoryAtURL:soundDirUrl withIntermediateDirectories:TRUE attributes:nil error:nil];
182 |
183 | NSURL *from = [NSURL fileURLWithPath:@"/Library/Ringtones/Constellation.m4r"];
184 | NSURL *dest = [soundDirUrl URLByAppendingPathComponent:musicUri];
185 | [fileManage copyItemAtURL:from toURL:dest error:nil];
186 |
187 | content.sound = [UNNotificationSound soundNamed:musicUri];
188 | }
189 | // NSTimeInterval time =[triggerTime doubleValue];
190 | //
191 | // NSDate *tgTime = [NSDate dateWithTimeIntervalSinceNow:time];
192 |
193 |
194 |
195 | // NSCalendar *gregorian = [[NSCalendar alloc] initWithCalendarIdentifier:NSCalendarIdentifierGregorian];
196 | // NSDateComponents *components =[gregorian components:componentFlags fromDate:tgTime];
197 | //
198 | // UNCalendarNotificationTrigger *trigger1 = [UNCalendarNotificationTrigger triggerWithDateMatchingComponents:components repeats:NO];
199 |
200 | // current date
201 | NSDate *date = [NSDate date];
202 | double nowSeconds = [date timeIntervalSince1970];
203 |
204 | double startDate =[triggerTime doubleValue];
205 |
206 | double intervalSeconds = startDate/1000 - nowSeconds;
207 | //NSTimeInterval time =[triggerTime doubleValue];
208 | if (intervalSeconds > 0) {
209 |
210 | //for (int i=0; i<3; i++) {
211 | UNTimeIntervalNotificationTrigger *trigger = [UNTimeIntervalNotificationTrigger triggerWithTimeInterval:intervalSeconds repeats:NO];
212 |
213 | UNNotificationRequest *request = [UNNotificationRequest requestWithIdentifier: [triggerTime stringByAppendingString: @"1"] content:content trigger:trigger];
214 |
215 | UNUserNotificationCenter *center = [UNUserNotificationCenter currentNotificationCenter];
216 |
217 | //NSArray *actionOption = [NSArray arrayWithObject:@"actionOption"];
218 |
219 | UNNotificationAction *action = [UNNotificationAction
220 | actionWithIdentifier:@"clear.repeat.action"
221 | title:@"关闭"
222 | options:UNNotificationActionOptionForeground];
223 | UNNotificationCategory *category = [UNNotificationCategory
224 | //categoryWithIdentifier:@"RNAlarmCategory"
225 | categoryWithIdentifier:triggerTime
226 | actions:@[action]
227 | intentIdentifiers:@[]
228 | options:UNNotificationCategoryOptionCustomDismissAction];
229 |
230 | [center setNotificationCategories: [NSSet setWithObjects:category, nil]];
231 | [center addNotificationRequest:request withCompletionHandler:^(NSError * _Nullable error) {
232 | if(error != nil)
233 | {
234 | // NSLog(error.localizedDescription);
235 | @throw error;
236 | }
237 | }];
238 |
239 | center.delegate = self;
240 | //intervalSeconds += 60;
241 | //}
242 | [self setAlarm:triggerTime andStatus:@"success"];
243 |
244 | NSArray *result = [NSArray arrayWithObjects:@"0", nil];
245 | if(successCallback != nil){
246 | successCallback(result);
247 | }
248 | }
249 | else{
250 | [self setAlarm:triggerTime andStatus:@"error"];
251 |
252 | NSArray *result = [NSArray arrayWithObjects:@"0",nil];
253 | if(errorCallback != nil) {
254 | errorCallback(result);
255 | }
256 | }
257 |
258 |
259 |
260 | }
261 | @catch(NSException *exception){
262 | NSLog(@"%@", exception.reason);
263 | NSArray *result = [NSArray arrayWithObjects:@"1",exception.reason, nil];
264 | if(errorCallback != nil) {
265 | errorCallback(result);
266 | }
267 | }
268 | }
269 |
270 |
271 |
272 | RCT_EXPORT_METHOD(setAlarmWithPromise:(NSString *)triggerTime
273 | title:(NSString *)title
274 | musicUri:(nullable NSString *)musicUri
275 | resolver:(RCTPromiseResolveBlock)resolver
276 | reject:(RCTPromiseRejectBlock)reject){
277 | @try
278 | {
279 | UNUserNotificationCenter *rCenter = UNUserNotificationCenter.currentNotificationCenter;
280 | [rCenter requestAuthorizationWithOptions:(UNAuthorizationOptionAlert | UNAuthorizationOptionSound)
281 | completionHandler:^(BOOL granted, NSError * _Nullable error){
282 | // Enable or disable based on authorization
283 | }];
284 |
285 | UNMutableNotificationContent *content = [[UNMutableNotificationContent alloc] init];
286 | //content.title = [NSString localizedUserNotificationStringForKey:@"RNALarm" arguments:nil];
287 | content.body = [NSString localizedUserNotificationStringForKey:title arguments:nil];
288 | if(musicUri == nil) {
289 | content.sound = [UNNotificationSound defaultSound];
290 | }else {
291 | content.sound = [UNNotificationSound soundNamed:musicUri];
292 | }
293 | NSTimeInterval time =[triggerTime doubleValue];
294 | NSDate *tgTime = [NSDate dateWithTimeIntervalSince1970:time];
295 | NSDateComponents *components = [[NSCalendar autoupdatingCurrentCalendar] components:componentFlags fromDate:tgTime];
296 | UNCalendarNotificationTrigger *trigger = [UNCalendarNotificationTrigger triggerWithDateMatchingComponents:components repeats:NO];
297 |
298 | UNNotificationRequest *request = [UNNotificationRequest requestWithIdentifier:@"RNAlarm" content:content trigger:trigger];
299 | UNUserNotificationCenter *center = [UNUserNotificationCenter currentNotificationCenter];
300 | [center addNotificationRequest:request withCompletionHandler:^(NSError * _Nullable error) {
301 | if(error != nil)
302 | {
303 | // NSLog(error.localizedDescription);
304 | @throw error;
305 | }
306 | }];
307 |
308 | NSArray *result = [NSArray arrayWithObjects:@"0", nil];
309 | resolver(result);
310 | }
311 | @catch(NSException *exception){
312 | NSLog(@"%@", exception.reason);
313 | NSError *error = [[NSError alloc] init];
314 |
315 | reject(@"RNAlarm_Errror", exception.name, error);
316 | }
317 | }
318 |
319 | @end
320 |
321 |
322 |
--------------------------------------------------------------------------------