An amazing project that generates micro reports from tournament results
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

208 lines
8.2 KiB

////////////////////////////////////////////////////////////////////////////
//
// Copyright 2014 Realm Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
////////////////////////////////////////////////////////////////////////////
#import "RLMPRealmPlugin.h"
#import "RLMPSimulatorManager.h"
static RLMPRealmPlugin *sharedPlugin;
static NSString *const RootDeviceSimulatorPath = @"Library/Developer/CoreSimulator/Devices";
static NSString *const DeviceSimulatorApplicationPath = @"data/Containers/Data/Application";
static NSString *const RLMPErrorDomain = @"io.Realm.error";
static NSArray * RLMPGlobFilesAtDirectoryURLWithPredicate(NSFileManager *fileManager, NSURL *directoryURL, NSPredicate *filteredPredicate, BOOL (^handler)(NSURL *URL, NSError *error))
{
NSDirectoryEnumerator *directoryEnumerator = [fileManager enumeratorAtURL:directoryURL
includingPropertiesForKeys:@[NSURLNameKey, NSURLIsDirectoryKey]
options:NSDirectoryEnumerationSkipsHiddenFiles
errorHandler:handler];
NSMutableArray *fileURLs = [NSMutableArray array];
for (NSURL *fileURL in directoryEnumerator) {
NSString *fileName;
[fileURL getResourceValue:&fileName forKey:NSURLNameKey error:nil];
NSString *isDirectory;
[fileURL getResourceValue:&isDirectory forKey:NSURLIsDirectoryKey error:nil];
// Check whether it is a directory or not
if (![isDirectory boolValue]) {
[fileURLs addObject:fileURL];
}
}
return [fileURLs filteredArrayUsingPredicate:filteredPredicate];
}
@interface RLMPRealmPlugin()
@property (nonatomic, strong) NSBundle *bundle;
@property (nonatomic, strong) NSURL *browserUrl;
@end
@implementation RLMPRealmPlugin
+ (void)pluginDidLoad:(NSBundle *)plugin
{
static dispatch_once_t onceToken;
NSString *currentApplicationName = [[NSBundle mainBundle] infoDictionary][@"CFBundleName"];
if ([currentApplicationName isEqual:@"Xcode"]) {
dispatch_once(&onceToken, ^{
sharedPlugin = [[self alloc] initWithBundle:plugin];
});
}
}
- (id)initWithBundle:(NSBundle *)plugin
{
if (self = [super init]) {
// Save reference to plugin's bundle, for resource acccess
self.bundle = plugin;
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(didApplicationFinishLaunchingNotification:)
name:NSApplicationDidFinishLaunchingNotification
object:nil];
}
return self;
}
- (void)didApplicationFinishLaunchingNotification:(NSNotification *)notification
{
// Look for the Realm Browser
NSString *urlString = [[NSWorkspace sharedWorkspace] fullPathForApplication:@"Realm Browser"];
if (urlString) {
self.browserUrl = [NSURL fileURLWithPath:urlString];
// Create menu item to open Browser under File:
NSMenuItem *menuItem = [[NSApp mainMenu] itemWithTitle:@"File"];
if (menuItem) {
[[menuItem submenu] addItem:[NSMenuItem separatorItem]];
NSMenuItem *actionMenuItem = [[NSMenuItem alloc] initWithTitle:@"Open Realm..."
action:@selector(openBrowser)
keyEquivalent:@""];
[actionMenuItem setTarget:self];
[[menuItem submenu] addItem:actionMenuItem];
}
}
else {
NSLog(@"Realm Plugin: Couldn't find Realm Browser. Will not show 'Open Realm...' menu item.");
}
}
- (void)openBrowser
{
// This shouldn't be possible to call without having the Browser installed
if (!self.browserUrl) {
NSString *title = @"Please install the Realm Browser";
NSString *message = @"You need to install the Realm Browser in order to use it from this plugin. Please visit realm.io for more information.";
NSError *error = [NSError errorWithDomain:RLMPErrorDomain
code:-1
userInfo:@{ NSLocalizedDescriptionKey : title,
NSLocalizedRecoverySuggestionErrorKey : message }];
[self showError:error];
return;
}
// Find Device UUID
NSString *bootedSimulatorUUID = [RLMPSimulatorManager bootedSimulatorUUID];
// Find Realm File URL
NSArray *realmFileURLs = [self realmFilesURLWithDeviceUUID:bootedSimulatorUUID];
if (realmFileURLs.count == 0) {
NSString *title = @"Unable to find Realm file";
NSString *message = @"You must launch iOS Simulator with app that uses Realm";
NSError *error = [NSError errorWithDomain:RLMPErrorDomain
code:-1
userInfo:@{ NSLocalizedDescriptionKey : title,
NSLocalizedRecoverySuggestionErrorKey : message }];
[self showError:error];
return;
}
NSMutableArray *arguments = [NSMutableArray array];
for (NSURL *realmFileURL in realmFileURLs) {
[arguments addObject:realmFileURL.path];
}
NSDictionary *configuration = @{ NSWorkspaceLaunchConfigurationArguments : arguments };
// Show confirmation alert if 2 or more files are detected
if (arguments.count > 1) {
NSAlert *alert = [[NSAlert alloc] init];
[alert setMessageText:@"Realm Browser"];
[alert setInformativeText:[NSString stringWithFormat:@"%ld Realm files are detected. Are you sure to open them at once?", arguments.count]];
[alert setAlertStyle:NSInformationalAlertStyle];
[alert addButtonWithTitle:@"OK"];
[alert addButtonWithTitle:@"Cancel"];
[alert beginSheetModalForWindow:[NSApp mainWindow] completionHandler:^(NSModalResponse returnCode) {
if (returnCode == NSAlertFirstButtonReturn) {
[self openRealmBrowserWithConfiguration:configuration];
}
}];
} else {
[self openRealmBrowserWithConfiguration:configuration];
}
}
- (void)openRealmBrowserWithConfiguration:(NSDictionary *)configuration
{
NSError *error;
if (![[NSWorkspace sharedWorkspace] launchApplicationAtURL:self.browserUrl options:NSWorkspaceLaunchNewInstance configuration:configuration error:&error]) {
// This will happen if the Browser was present at Xcode launch and then was deleted
[self showError:error];
}
}
- (NSArray *)realmFilesURLWithDeviceUUID:(NSString *)deviceUUID
{
NSFileManager *fileManager = [NSFileManager defaultManager];
NSURL *homeURL = [NSURL URLWithString:NSHomeDirectory()];
NSMutableString *fullPath = [NSMutableString string];
[fullPath appendFormat:@"%@/%@/%@", RootDeviceSimulatorPath, deviceUUID, DeviceSimulatorApplicationPath];
NSURL *bootedDeviceDirectoryURL = [homeURL URLByAppendingPathComponent:fullPath];
NSArray* fileURLs = RLMPGlobFilesAtDirectoryURLWithPredicate(fileManager, bootedDeviceDirectoryURL, [NSPredicate predicateWithFormat:@"pathExtension == 'realm'"], ^BOOL(NSURL *URL, NSError *error) {
if (error) {
NSLog(@"%@", error);
return NO;
}
return YES;
});
return fileURLs;
}
- (void)showError:(NSError *)error
{
NSAlert *alert = [NSAlert alertWithError:error];
[alert runModal];
}
- (void)dealloc
{
[[NSNotificationCenter defaultCenter] removeObserver:self];
}
@end