Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[menu-bar] Improve performance when running cli commands #61

Merged
merged 2 commits into from
Sep 15, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@

### 🎉 New features

- Improved performance when running `cli` commands. ([#61](https://github.com/expo/orbit/pull/61) by [@gabrieldonadel](https://github.com/gabrieldonadel))
- Added drag and drop support for installing apps. ([#57](https://github.com/expo/orbit/pull/57) by [@gabrieldonadel](https://github.com/gabrieldonadel))
- Added support for installing apps directly from Finder. ([#56](https://github.com/expo/orbit/pull/56) by [@gabrieldonadel](https://github.com/gabrieldonadel))
- Added local HTTP server to circumvent deep-link limitations. ([#52](https://github.com/expo/orbit/pull/52), [#53](https://github.com/expo/orbit/pull/53), [#54](https://github.com/expo/orbit/pull/54), [#55](https://github.com/expo/orbit/pull/55) by [@gabrieldonadel](https://github.com/gabrieldonadel))
Expand Down
133 changes: 60 additions & 73 deletions apps/menu-bar/macos/ExpoMenuBar-macOS/MenuBarModule.m
Original file line number Diff line number Diff line change
Expand Up @@ -124,85 +124,72 @@ - (NSDictionary *)constantsToExport
resolver:(RCTPromiseResolveBlock)resolve
rejecter:(RCTPromiseRejectBlock)reject)
{
NSTask *task = [[NSTask alloc] init];
NSPipe *pipe = [NSPipe pipe];
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
NSTask *task = [[NSTask alloc] init];
NSPipe *pipe = [NSPipe pipe];

NSString *executablePath = [[NSBundle mainBundle] pathForResource:getCliResourceNameForArch() ofType:nil];
NSString *executablePath = [[NSBundle mainBundle] pathForResource:getCliResourceNameForArch() ofType:nil];

[task setLaunchPath:executablePath];
[task setArguments:[@[command] arrayByAddingObjectsFromArray:arguments]];
[task setLaunchPath:executablePath];
[task setArguments:[@[command] arrayByAddingObjectsFromArray:arguments]];

NSMutableDictionary *environment = [[NSMutableDictionary alloc] initWithDictionary:[[NSProcessInfo processInfo] environment]];
// Retrieve the envVars from NSUserDefaults
NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults];
NSDictionary *envVars = [userDefaults objectForKey:@"envVars"];
NSMutableDictionary *environment = [NSMutableDictionary dictionaryWithDictionary:[[NSProcessInfo processInfo] environment]];
// Retrieve the envVars from NSUserDefaults
NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults];
NSDictionary *envVars = [userDefaults objectForKey:@"envVars"];

// Check if the retrieved object is indeed a NSDictionary
if ([envVars isKindOfClass:[NSDictionary class]] && [envVars count] > 0) {
for (NSString *key in envVars) {
[environment setObject:envVars[key] forKey:key];
NSLog(@"Key: %@ - value: %@", key,envVars[key]);
// Check if the retrieved object is indeed a NSDictionary
if ([envVars isKindOfClass:[NSDictionary class]] && [envVars count] > 0) {
[environment addEntriesFromDictionary:envVars];
[task setEnvironment:environment];
}
[task setEnvironment:environment];
}

[task setStandardOutput:pipe];
[task setStandardError:pipe];

NSFileHandle *file = [pipe fileHandleForReading];
__block NSString *returnOutput = @"";
__block BOOL hasReachedReturnOutput = false;
__block BOOL hasReachedError = false;

[task launch];

NSNotificationCenter *notificationCenter = [NSNotificationCenter defaultCenter];
[notificationCenter addObserverForName:NSFileHandleReadCompletionNotification
object:file
queue:nil
usingBlock:^(NSNotification *notification) {
NSData *chunk = notification.userInfo[NSFileHandleNotificationDataItem];
NSString *wholeOutput = [[NSString alloc] initWithData:chunk encoding:NSUTF8StringEncoding];
NSArray *outputs = [wholeOutput componentsSeparatedByCharactersInSet:[NSCharacterSet newlineCharacterSet]];

for (NSString *output in outputs) {
if ([output isEqualToString:@""]) {
continue;
}

if(hasReachedReturnOutput || hasReachedError){
returnOutput = [returnOutput stringByAppendingString:output];
} else if([output isEqualToString:@"---- return output ----"]){
hasReachedReturnOutput = true;
} else if([output isEqualToString:@"---- thrown error ----"]){
hasReachedError = true;
} else if(self->hasListeners && output.length > 0 && ![output isEqualToString:@"\n"]){
NSDictionary *eventData = @{
@"listenerId": listenerId,
@"output": output
};
[self sendEventWithName:@"onCLIOutput" body:eventData];
}
}

[file readInBackgroundAndNotify];
}];
[notificationCenter addObserverForName:NSTaskDidTerminateNotification
object:task
queue:nil
usingBlock:^(NSNotification *notification) {
[notificationCenter removeObserver:self];
}];

[file readInBackgroundAndNotify];
[task waitUntilExit];

if(hasReachedError){
reject(@"CLI_ERROR", returnOutput, nil);
return;
}

resolve(hasReachedReturnOutput ? returnOutput : nil);
[task setStandardOutput:pipe];
[task setStandardError:pipe];

NSFileHandle *file = [pipe fileHandleForReading];
NSMutableString *returnOutput = [NSMutableString string];
__block BOOL hasReachedReturnOutput = NO;
__block BOOL hasReachedError = NO;

[file setReadabilityHandler:^(NSFileHandle * _Nonnull handle) {
NSData *availableData = [handle availableData];
NSString *wholeOutput = [[NSString alloc] initWithData:availableData encoding:NSUTF8StringEncoding];
NSArray *outputs = [wholeOutput componentsSeparatedByCharactersInSet:[NSCharacterSet newlineCharacterSet]];

for (NSString *output in outputs) {
if ([output isEqualToString:@""]) {
continue;
}

if(hasReachedReturnOutput || hasReachedError){
[returnOutput appendString:output];
} else if([output isEqualToString:@"---- return output ----"]) {
hasReachedReturnOutput = YES;
} else if([output isEqualToString:@"---- thrown error ----"]) {
hasReachedError = YES;
} else if(self->hasListeners && output.length > 0 && ![output isEqualToString:@"\n"]) {
NSDictionary *eventData = @{
@"listenerId": listenerId,
@"output": output
};
[self sendEventWithName:@"onCLIOutput" body:eventData];
}
}
}];

[task setTerminationHandler:^(NSTask * _Nonnull task) {
[file setReadabilityHandler:nil];

if(hasReachedError){
reject(@"CLI_ERROR", returnOutput, nil);
} else {
resolve(hasReachedReturnOutput ? returnOutput : nil);
}
}];

[task launch];
});
}

RCT_EXPORT_METHOD(setLoginItemEnabled:(BOOL)enabled
Expand Down