airborne-react-native 0.1.0 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/AirborneReact.podspec +4 -1
- package/ios/Airborne.h +13 -5
- package/ios/Airborne.mm +27 -22
- package/ios/AirborneiOS.h +58 -9
- package/ios/AirborneiOS.m +84 -98
- package/package.json +4 -1
package/AirborneReact.podspec
CHANGED
|
@@ -33,7 +33,10 @@ Pod::Spec.new do |s|
|
|
|
33
33
|
}
|
|
34
34
|
|
|
35
35
|
s.source_files = "ios/**/*.{h,m,mm,cpp}"
|
|
36
|
-
s.
|
|
36
|
+
s.public_header_files = "ios/**/*.h"
|
|
37
|
+
s.static_framework = false
|
|
38
|
+
|
|
39
|
+
s.dependency "Airborne", "0.0.4"
|
|
37
40
|
|
|
38
41
|
install_modules_dependencies(s)
|
|
39
42
|
end
|
package/ios/Airborne.h
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
#import "AirborneiOS.h"
|
|
1
2
|
#ifdef RCT_NEW_ARCH_ENABLED
|
|
2
3
|
#import <AirborneSpec/AirborneSpec.h>
|
|
3
4
|
|
|
@@ -5,13 +6,20 @@
|
|
|
5
6
|
#else
|
|
6
7
|
#import <React/RCTBridgeModule.h>
|
|
7
8
|
|
|
9
|
+
|
|
8
10
|
@interface Airborne : NSObject <RCTBridgeModule>
|
|
9
11
|
#endif
|
|
10
12
|
|
|
11
|
-
+ (void)
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
13
|
+
+ (void)initializeAirborneWithReleaseConfigUrl:(NSString *) releaseConfigUrl;
|
|
14
|
+
|
|
15
|
+
+ (void)initializeAirborneWithReleaseConfigUrl:(NSString *) releaseConfigUrl
|
|
16
|
+
inNamespace:(NSString *) ns;
|
|
17
|
+
|
|
18
|
+
+ (void)initializeAirborneWithReleaseConfigUrl:(NSString *)releaseConfigUrl
|
|
19
|
+
delegate:delegate;
|
|
20
|
+
|
|
21
|
+
+ (void)initializeAirborneWithReleaseConfigUrl:(NSString *) releaseConfigUrl
|
|
22
|
+
inNamespace:(NSString *) ns
|
|
23
|
+
delegate:(id<AirborneReactDelegate>) delegate;
|
|
16
24
|
|
|
17
25
|
@end
|
package/ios/Airborne.mm
CHANGED
|
@@ -1,34 +1,39 @@
|
|
|
1
1
|
#import "Airborne.h"
|
|
2
2
|
#import "AirborneiOS.h"
|
|
3
3
|
#import <React/RCTLog.h>
|
|
4
|
+
#import <Airborne/Airborne.h>
|
|
5
|
+
#import <Airborne/Airborne-Swift.h>
|
|
4
6
|
|
|
5
7
|
@implementation Airborne
|
|
6
8
|
|
|
7
9
|
RCT_EXPORT_MODULE(Airborne)
|
|
8
10
|
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
11
|
+
static NSString * const defaultNamespace = @"default";
|
|
12
|
+
|
|
13
|
+
+ (void)initializeAirborneWithReleaseConfigUrl:(NSString *)releaseConfigUrl {
|
|
14
|
+
[self initializeAirborneWithReleaseConfigUrl:releaseConfigUrl inNamespace:defaultNamespace];
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
+ (void)initializeAirborneWithReleaseConfigUrl:(NSString *)releaseConfigUrl inNamespace:ns {
|
|
18
|
+
AirborneiOS* air = [AirborneiOS sharedInstanceWithNamespace:ns];
|
|
19
|
+
[air loadWithReleaseConfig:releaseConfigUrl delegate:nil];
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
+ (void)initializeAirborneWithReleaseConfigUrl:(NSString *)releaseConfigUrl delegate:delegate {
|
|
23
|
+
AirborneiOS* air = [AirborneiOS sharedInstanceWithNamespace:defaultNamespace];
|
|
24
|
+
[air loadWithReleaseConfig:releaseConfigUrl delegate:delegate];
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
+ (void)initializeAirborneWithReleaseConfigUrl:(NSString *)releaseConfigUrl inNamespace:ns delegate:delegate {
|
|
28
|
+
AirborneiOS* air = [AirborneiOS sharedInstanceWithNamespace:ns];
|
|
29
|
+
[air loadWithReleaseConfig:releaseConfigUrl delegate:delegate];
|
|
25
30
|
}
|
|
26
31
|
|
|
27
32
|
#ifdef RCT_NEW_ARCH_ENABLED
|
|
28
33
|
- (void)readReleaseConfig:(RCTPromiseResolveBlock)resolve
|
|
29
34
|
reject:(RCTPromiseRejectBlock)reject {
|
|
30
35
|
@try {
|
|
31
|
-
NSString *config = [[AirborneiOS
|
|
36
|
+
NSString *config = [[AirborneiOS sharedInstanceWithNamespace:defaultNamespace] getReleaseConfig];
|
|
32
37
|
resolve(config);
|
|
33
38
|
} @catch (NSException *exception) {
|
|
34
39
|
reject(@"AIRBORNE_ERROR", exception.reason, nil);
|
|
@@ -39,7 +44,7 @@ RCT_EXPORT_MODULE(Airborne)
|
|
|
39
44
|
resolve:(RCTPromiseResolveBlock)resolve
|
|
40
45
|
reject:(RCTPromiseRejectBlock)reject {
|
|
41
46
|
@try {
|
|
42
|
-
NSString *content = [[AirborneiOS
|
|
47
|
+
NSString *content = [[AirborneiOS sharedInstanceWithNamespace:defaultNamespace] getFileContent:filePath];
|
|
43
48
|
resolve(content);
|
|
44
49
|
} @catch (NSException *exception) {
|
|
45
50
|
reject(@"AIRBORNE_ERROR", exception.reason, nil);
|
|
@@ -49,7 +54,7 @@ RCT_EXPORT_MODULE(Airborne)
|
|
|
49
54
|
- (void)getBundlePath:(RCTPromiseResolveBlock)resolve
|
|
50
55
|
reject:(RCTPromiseRejectBlock)reject {
|
|
51
56
|
@try {
|
|
52
|
-
NSString *bundlePath = [[AirborneiOS
|
|
57
|
+
NSString *bundlePath = [[AirborneiOS sharedInstanceWithNamespace:defaultNamespace] getBundlePath];
|
|
53
58
|
resolve(bundlePath);
|
|
54
59
|
} @catch (NSException *exception) {
|
|
55
60
|
reject(@"AIRBORNE_ERROR", exception.reason, nil);
|
|
@@ -59,7 +64,7 @@ RCT_EXPORT_MODULE(Airborne)
|
|
|
59
64
|
RCT_EXPORT_METHOD(readReleaseConfig:(RCTPromiseResolveBlock)resolve
|
|
60
65
|
rejecter:(RCTPromiseRejectBlock)reject) {
|
|
61
66
|
@try {
|
|
62
|
-
NSString *config = [[AirborneiOS
|
|
67
|
+
NSString *config = [[AirborneiOS sharedInstanceWithNamespace:defaultNamespace] getReleaseConfig];
|
|
63
68
|
resolve(config);
|
|
64
69
|
} @catch (NSException *exception) {
|
|
65
70
|
reject(@"AIRBORNE_ERROR", exception.reason, nil);
|
|
@@ -70,7 +75,7 @@ RCT_EXPORT_METHOD(getFileContent:(NSString *)filePath
|
|
|
70
75
|
resolver:(RCTPromiseResolveBlock)resolve
|
|
71
76
|
rejecter:(RCTPromiseRejectBlock)reject) {
|
|
72
77
|
@try {
|
|
73
|
-
NSString *content = [[AirborneiOS
|
|
78
|
+
NSString *content = [[AirborneiOS sharedInstanceWithNamespace:defaultNamespace] getFileContent:filePath];
|
|
74
79
|
resolve(content);
|
|
75
80
|
} @catch (NSException *exception) {
|
|
76
81
|
reject(@"AIRBORNE_ERROR", exception.reason, nil);
|
|
@@ -80,7 +85,7 @@ RCT_EXPORT_METHOD(getFileContent:(NSString *)filePath
|
|
|
80
85
|
RCT_EXPORT_METHOD(getBundlePath:(RCTPromiseResolveBlock)resolve
|
|
81
86
|
rejecter:(RCTPromiseRejectBlock)reject) {
|
|
82
87
|
@try {
|
|
83
|
-
NSString *bundlePath = [[AirborneiOS
|
|
88
|
+
NSString *bundlePath = [[AirborneiOS sharedInstanceWithNamespace:defaultNamespace] getBundlePath];
|
|
84
89
|
resolve(bundlePath);
|
|
85
90
|
} @catch (NSException *exception) {
|
|
86
91
|
reject(@"AIRBORNE_ERROR", exception.reason, nil);
|
package/ios/AirborneiOS.h
CHANGED
|
@@ -2,21 +2,70 @@
|
|
|
2
2
|
|
|
3
3
|
NS_ASSUME_NONNULL_BEGIN
|
|
4
4
|
|
|
5
|
+
@protocol AirborneReactDelegate <NSObject>
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Returns custom dimensions/metadata to include with release configuration requests.
|
|
9
|
+
*
|
|
10
|
+
* These dimensions are sent as HTTP headers when fetching the release configuration
|
|
11
|
+
* and can be used for:
|
|
12
|
+
* - A/B testing and feature flags
|
|
13
|
+
* - Device-specific configurations
|
|
14
|
+
* - User segmentation
|
|
15
|
+
* - Analytics and debugging context
|
|
16
|
+
*
|
|
17
|
+
* @return A dictionary of header field names and values to include in network requests.
|
|
18
|
+
* If not implemented, defaults to an empty dictionary.
|
|
19
|
+
*/
|
|
20
|
+
- (NSDictionary<NSString *, NSString *> *)getDimensions;
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* Called when the OTA boot process has completed successfully.
|
|
24
|
+
*
|
|
25
|
+
* This callback indicates that the application is ready to load the packages & resources
|
|
26
|
+
*
|
|
27
|
+
* @note This method is called on a background queue. Dispatch UI updates
|
|
28
|
+
* to the main queue if needed.
|
|
29
|
+
* @note Boot completion occurs even if some downloads failed or timed out.
|
|
30
|
+
* Check the release configuration for actual status.
|
|
31
|
+
*/
|
|
32
|
+
- (void)onBootComplete:(NSString *) bundlePath;
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* Called when significant events occur during the OTA update process.
|
|
36
|
+
*
|
|
37
|
+
* This callback provides detailed information about:
|
|
38
|
+
* - Download progress and completion
|
|
39
|
+
* - Error conditions and failures
|
|
40
|
+
* - Performance metrics and timing
|
|
41
|
+
* - State transitions in the update process
|
|
42
|
+
*
|
|
43
|
+
* @param level The severity level of the event ("info", "error", "warning")
|
|
44
|
+
* @param label A category label for the event (e.g., "ota_update")
|
|
45
|
+
* @param key A specific identifier for the event type
|
|
46
|
+
* @param value Additional structured data about the event
|
|
47
|
+
* @param category The broad category of the event (e.g., "lifecycle")
|
|
48
|
+
* @param subcategory The specific subcategory (e.g., "hyperota")
|
|
49
|
+
*
|
|
50
|
+
* @note Use this for logging, analytics, debugging, and monitoring OTA performance.
|
|
51
|
+
*/
|
|
52
|
+
- (void)onEventWithLevel:(NSString *)level
|
|
53
|
+
label:(NSString *)label
|
|
54
|
+
key:(NSString *)key
|
|
55
|
+
value:(NSDictionary<NSString *, id> *)value
|
|
56
|
+
category:(NSString *)category
|
|
57
|
+
subcategory:(NSString *)subcategory;
|
|
58
|
+
|
|
59
|
+
@end
|
|
60
|
+
|
|
5
61
|
typedef void (^HyperOTALazyDownloadCallback)(NSString *filePath, BOOL success);
|
|
6
62
|
typedef void (^HyperOTALazySplitsCallback)(BOOL success);
|
|
7
63
|
|
|
8
64
|
@interface AirborneiOS : NSObject
|
|
9
65
|
|
|
10
|
-
+ (instancetype)
|
|
11
|
-
|
|
12
|
-
- (void)initializeWithAppId:(NSString *)appId
|
|
13
|
-
indexFileName:(NSString *)indexFileName
|
|
14
|
-
appVersion:(NSString *)appVersion
|
|
15
|
-
releaseConfigTemplateUrl:(NSString *)releaseConfigTemplateUrl
|
|
16
|
-
headers:(nullable NSDictionary<NSString *, NSString *> *)headers
|
|
17
|
-
lazyDownloadCallback:(nullable HyperOTALazyDownloadCallback)lazyDownloadCallback
|
|
18
|
-
lazySplitsCallback:(nullable HyperOTALazySplitsCallback)lazySplitsCallback;
|
|
66
|
+
+ (instancetype)sharedInstanceWithNamespace:(NSString *)ns;
|
|
19
67
|
|
|
68
|
+
- (void) loadWithReleaseConfig:(NSString *) rcurl delegate:(id<AirborneReactDelegate>) delegate;
|
|
20
69
|
- (NSString *)getBundlePath;
|
|
21
70
|
- (NSString *)getFileContent:(NSString *)filePath;
|
|
22
71
|
- (NSString *)getReleaseConfig;
|
package/ios/AirborneiOS.m
CHANGED
|
@@ -1,128 +1,114 @@
|
|
|
1
1
|
#import "AirborneiOS.h"
|
|
2
|
+
#import "Airborne/Airborne.h"
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
@interface AirborneLocalDelegate : NSObject<AirborneDelegate>
|
|
6
|
+
@property (nonatomic, weak) NSString* ns;
|
|
7
|
+
@property (nonatomic, weak) id<AirborneReactDelegate> delegate;
|
|
8
|
+
-(instancetype)initWithNamespace:(NSString*) ns
|
|
9
|
+
delegate:(id<AirborneReactDelegate>) delegate;
|
|
10
|
+
@end
|
|
11
|
+
|
|
12
|
+
@implementation AirborneLocalDelegate
|
|
13
|
+
|
|
14
|
+
-(instancetype)initWithNamespace:(NSString*) ns delegate:(id<AirborneReactDelegate>) del {
|
|
15
|
+
self = [super init];
|
|
16
|
+
if (self) {
|
|
17
|
+
_ns = ns;
|
|
18
|
+
_delegate = del;
|
|
19
|
+
}
|
|
20
|
+
return self;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
- (NSString *)namespace{
|
|
24
|
+
return self.ns;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
- (NSDictionary *)dimensions{
|
|
28
|
+
if(_delegate == nil) return @{};
|
|
29
|
+
return [_delegate getDimensions];
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
- (void)onBootCompleteWithIndexBundlePath:(NSString *)indexBundlePath{
|
|
33
|
+
if (_delegate == nil) return;
|
|
34
|
+
[_delegate onBootComplete:indexBundlePath];
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
-(void)onEventWithLevel:(NSString *)level label:(NSString *)label key:(NSString *)key value:(NSDictionary<NSString *,id> *)value category:(NSString *)category subcategory:(NSString *)subcategory{
|
|
38
|
+
if (_delegate == nil) return;
|
|
39
|
+
[_delegate onEventWithLevel:level label:label key:key value:value category:category subcategory:subcategory];
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
@end
|
|
43
|
+
|
|
2
44
|
|
|
3
45
|
@interface AirborneiOS ()
|
|
4
|
-
@property (nonatomic,
|
|
5
|
-
@property (nonatomic, strong)
|
|
6
|
-
|
|
46
|
+
@property (nonatomic, strong) NSString* ns;
|
|
47
|
+
@property (nonatomic, strong) AirborneServices* air;
|
|
48
|
+
@property (nonatomic, strong) id<AirborneDelegate> delegate;
|
|
49
|
+
@property (nonatomic, strong) AirborneLocalDelegate* delegateproxy;
|
|
50
|
+
|
|
7
51
|
@end
|
|
8
52
|
|
|
9
53
|
@implementation AirborneiOS
|
|
10
54
|
|
|
11
|
-
+ (instancetype)
|
|
12
|
-
static AirborneiOS *
|
|
55
|
+
+ (instancetype)sharedInstanceWithNamespace:(NSString *)namespace{
|
|
56
|
+
static NSMutableDictionary<NSString *, AirborneiOS *> *instances = nil;
|
|
57
|
+
static dispatch_queue_t syncQueue;
|
|
13
58
|
static dispatch_once_t onceToken;
|
|
59
|
+
|
|
60
|
+
// Initialize dictionary and queue once
|
|
14
61
|
dispatch_once(&onceToken, ^{
|
|
15
|
-
|
|
62
|
+
instances = [NSMutableDictionary dictionary];
|
|
63
|
+
syncQueue = dispatch_queue_create("in.juspay.Airborne.singleton", DISPATCH_QUEUE_CONCURRENT);
|
|
16
64
|
});
|
|
17
|
-
|
|
65
|
+
|
|
66
|
+
__block AirborneiOS *instance = nil;
|
|
67
|
+
|
|
68
|
+
// Read existing instance (concurrent)
|
|
69
|
+
dispatch_sync(syncQueue, ^{
|
|
70
|
+
instance = instances[namespace];
|
|
71
|
+
});
|
|
72
|
+
|
|
73
|
+
if (instance == nil) {
|
|
74
|
+
// Write new instance (barrier to prevent concurrent writes)
|
|
75
|
+
dispatch_barrier_sync(syncQueue, ^{
|
|
76
|
+
if (!instances[namespace]) {
|
|
77
|
+
instances[namespace] = [[self alloc] initWithNamespace:namespace];
|
|
78
|
+
}
|
|
79
|
+
instance = instances[namespace];
|
|
80
|
+
});
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
return instance;
|
|
18
84
|
}
|
|
19
85
|
|
|
20
|
-
|
|
86
|
+
|
|
87
|
+
- (instancetype)initWithNamespace:(NSString *) ns{
|
|
21
88
|
self = [super init];
|
|
22
89
|
if (self) {
|
|
23
|
-
|
|
90
|
+
_ns = ns;
|
|
91
|
+
|
|
24
92
|
}
|
|
25
93
|
return self;
|
|
26
94
|
}
|
|
27
95
|
|
|
28
|
-
- (void)
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
releaseConfigTemplateUrl:(NSString *)releaseConfigTemplateUrl
|
|
32
|
-
headers:(nullable NSDictionary<NSString *, NSString *> *)headers
|
|
33
|
-
lazyDownloadCallback:(nullable HyperOTALazyDownloadCallback)lazyDownloadCallback
|
|
34
|
-
lazySplitsCallback:(nullable HyperOTALazySplitsCallback)lazySplitsCallback {
|
|
35
|
-
|
|
36
|
-
if (self.isInitialized) {
|
|
37
|
-
NSLog(@"AirborneiOS: Already initialized");
|
|
38
|
-
return;
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
self.indexFileName = indexFileName;
|
|
42
|
-
|
|
43
|
-
// TODO: Initialize the actual Airborne SDK here
|
|
44
|
-
// This is a placeholder implementation
|
|
45
|
-
// In a real implementation, you would:
|
|
46
|
-
// 1. Import the HyperOTA iOS SDK
|
|
47
|
-
// 2. Initialize HyperOTAServices with the provided parameters
|
|
48
|
-
// 3. Create an ApplicationManager
|
|
49
|
-
// 4. Load the application
|
|
50
|
-
|
|
51
|
-
NSLog(@"AirborneiOS: Initializing with appId: %@, indexFileName: %@, appVersion: %@",
|
|
52
|
-
appId, indexFileName, appVersion);
|
|
53
|
-
|
|
54
|
-
self.isInitialized = YES;
|
|
55
|
-
|
|
56
|
-
// Simulate callbacks for demo purposes
|
|
57
|
-
if (lazyDownloadCallback) {
|
|
58
|
-
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
|
|
59
|
-
lazyDownloadCallback(@"demo/file.js", YES);
|
|
60
|
-
});
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
if (lazySplitsCallback) {
|
|
64
|
-
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(2 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
|
|
65
|
-
lazySplitsCallback(YES);
|
|
66
|
-
});
|
|
67
|
-
}
|
|
96
|
+
- (void)loadWithReleaseConfig:(NSString *) rcurl delegate:(id<AirborneReactDelegate>) delegate{
|
|
97
|
+
_delegateproxy = [[AirborneLocalDelegate alloc] initWithNamespace: self.ns delegate:delegate];
|
|
98
|
+
_air = [[AirborneServices alloc] initWithReleaseConfigURL:rcurl delegate:_delegateproxy];
|
|
68
99
|
}
|
|
69
100
|
|
|
70
101
|
- (NSString *)getBundlePath {
|
|
71
|
-
|
|
72
|
-
// @throw [NSException exceptionWithName:@"HyperOTANotInitialized"
|
|
73
|
-
// reason:@"HyperOTA is not initialized. Call initialize first."
|
|
74
|
-
// userInfo:nil];
|
|
75
|
-
// }
|
|
76
|
-
//
|
|
77
|
-
// // TODO: Get the actual bundle path from HyperOTA SDK //
|
|
78
|
-
// // This is a placeholder implementation
|
|
79
|
-
// NSString *bundlePath = [[NSBundle mainBundle] pathForResource:self.indexFileName ofType:nil];
|
|
80
|
-
// if (!bundlePath) {
|
|
81
|
-
// bundlePath = [NSString stringWithFormat:@"assets://%@", self.indexFileName];
|
|
82
|
-
// }
|
|
83
|
-
//
|
|
84
|
-
// return bundlePath;
|
|
85
|
-
return @"";
|
|
102
|
+
return [_air getIndexBundlePath] ;
|
|
86
103
|
}
|
|
87
104
|
|
|
88
105
|
- (NSString *)getFileContent:(NSString *)filePath {
|
|
89
|
-
|
|
90
|
-
// @throw [NSException exceptionWithName:@"HyperOTANotInitialized"
|
|
91
|
-
// reason:@"HyperOTA is not initialized. Call initialize first."
|
|
92
|
-
// userInfo:nil];
|
|
93
|
-
// }
|
|
94
|
-
//
|
|
95
|
-
// // TODO: Read the actual file content from HyperOTA SDK //
|
|
96
|
-
// // This is a placeholder implementation
|
|
97
|
-
// return [NSString stringWithFormat:@"File content for: %@", filePath];
|
|
98
|
-
return @"";
|
|
106
|
+
return [_air getFileContentAtPath:filePath];
|
|
99
107
|
}
|
|
100
108
|
|
|
101
109
|
- (NSString *)getReleaseConfig {
|
|
102
|
-
|
|
103
|
-
// @throw [NSException exceptionWithName:@"HyperOTANotInitialized"
|
|
104
|
-
// reason:@"HyperOTA is not initialized. Call initialize first."
|
|
105
|
-
// userInfo:nil];
|
|
106
|
-
// }
|
|
107
|
-
//
|
|
108
|
-
// // TODO: Get the actual release config from HyperOTA SDK //
|
|
109
|
-
// // This is a placeholder implementation
|
|
110
|
-
// NSDictionary *config = @{
|
|
111
|
-
// @"version": @"1.0.0",
|
|
112
|
-
// @"environment": @"production",
|
|
113
|
-
// @"features": @{
|
|
114
|
-
// @"featureA": @YES,
|
|
115
|
-
// @"featureB": @NO
|
|
116
|
-
// }
|
|
117
|
-
// };
|
|
118
|
-
//
|
|
119
|
-
// NSError *error;
|
|
120
|
-
// NSData *jsonData = [NSJSONSerialization dataWithJSONObject:config options:0 error:&error];
|
|
121
|
-
// if (jsonData) {
|
|
122
|
-
// return [[NSString alloc] initWithData:jsonData encoding:NSUTF8StringEncoding];
|
|
123
|
-
// }
|
|
124
|
-
|
|
125
|
-
return @"{}";
|
|
110
|
+
return [_air getReleaseConfig];
|
|
126
111
|
}
|
|
127
112
|
|
|
128
113
|
@end
|
|
114
|
+
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "airborne-react-native",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.2.0",
|
|
4
4
|
"description": "Airborne",
|
|
5
5
|
"main": "./lib/module/index.js",
|
|
6
6
|
"types": "./lib/typescript/src/index.d.ts",
|
|
@@ -58,6 +58,9 @@
|
|
|
58
58
|
"publishConfig": {
|
|
59
59
|
"registry": "https://registry.npmjs.org/"
|
|
60
60
|
},
|
|
61
|
+
"dependencies": {
|
|
62
|
+
"airborne-cli-react-native": "file:../airborne_cli"
|
|
63
|
+
},
|
|
61
64
|
"devDependencies": {
|
|
62
65
|
"@commitlint/config-conventional": "^19.6.0",
|
|
63
66
|
"@eslint/compat": "^1.2.7",
|