airborne-react-native 0.3.0 → 0.4.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 -7
- package/ios/Airborne.h +11 -18
- package/ios/Airborne.m +80 -0
- package/ios/AirborneReact.h +26 -0
- package/ios/{Airborne.mm → AirborneReact.mm} +10 -12
- package/package.json +1 -1
- package/ios/AirborneiOS.h +0 -89
- package/ios/AirborneiOS.m +0 -120
package/AirborneReact.podspec
CHANGED
|
@@ -28,15 +28,12 @@ Pod::Spec.new do |s|
|
|
|
28
28
|
|
|
29
29
|
s.platforms = { :ios => "12.0"}
|
|
30
30
|
s.source = { :git => "https://github.com/juspay/airborne.git", :tag => "#{s.version}" }
|
|
31
|
-
s.resource_bundles = {
|
|
32
|
-
'AirborneReactResources' => ['ios/**/*.{xib,storyboard,xcassets,json}']
|
|
33
|
-
}
|
|
34
31
|
|
|
35
32
|
s.source_files = "ios/**/*.{h,m,mm,cpp}"
|
|
36
33
|
s.public_header_files = "ios/**/*.h"
|
|
37
34
|
s.static_framework = false
|
|
38
|
-
|
|
39
|
-
s.dependency "Airborne", "0.
|
|
40
|
-
|
|
41
|
-
|
|
35
|
+
|
|
36
|
+
s.dependency "Airborne", "0.3.2"
|
|
37
|
+
|
|
38
|
+
install_modules_dependencies(s)
|
|
42
39
|
end
|
package/ios/Airborne.h
CHANGED
|
@@ -1,25 +1,18 @@
|
|
|
1
|
-
#import
|
|
2
|
-
#
|
|
3
|
-
#import <AirborneSpec/AirborneSpec.h>
|
|
1
|
+
#import <Foundation/Foundation.h>
|
|
2
|
+
#import <Airborne/Airborne-Swift.h>
|
|
4
3
|
|
|
5
|
-
|
|
6
|
-
#else
|
|
7
|
-
#import <React/RCTBridgeModule.h>
|
|
4
|
+
NS_ASSUME_NONNULL_BEGIN
|
|
8
5
|
|
|
6
|
+
@interface Airborne : NSObject
|
|
9
7
|
|
|
10
|
-
|
|
11
|
-
#endif
|
|
8
|
+
+ (instancetype)sharedInstanceWithNamespace:(NSString *)aNamespace;
|
|
12
9
|
|
|
13
|
-
|
|
10
|
+
- (instancetype)initWithReleaseConfigURL:(NSString *)releaseConfigURL delegate:(id<AirborneDelegate>)delegate;
|
|
14
11
|
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
+ (void)initializeAirborneWithReleaseConfigUrl:(NSString *)releaseConfigUrl
|
|
19
|
-
delegate:delegate;
|
|
20
|
-
|
|
21
|
-
+ (void)initializeAirborneWithReleaseConfigUrl:(NSString *) releaseConfigUrl
|
|
22
|
-
inNamespace:(NSString *) ns
|
|
23
|
-
delegate:(id<AirborneReactDelegate>) delegate;
|
|
12
|
+
- (NSString *)getBundlePath;
|
|
13
|
+
- (NSString *)getFileContent:(NSString *)filePath;
|
|
14
|
+
- (NSString *)getReleaseConfig;
|
|
24
15
|
|
|
25
16
|
@end
|
|
17
|
+
|
|
18
|
+
NS_ASSUME_NONNULL_END
|
package/ios/Airborne.m
ADDED
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
|
|
2
|
+
#import "Airborne.h"
|
|
3
|
+
|
|
4
|
+
@interface Airborne() <AirborneDelegate>
|
|
5
|
+
|
|
6
|
+
@property (nonatomic, strong) NSString* namespace;
|
|
7
|
+
@property (nonatomic, strong) AirborneServices* airborne;
|
|
8
|
+
@property (nonatomic, weak) id <AirborneDelegate> delegate;
|
|
9
|
+
|
|
10
|
+
@end
|
|
11
|
+
|
|
12
|
+
@implementation Airborne
|
|
13
|
+
|
|
14
|
+
+ (instancetype)sharedInstanceWithNamespace:(NSString *)aNamespace {
|
|
15
|
+
static NSMutableDictionary<NSString *, Airborne *> *instances = nil;
|
|
16
|
+
static dispatch_queue_t syncQueue;
|
|
17
|
+
static dispatch_once_t onceToken;
|
|
18
|
+
|
|
19
|
+
// Initialize dictionary and queue once
|
|
20
|
+
dispatch_once(&onceToken, ^{
|
|
21
|
+
instances = [NSMutableDictionary dictionary];
|
|
22
|
+
syncQueue = dispatch_queue_create("in.juspay.Airborne.singleton", DISPATCH_QUEUE_CONCURRENT);
|
|
23
|
+
});
|
|
24
|
+
|
|
25
|
+
__block Airborne *instance = nil;
|
|
26
|
+
|
|
27
|
+
// Read existing instance (concurrent)
|
|
28
|
+
dispatch_sync(syncQueue, ^{
|
|
29
|
+
instance = instances[aNamespace];
|
|
30
|
+
});
|
|
31
|
+
|
|
32
|
+
if (instance == nil) {
|
|
33
|
+
// Write new instance (barrier to prevent concurrent writes)
|
|
34
|
+
dispatch_barrier_sync(syncQueue, ^{
|
|
35
|
+
if (!instances[aNamespace]) {
|
|
36
|
+
instances[aNamespace] = [[self alloc] initWithNamespace:aNamespace];
|
|
37
|
+
}
|
|
38
|
+
instance = instances[aNamespace];
|
|
39
|
+
});
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
return instance;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
- (instancetype)initWithNamespace:(NSString *)namespace {
|
|
46
|
+
self = [super init];
|
|
47
|
+
if (self) {
|
|
48
|
+
self.namespace = namespace;
|
|
49
|
+
}
|
|
50
|
+
return self;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
- (instancetype)initWithReleaseConfigURL:(NSString *)releaseConfigURL delegate:(id<AirborneDelegate>)delegate {
|
|
54
|
+
self = [super init];
|
|
55
|
+
if (self) {
|
|
56
|
+
self.airborne = [[AirborneServices alloc] initWithReleaseConfigURL:releaseConfigURL delegate:delegate ?: self];
|
|
57
|
+
}
|
|
58
|
+
return self;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
- (NSString *)getBundlePath {
|
|
62
|
+
return [self.airborne getIndexBundlePath].absoluteString;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
- (NSString *)getFileContent:(NSString *)filePath {
|
|
66
|
+
return [self.airborne getFileContentAtPath:filePath];
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
- (NSString *)getReleaseConfig {
|
|
70
|
+
return [self.airborne getReleaseConfig];
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
#pragma mark - AirborneDelegate
|
|
74
|
+
|
|
75
|
+
- (NSString *)namespace {
|
|
76
|
+
return @"default";
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
@end
|
|
80
|
+
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
#import "Airborne.h"
|
|
2
|
+
#ifdef RCT_NEW_ARCH_ENABLED
|
|
3
|
+
#import <AirborneSpec/AirborneSpec.h>
|
|
4
|
+
#import <Airborne/Airborne-Swift.h>
|
|
5
|
+
|
|
6
|
+
@interface AirborneReact : NSObject <NativeAirborneSpec>
|
|
7
|
+
#else
|
|
8
|
+
#import <React/RCTBridgeModule.h>
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
@interface AirborneReact : NSObject <RCTBridgeModule>
|
|
12
|
+
#endif
|
|
13
|
+
|
|
14
|
+
+ (void)initializeAirborneWithReleaseConfigUrl:(NSString *) releaseConfigUrl;
|
|
15
|
+
|
|
16
|
+
+ (void)initializeAirborneWithReleaseConfigUrl:(NSString *) releaseConfigUrl
|
|
17
|
+
inNamespace:(NSString *) ns;
|
|
18
|
+
|
|
19
|
+
+ (void)initializeAirborneWithReleaseConfigUrl:(NSString *)releaseConfigUrl
|
|
20
|
+
delegate:delegate;
|
|
21
|
+
|
|
22
|
+
+ (void)initializeAirborneWithReleaseConfigUrl:(NSString *) releaseConfigUrl
|
|
23
|
+
inNamespace:(NSString *) ns
|
|
24
|
+
delegate:(id<AirborneDelegate>) delegate;
|
|
25
|
+
|
|
26
|
+
@end
|
|
@@ -1,10 +1,11 @@
|
|
|
1
|
+
#import "AirborneReact.h"
|
|
1
2
|
#import "Airborne.h"
|
|
2
|
-
#import "AirborneiOS.h"
|
|
3
3
|
#import <React/RCTLog.h>
|
|
4
|
-
#import <Airborne/
|
|
4
|
+
#import <Airborne/AJPLoggerDelegate.h>
|
|
5
|
+
#import <Airborne/AJPApplicationManager.h>
|
|
5
6
|
#import <Airborne/Airborne-Swift.h>
|
|
6
7
|
|
|
7
|
-
@implementation
|
|
8
|
+
@implementation AirborneReact
|
|
8
9
|
|
|
9
10
|
RCT_EXPORT_MODULE(Airborne)
|
|
10
11
|
|
|
@@ -15,25 +16,22 @@ static NSString * const defaultNamespace = @"default";
|
|
|
15
16
|
}
|
|
16
17
|
|
|
17
18
|
+ (void)initializeAirborneWithReleaseConfigUrl:(NSString *)releaseConfigUrl inNamespace:ns {
|
|
18
|
-
|
|
19
|
-
[air loadWithReleaseConfig:releaseConfigUrl delegate:nil];
|
|
19
|
+
AJPApplicationManager* manager = [AJPApplicationManager getSharedInstanceWithWorkspace:ns delegate:nil logger:nil];
|
|
20
20
|
}
|
|
21
21
|
|
|
22
22
|
+ (void)initializeAirborneWithReleaseConfigUrl:(NSString *)releaseConfigUrl delegate:delegate {
|
|
23
|
-
|
|
24
|
-
[air loadWithReleaseConfig:releaseConfigUrl delegate:delegate];
|
|
23
|
+
AJPApplicationManager* manager = [AJPApplicationManager getSharedInstanceWithWorkspace:defaultNamespace delegate:delegate logger:nil];
|
|
25
24
|
}
|
|
26
25
|
|
|
27
26
|
+ (void)initializeAirborneWithReleaseConfigUrl:(NSString *)releaseConfigUrl inNamespace:ns delegate:delegate {
|
|
28
|
-
|
|
29
|
-
[air loadWithReleaseConfig:releaseConfigUrl delegate:delegate];
|
|
27
|
+
AJPApplicationManager* manager = [AJPApplicationManager getSharedInstanceWithWorkspace:ns delegate:delegate logger:nil];
|
|
30
28
|
}
|
|
31
29
|
|
|
32
30
|
#ifdef RCT_NEW_ARCH_ENABLED
|
|
33
31
|
- (void)readReleaseConfig:(RCTPromiseResolveBlock)resolve
|
|
34
32
|
reject:(RCTPromiseRejectBlock)reject {
|
|
35
33
|
@try {
|
|
36
|
-
NSString *config = [[
|
|
34
|
+
NSString *config = [[Airborne sharedInstanceWithNamespace:defaultNamespace] getReleaseConfig];
|
|
37
35
|
resolve(config);
|
|
38
36
|
} @catch (NSException *exception) {
|
|
39
37
|
reject(@"AIRBORNE_ERROR", exception.reason, nil);
|
|
@@ -44,7 +42,7 @@ static NSString * const defaultNamespace = @"default";
|
|
|
44
42
|
resolve:(RCTPromiseResolveBlock)resolve
|
|
45
43
|
reject:(RCTPromiseRejectBlock)reject {
|
|
46
44
|
@try {
|
|
47
|
-
NSString *content = [[
|
|
45
|
+
NSString *content = [[Airborne sharedInstanceWithNamespace:defaultNamespace] getFileContent:filePath];
|
|
48
46
|
resolve(content);
|
|
49
47
|
} @catch (NSException *exception) {
|
|
50
48
|
reject(@"AIRBORNE_ERROR", exception.reason, nil);
|
|
@@ -54,7 +52,7 @@ static NSString * const defaultNamespace = @"default";
|
|
|
54
52
|
- (void)getBundlePath:(RCTPromiseResolveBlock)resolve
|
|
55
53
|
reject:(RCTPromiseRejectBlock)reject {
|
|
56
54
|
@try {
|
|
57
|
-
NSString *bundlePath = [[
|
|
55
|
+
NSString *bundlePath = [[Airborne sharedInstanceWithNamespace:defaultNamespace] getBundlePath];
|
|
58
56
|
resolve(bundlePath);
|
|
59
57
|
} @catch (NSException *exception) {
|
|
60
58
|
reject(@"AIRBORNE_ERROR", exception.reason, nil);
|
package/package.json
CHANGED
package/ios/AirborneiOS.h
DELETED
|
@@ -1,89 +0,0 @@
|
|
|
1
|
-
#import <Foundation/Foundation.h>
|
|
2
|
-
|
|
3
|
-
NS_ASSUME_NONNULL_BEGIN
|
|
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
|
-
* Returns the namespace, an unique identifier of the app/sdk.
|
|
24
|
-
*
|
|
25
|
-
* This namespace is used to store the files in the internal storage.
|
|
26
|
-
* and also to read the bundled release config.
|
|
27
|
-
*
|
|
28
|
-
* @return the namespace, an unique identifier of the app/sdk.
|
|
29
|
-
* If not implemented, defaults to an default.
|
|
30
|
-
*/
|
|
31
|
-
- (NSString *)getNamespace;
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
- (NSBundle *)getBundle;
|
|
35
|
-
|
|
36
|
-
/**
|
|
37
|
-
* Called when the OTA boot process has completed successfully.
|
|
38
|
-
*
|
|
39
|
-
* This callback indicates that the application is ready to load the packages & resources
|
|
40
|
-
*
|
|
41
|
-
* @note This method is called on a background queue. Dispatch UI updates
|
|
42
|
-
* to the main queue if needed.
|
|
43
|
-
* @note Boot completion occurs even if some downloads failed or timed out.
|
|
44
|
-
* Check the release configuration for actual status.
|
|
45
|
-
*/
|
|
46
|
-
- (void)startApp:(NSString *) bundlePath;
|
|
47
|
-
|
|
48
|
-
/**
|
|
49
|
-
* Called when significant events occur during the OTA update process.
|
|
50
|
-
*
|
|
51
|
-
* This callback provides detailed information about:
|
|
52
|
-
* - Download progress and completion
|
|
53
|
-
* - Error conditions and failures
|
|
54
|
-
* - Performance metrics and timing
|
|
55
|
-
* - State transitions in the update process
|
|
56
|
-
*
|
|
57
|
-
* @param level The severity level of the event ("info", "error", "warning")
|
|
58
|
-
* @param label A category label for the event (e.g., "ota_update")
|
|
59
|
-
* @param key A specific identifier for the event type
|
|
60
|
-
* @param value Additional structured data about the event
|
|
61
|
-
* @param category The broad category of the event (e.g., "lifecycle")
|
|
62
|
-
* @param subcategory The specific subcategory (e.g., "hyperota")
|
|
63
|
-
*
|
|
64
|
-
* @note Use this for logging, analytics, debugging, and monitoring OTA performance.
|
|
65
|
-
*/
|
|
66
|
-
- (void)onEventWithLevel:(NSString *)level
|
|
67
|
-
label:(NSString *)label
|
|
68
|
-
key:(NSString *)key
|
|
69
|
-
value:(NSDictionary<NSString *, id> *)value
|
|
70
|
-
category:(NSString *)category
|
|
71
|
-
subcategory:(NSString *)subcategory;
|
|
72
|
-
|
|
73
|
-
@end
|
|
74
|
-
|
|
75
|
-
typedef void (^HyperOTALazyDownloadCallback)(NSString *filePath, BOOL success);
|
|
76
|
-
typedef void (^HyperOTALazySplitsCallback)(BOOL success);
|
|
77
|
-
|
|
78
|
-
@interface AirborneiOS : NSObject
|
|
79
|
-
|
|
80
|
-
+ (instancetype)sharedInstanceWithNamespace:(NSString *)ns;
|
|
81
|
-
|
|
82
|
-
- (void) loadWithReleaseConfig:(NSString *) rcurl delegate:(id<AirborneReactDelegate>) delegate;
|
|
83
|
-
- (NSString *)getBundlePath;
|
|
84
|
-
- (NSString *)getFileContent:(NSString *)filePath;
|
|
85
|
-
- (NSString *)getReleaseConfig;
|
|
86
|
-
|
|
87
|
-
@end
|
|
88
|
-
|
|
89
|
-
NS_ASSUME_NONNULL_END
|
package/ios/AirborneiOS.m
DELETED
|
@@ -1,120 +0,0 @@
|
|
|
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
|
-
if(_delegate == nil) return @"default";
|
|
25
|
-
return [_delegate getNamespace];
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
- (NSBundle *)bundle{
|
|
29
|
-
if(_delegate == nil) return NSBundle.mainBundle;
|
|
30
|
-
return [_delegate getBundle];
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
- (NSDictionary *)dimensions{
|
|
34
|
-
if(_delegate == nil) return @{};
|
|
35
|
-
return [_delegate getDimensions];
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
- (void)onBootCompleteWithIndexBundlePath:(NSString *)indexBundlePath{
|
|
39
|
-
if (_delegate == nil) return;
|
|
40
|
-
[_delegate startApp:indexBundlePath];
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
-(void)onEventWithLevel:(NSString *)level label:(NSString *)label key:(NSString *)key value:(NSDictionary<NSString *,id> *)value category:(NSString *)category subcategory:(NSString *)subcategory{
|
|
44
|
-
if (_delegate == nil) return;
|
|
45
|
-
[_delegate onEventWithLevel:level label:label key:key value:value category:category subcategory:subcategory];
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
@end
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
@interface AirborneiOS ()
|
|
52
|
-
@property (nonatomic, strong) NSString* ns;
|
|
53
|
-
@property (nonatomic, strong) AirborneServices* air;
|
|
54
|
-
@property (nonatomic, strong) id<AirborneDelegate> delegate;
|
|
55
|
-
@property (nonatomic, strong) AirborneLocalDelegate* delegateproxy;
|
|
56
|
-
|
|
57
|
-
@end
|
|
58
|
-
|
|
59
|
-
@implementation AirborneiOS
|
|
60
|
-
|
|
61
|
-
+ (instancetype)sharedInstanceWithNamespace:(NSString *)namespace{
|
|
62
|
-
static NSMutableDictionary<NSString *, AirborneiOS *> *instances = nil;
|
|
63
|
-
static dispatch_queue_t syncQueue;
|
|
64
|
-
static dispatch_once_t onceToken;
|
|
65
|
-
|
|
66
|
-
// Initialize dictionary and queue once
|
|
67
|
-
dispatch_once(&onceToken, ^{
|
|
68
|
-
instances = [NSMutableDictionary dictionary];
|
|
69
|
-
syncQueue = dispatch_queue_create("in.juspay.Airborne.singleton", DISPATCH_QUEUE_CONCURRENT);
|
|
70
|
-
});
|
|
71
|
-
|
|
72
|
-
__block AirborneiOS *instance = nil;
|
|
73
|
-
|
|
74
|
-
// Read existing instance (concurrent)
|
|
75
|
-
dispatch_sync(syncQueue, ^{
|
|
76
|
-
instance = instances[namespace];
|
|
77
|
-
});
|
|
78
|
-
|
|
79
|
-
if (instance == nil) {
|
|
80
|
-
// Write new instance (barrier to prevent concurrent writes)
|
|
81
|
-
dispatch_barrier_sync(syncQueue, ^{
|
|
82
|
-
if (!instances[namespace]) {
|
|
83
|
-
instances[namespace] = [[self alloc] initWithNamespace:namespace];
|
|
84
|
-
}
|
|
85
|
-
instance = instances[namespace];
|
|
86
|
-
});
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
return instance;
|
|
90
|
-
}
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
- (instancetype)initWithNamespace:(NSString *) ns{
|
|
94
|
-
self = [super init];
|
|
95
|
-
if (self) {
|
|
96
|
-
_ns = ns;
|
|
97
|
-
|
|
98
|
-
}
|
|
99
|
-
return self;
|
|
100
|
-
}
|
|
101
|
-
|
|
102
|
-
- (void)loadWithReleaseConfig:(NSString *) rcurl delegate:(id<AirborneReactDelegate>) delegate{
|
|
103
|
-
_delegateproxy = [[AirborneLocalDelegate alloc] initWithNamespace: self.ns delegate:delegate];
|
|
104
|
-
_air = [[AirborneServices alloc] initWithReleaseConfigURL:rcurl delegate:_delegateproxy];
|
|
105
|
-
}
|
|
106
|
-
|
|
107
|
-
- (NSString *)getBundlePath {
|
|
108
|
-
return [_air getIndexBundlePath] ;
|
|
109
|
-
}
|
|
110
|
-
|
|
111
|
-
- (NSString *)getFileContent:(NSString *)filePath {
|
|
112
|
-
return [_air getFileContentAtPath:filePath];
|
|
113
|
-
}
|
|
114
|
-
|
|
115
|
-
- (NSString *)getReleaseConfig {
|
|
116
|
-
return [_air getReleaseConfig];
|
|
117
|
-
}
|
|
118
|
-
|
|
119
|
-
@end
|
|
120
|
-
|