Skip to content

Commit

Permalink
Merge pull request #2 from Derewith/update
Browse files Browse the repository at this point in the history
Updated logic for bundle update + some fixes
  • Loading branch information
Derewith authored Nov 22, 2023
2 parents a549ac2 + 35db91d commit f9b7c82
Show file tree
Hide file tree
Showing 4 changed files with 100 additions and 33 deletions.
4 changes: 2 additions & 2 deletions example/ios/BundleUpdaterExample/AppDelegate.mm
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ - (BOOL)application:(UIApplication *)application
self.initialProps = @{};

BundleUpdater *bundleUpdater = [BundleUpdater sharedInstance];
[bundleUpdater initialization:@"9980a7943e0db5892b50f6972b02b4c2a2b3"
[bundleUpdater initialization:@"70df8a199213d53d892a3eddb6f3bf9c4158"
resolve:^(NSString *result) {
NSLog(@"[APP]Initialization success: %@", result);
}
Expand All @@ -25,7 +25,7 @@ - (BOOL)application:(UIApplication *)application

- (NSURL *)sourceURLForBridge:(RCTBridge *)bridge {
BundleUpdater *bundleUpdater = [BundleUpdater sharedInstance];
[bundleUpdater initializeBundle:bridge];
return [bundleUpdater initializeBundle:bridge withKey:@"70df8a199213d53d892a3eddb6f3bf9c4158"];
}

@end
5 changes: 3 additions & 2 deletions ios/BundleUpdater.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,12 @@
@interface BundleUpdater : NSObject <RCTBridgeModule, UIViewControllerTransitioningDelegate>
@property (nonatomic, weak) RCTBridge *bridge;

+ (instancetype)sharedInstance;
- (void)initialization:(NSString *)apiKey
resolve:(void (^)(NSString *))resolve
reject:(void (^)(NSString *, NSString *, NSError *))reject;
- (NSURL *)initializeBundle:(RCTBridge *)bridge;
+ (instancetype)sharedInstance;
- (NSURL *)initializeBundle:(RCTBridge *)bridge withKey:(NSString *)key;
- (void)reload;
#endif

@end
85 changes: 67 additions & 18 deletions ios/BundleUpdater.mm
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,15 @@
#import <React/RCTBridgeModule.h>
#import <sys/utsname.h>
#import <React/RCTBundleURLProvider.h>
#import <React/RCTReloadCommand.h>

@implementation BundleUpdater
@synthesize bridge = _bridge;

RCT_EXPORT_MODULE()

NSString *apiUrl = @"http://192.168.0.103:3003";
NSString *apiUrl = @"http://192.168.10.37:3003";
NSDictionary *update_config = @{};

+ (instancetype)sharedInstance{
static BundleUpdater *sharedInstance = nil;
Expand Down Expand Up @@ -49,6 +51,9 @@ - (NSString *)loadHashFromDisk {

- (void)saveNewBundleAndHashToDisk:(NSData *)script
hashString:(NSString *)hashString {
// Save the bundle on a folder with the sdk key as path
// NSString *folder = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) firstObject];
// NSFileManager *manager = [NSFileManager defaultManager];
NSString *scriptPath = [[NSSearchPathForDirectoriesInDomains(
NSDocumentDirectory, NSUserDomainMask, YES) firstObject]
stringByAppendingPathComponent:@"main.jsbundle"];
Expand Down Expand Up @@ -179,7 +184,8 @@ - (void)initialization:(NSString *)apiKey
// 'initialization:resolve:reject:': 'void (^__strong)(NSString *__strong)'
// vs '__strong RCTPromiseResolveBlock' (aka 'void (^__strong)(__strong
// id)')

NSString *savedBundle = [[NSUserDefaults standardUserDefaults]
stringForKey:@"bundleId"];
NSString *urlString =
[NSString stringWithFormat:@"%@/project/%@/initialize", apiUrl, apiKey];

Expand All @@ -188,10 +194,15 @@ - (void)initialization:(NSString *)apiKey
[request setHTTPMethod:@"POST"];

// Create a dictionary to hold the field values
NSDictionary *fields = [[NSMutableDictionary alloc]
initWithDictionary:@{@"metaData" : [self getMetaData]}];
// NSDictionary *fields = [[NSMutableDictionary alloc]
// initWithDictionary:@{@"metaData" : [self getMetaData]}];
NSDictionary *body = [[NSMutableDictionary alloc]
initWithDictionary:@{
@"metaData" : [self getMetaData],
@"bundleId" : savedBundle ? savedBundle : @""
}];
NSError *jsonError;
NSData *jsonData = [NSJSONSerialization dataWithJSONObject:fields
NSData *jsonData = [NSJSONSerialization dataWithJSONObject:body
options:0
error:&jsonError];
if (!jsonData) {
Expand All @@ -211,7 +222,18 @@ - (void)initialization:(NSString *)apiKey
[NSURLSessionConfiguration defaultSessionConfiguration];
NSURLSession *session =
[NSURLSession sessionWithConfiguration:sessionConfiguration];

// MARK: - TO TEST THE MODAL
// dispatch_async(dispatch_get_main_queue(), ^{
// [self showBottomSheet:@{
// @"button_color": @"#FF1542",
// @"button_label": @"Aggiorna ora",
// @"button_link" : @"https://xylem.com",
// @"image" : @"https://i.ibb.co/ngTj6wc/xylem-italia-logo.jpg",
// @"message": @"Per continuare a utilizzare Xylem X, aggiorna per le ultime funzionalita e correzioni di bug.",
// @"privacy": @"https://develondigital.com",
// @"title": @"Aggiornamento disponibile!"
// }];
// });
// Create the task to send the request
NSURLSessionDataTask *dataTask = [session
dataTaskWithRequest:request
Expand All @@ -221,8 +243,8 @@ - (void)initialization:(NSString *)apiKey
NSLog(@"[SDK] initialization error: %@", error);
reject(@"error", @"Initialization error", error);
} else {
NSHTTPURLResponse *httpResponse =
(NSHTTPURLResponse *)response;
// NSHTTPURLResponse *httpResponse =
// (NSHTTPURLResponse *)response;
NSLog(@"[SDK] initialization response: %@",
[[NSString alloc] initWithData:data
encoding:NSUTF8StringEncoding]);
Expand All @@ -239,25 +261,50 @@ - (void)initialization:(NSString *)apiKey
NSLog(@"[SDK] JSON parsing error: %@", jsonError);
return;
}

if (responseDict[@"update_required"]) {
// Pass the "update_required" object to the showBottomSheet
// method
dispatch_async(dispatch_get_main_queue(), ^{
[self showBottomSheet:responseDict[@"update_required"]];
});
NSLog(@"%@", responseDict.description);
@try {
if ([responseDict valueForKey:@"update_required"]) {
// Pass the "update_required" object to the showBottomSheet
// method
update_config = [responseDict valueForKey:@"update_required"];
NSString *bundle_id = [responseDict valueForKey:@"bundleId"];
[[NSUserDefaults standardUserDefaults] setObject:bundle_id forKey:@"bundleId"];
// dispatch_async(dispatch_get_main_queue(), ^{
// [self showBottomSheet:responseDict[@"update_required"]];
// });
}
} @catch (NSException *exception) {
NSLog(@"Update not required");
}
}
}];

[dataTask resume];
}

- (NSURL *)initializeBundle:(RCTBridge *)bridge {
- (NSURL *)initializeBundle:(RCTBridge *)bridge withKey:(NSString *)key{
#if DEBUG
return [[RCTBundleURLProvider sharedSettings]
jsBundleURLForBundleRoot:@"index"];
#else
//verify if the key is the same as the previous one
NSString *oldKey = [[NSUserDefaults standardUserDefaults] stringForKey:@"bundleKey"];
if(!oldKey || ![oldKey isEqualToString:key]){
NSLog(@"detected api key change");
//if not, delete the old bundle
NSString *documentDirectoryJSBundleFilePath =
[[NSSearchPathForDirectoriesInDomains(
NSDocumentDirectory, NSUserDomainMask, YES) firstObject]
stringByAppendingPathComponent:@"main.jsbundle"];
BOOL isDir;
BOOL fileExistsAtPath = [[NSFileManager defaultManager]
fileExistsAtPath:documentDirectoryJSBundleFilePath
isDirectory:&isDir];
if (fileExistsAtPath) {
[[NSFileManager defaultManager] removeItemAtPath:documentDirectoryJSBundleFilePath error:nil];
}
[[NSUserDefaults standardUserDefaults] setObject:key forKey:@"bundleKey"];
}
// Check if there is the main.jsbundle file in the Document directory
NSString *documentDirectoryJSBundleFilePath =
[[NSSearchPathForDirectoriesInDomains(
Expand Down Expand Up @@ -340,6 +387,9 @@ - (NSURL *)initializeBundle:(RCTBridge *)bridge {
[self saveNewBundleAndHashToDisk:script
hashString:hashString];
NSLog(@"[SDK] SAVED NEW BUNDLE CORRECTLY");
dispatch_async(dispatch_get_main_queue(), ^{
[self showBottomSheet:update_config];
});
} else {
NSLog(@"[SDK] BUNDLE IS UP TO DATE");
}
Expand All @@ -364,8 +414,7 @@ - (NSURL *)initializeBundle:(RCTBridge *)bridge {

RCT_EXPORT_METHOD(reload) {
dispatch_async(dispatch_get_main_queue(), ^{
[self.bridge requestReload];
// TODO fix 'requestReload' is deprecated: Use RCTReloadCommand instead
RCTTriggerReloadCommandListeners(@"bundle changed");
});
}

Expand Down
39 changes: 28 additions & 11 deletions ios/BundleUpdaterBottomSheetViewController.mm
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
#import "BundleUpdaterButton.h"
#import "UIColor+HexString.h"
#import <SDWebImage/UIImageView+WebCache.h>

#import "BundleUpdater.h"
@implementation BundleUpdaterBottomSheetViewController

- (UIFont *)customFontWithSize:(CGFloat)size {
Expand Down Expand Up @@ -42,6 +42,12 @@ - (void)visitwebsitebuttonTapped:(UIButton *)sender {
}
}

- (void)reloadApp:(UIButton *)sender {
[[BundleUpdater sharedInstance] reload];
// hide the modal
[self dismissViewControllerAnimated:YES completion:nil];
}

- (void)viewDidLoad {
[super viewDidLoad];

Expand Down Expand Up @@ -72,7 +78,7 @@ - (void)viewDidLoad {
// Create the background view
self.backgroundView = [[UIView alloc] initWithFrame:self.view.bounds];
self.backgroundView.backgroundColor = [UIColor blackColor];
self.backgroundView.alpha = 0.5;
self.backgroundView.alpha = 0;
[self.view addSubview:self.backgroundView];

// Create the modal view
Expand All @@ -82,16 +88,21 @@ - (void)viewDidLoad {
self.modalView = [[UIView alloc]
initWithFrame:CGRectMake(0, modalY, self.view.bounds.size.width,
modalHeight)];

self.modalView.backgroundColor = [UIColor whiteColor];
self.modalView.layer.borderWidth = 0.1f;
self.modalView.layer.borderColor = [UIColor blackColor].CGColor;
self.modalView.layer.cornerRadius = 20;

UIBezierPath *maskPath = [UIBezierPath
bezierPathWithRoundedRect:self.modalView.bounds
byRoundingCorners:(UIRectCornerTopLeft | UIRectCornerTopRight)
cornerRadii:CGSizeMake(20.0, 20.0)];
CAShapeLayer *maskLayer = [[CAShapeLayer alloc] init];
maskLayer.frame = self.modalView.bounds;
maskLayer.path = maskPath.CGPath;
self.modalView.layer.mask = maskLayer;

// UIBezierPath *maskPath = [UIBezierPath
// bezierPathWithRoundedRect:self.modalView.bounds
// byRoundingCorners:(UIRectCornerTopLeft | UIRectCornerTopRight)
// cornerRadii:CGSizeMake(20.0, 20.0)];
// CAShapeLayer *maskLayer = [[CAShapeLayer alloc] init];
// maskLayer.frame = self.modalView.bounds;
// maskLayer.path = maskPath.CGPath;
// self.modalView.layer.mask = maskLayer;

[self.view addSubview:self.modalView];

Expand Down Expand Up @@ -158,7 +169,7 @@ - (void)viewDidLoad {
forState:UIControlStateNormal];
[self.button setCenter:CGPointMake(screenWidth / 2, self.button.center.y)];
[self.button addTarget:self
action:@selector(visitwebsitebuttonTapped:)
action:@selector(reloadApp:)
forControlEvents:UIControlEventTouchUpInside];

// footerLogo
Expand Down Expand Up @@ -226,6 +237,12 @@ - (void)viewDidLoad {
// [self.view setNeedsUpdateConstraints];
}

-(void)viewDidAppear:(BOOL)animated{
[super viewDidAppear:animated];
[UIView animateWithDuration:0.3 animations:^{
self.backgroundView.alpha = 0.5;
}];
}
- (void)updateViewConstraints {
[super updateViewConstraints];

Expand Down

0 comments on commit f9b7c82

Please sign in to comment.