알람앱을 만들면서 ReactNative의 DeviceEventEmitter 를 직접적으로 커스터마이징이 필요한 상황이 오게 되었다.
IOS 에서 어떻게 RCTEmitter 를 커스터마이징하여 적용할지 찾아보았다.
흔들기 기능을 추가하려면 흔들기 감지하고 그것을 실시간 보내주어야 하는데, 그부분을 모듈화하여 ReactNative 안에서 실행하려고 했다.
우선 , .Swift 와 .h 을 만들어야한다 . 그리고 흔들기 기능관련된 부분을 추가해준다.
import Foundation
import UIKit
import AVFoundation
import React
import CoreMotion
@objc(ShakeModule)
class ShakeModule : RCTEventEmitter {
var motionManager: CMMotionManager!
override init() {
super.init()
self.motionManager = CMMotionManager()
self.motionManager.accelerometerUpdateInterval = 0.2
}
override class func requiresMainQueueSetup() -> Bool {
return true
}
override func supportedEvents() -> [String] {
return ["ShakeEvent"]
}
@objc
func startAccelerometerUpdates() {
self.motionManager.startAccelerometerUpdates(to: .main) { [weak self] data, error in
guard let x = data?.acceleration.x,
let y = data?.acceleration.y,
let z = data?.acceleration.z else {
return
}
let speed = sqrt(pow(x, 2)) + sqrt(pow(y, 2)) + sqrt(pow(z, 2))
if speed > 2.0 {
self?.sendEvent(withName: "ShakeEvent", body: ["isShake": true])
} else {
self?.sendEvent(withName: "ShakeEvent", body: ["isShake": false])
}
}
}
@objc
func stopAccelerometerUpdates() {
self.motionManager.stopAccelerometerUpdates()
}
}
#import <Foundation/Foundation.h>
#import <React/RCTBridgeModule.h>
#import <React/RCTEventEmitter.h>
#import <React/RCTEventDispatcher.h>
@interface RCT_EXTERN_REMAP_MODULE(RNShake ,ShakeModule, RCTEventEmitter)
_RCT_EXTERN_REMAP_METHOD(startShakeInit, startAccelerometerUpdates, false)
_RCT_EXTERN_REMAP_METHOD(stopShakeInit, stopAccelerometerUpdates, false)
@end
그리고 React Native에서
위와 같이 EventEmitter라고 선언해주고 그 값들을 형변환하여 가져온다.
그리고 위와 같이 사용하면 커스터마이징 된 Emitter를 사용할 수 있게 된다 !!
끝!!
참고 *
ReactNative IOS 에서 UIViewController 도 역시 커스터마이징 가능하다
NSDictionary *initProps = [self prepareInitialProps];
UIView *rootView = RCTAppSetupDefaultRootView(bridge, @"alarm", initProps);
rootView.backgroundColor = [UIColor whiteColor];
self.window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds];
MainViewController *rootViewController = [MainViewController new];
rootViewController.view = rootView;
self.myAlarm = [[Alarm alloc] init];
[self.myAlarm initBridgeWithBridge:bridge];
[application setApplicationSupportsShakeToEdit:YES];
[application registerForRemoteNotifications];
[application setMinimumBackgroundFetchInterval:UIApplicationBackgroundFetchIntervalMinimum];
UNUserNotificationCenter *center = [UNUserNotificationCenter currentNotificationCenter];
center.delegate = self;
AVAudioSession * session = [AVAudioSession sharedInstance];
[session setCategory: AVAudioSessionCategoryPlayback error: nil];
[FIRApp configure];
if (@available(iOS 13.0, *)) {
[[BGTaskScheduler sharedScheduler] registerForTaskWithIdentifier:@"com.alarm.backgroundTasking" usingQueue:nil launchHandler:^(BGTask *task) {
[self.myAlarm appTerminated];
}];
[[BGTaskScheduler sharedScheduler] registerForTaskWithIdentifier:@"com.alarm.backgroundAppRefresh" usingQueue:nil launchHandler:^(BGTask *task) {
}];
} else {
UIApplication* app = [UIApplication sharedApplication];
__block UIBackgroundTaskIdentifier backgroundTask;
backgroundTask = [app beginBackgroundTaskWithExpirationHandler:^{
[app endBackgroundTask:backgroundTask];
}];
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
[app endBackgroundTask:backgroundTask];
});
}
![](https://t1.daumcdn.net/keditor/emoticon/friends1/large/004.gif)
'ReactNative' 카테고리의 다른 글
ReactNative_ AOS 커스텀 RCTEmitter 생성 및 적용 (0) | 2024.03.05 |
---|---|
ReactNative_ IOS 빌드 환경 분리 (0) | 2024.03.04 |
ReactNative_ AOS 의 빌드 환경 분리 (0) | 2024.03.04 |