Skip to content

Commit

Permalink
Merge pull request flutter#426 from iansf/ios_refresh
Browse files Browse the repository at this point in the history
Allow iOS apps to restart by copying the app.skyx to the Documents directory on the device.
  • Loading branch information
iansf committed Aug 3, 2015
2 parents 215ffde + 0577988 commit e7d1dc7
Show file tree
Hide file tree
Showing 4 changed files with 156 additions and 1 deletion.
1 change: 1 addition & 0 deletions sky/shell/BUILD.gn
Original file line number Diff line number Diff line change
Expand Up @@ -174,6 +174,7 @@ if (is_android) {

source_set("ios_scaffolding") {
sources = [
"ios/document_watcher.m",
"ios/main_ios.mm",
"ios/sky_app_delegate.h",
"ios/sky_app_delegate.mm",
Expand Down
13 changes: 13 additions & 0 deletions sky/shell/ios/document_watcher.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
// Copyright 2015 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef NDEBUG
#import <Foundation/Foundation.h>

@interface DocumentWatcher : NSThread
- (instancetype)initWithDocumentPath:(NSString*)path callbackBlock:(void (^)(void))callbackBlock;
- (void)cancel;
@end

#endif // !NDEBUG
100 changes: 100 additions & 0 deletions sky/shell/ios/document_watcher.m
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
// Copyright 2015 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef NDEBUG
#import "document_watcher.h"

@interface DocumentWatcher ()

@property(nonatomic, readonly) NSDate* lastModifiedDate;
@property (copy) void (^callbackBlock)(void);

@end

@implementation DocumentWatcher {
NSString* _documentPath;
NSTimer* _timer;
CFRunLoopRef _loop;
}

@synthesize lastModifiedDate = _lastModifiedDate;

- (instancetype)initWithDocumentPath:(NSString*)path callbackBlock:(void (^)(void))callbackBlock {
self = [super init];

if (self) {
_documentPath = path;
self.callbackBlock = callbackBlock;

[self start];
}

return self;
}

- (void)main {
[self onCheck:nil];
_timer = [[NSTimer scheduledTimerWithTimeInterval:1.0
target:self
selector:@selector(onCheck:)
userInfo:nil
repeats:YES] retain];
while (!self.isCancelled) {
_loop = CFRunLoopGetCurrent();
CFRunLoopRunInMode(kCFRunLoopDefaultMode,
[[NSDate distantFuture] timeIntervalSinceNow], YES);
}
}

- (void)_setLastModifiedDate:(NSDate*)lastModifiedDate path:(NSString*)path {
if ([_lastModifiedDate isEqualToDate:lastModifiedDate]) {
return;
}

[_lastModifiedDate release];
_lastModifiedDate = [lastModifiedDate retain];

if (_lastModifiedDate == nil && lastModifiedDate == nil) {
return;
}

dispatch_async(dispatch_get_main_queue(), self.callbackBlock);
}

- (void)onCheck:(id)sender {
if (![[NSFileManager defaultManager] fileExistsAtPath:_documentPath]) {
return;
}

NSError* error = nil;
NSDictionary* attributes = [[NSFileManager defaultManager] attributesOfItemAtPath:_documentPath
error:&error];
if (error != nil) {
NSLog(@"[DocumentWatcher onCheck]: error reading attributes for path %@: %@", _documentPath, error);
return;
}

[self _setLastModifiedDate:attributes.fileModificationDate path:_documentPath];
}

- (void)cancel {
[_timer invalidate];
[_timer release];
_timer = nil;

if (_loop) {
CFRunLoopWakeUp(_loop);
_loop = NULL;
}

[super cancel];
}

- (void)dealloc {
[_documentPath release];
[_lastModifiedDate release];
[super dealloc];
}

@end
#endif // !NDEBUG
43 changes: 42 additions & 1 deletion sky/shell/ios/sky_surface.mm
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,10 @@
#include "sky/shell/shell.h"
#include "sky/shell/ui_delegate.h"

#ifndef NDEBUG
#include "document_watcher.h"
#endif

static inline sky::EventType EventTypeFromUITouchPhase(UITouchPhase phase) {
switch (phase) {
case UITouchPhaseBegan:
Expand Down Expand Up @@ -62,6 +66,10 @@ @implementation SkySurface {

sky::SkyEnginePtr _sky_engine;
scoped_ptr<sky::shell::ShellView> _shell_view;

#ifndef NDEBUG
DocumentWatcher *_document_watcher;
#endif
}

-(instancetype) initWithShellView:(sky::shell::ShellView *) shellView {
Expand Down Expand Up @@ -137,7 +145,24 @@ - (NSString*)skyInitialLoadURL {
}

- (NSString*)skyInitialBundleURL {
return [[NSBundle mainBundle] pathForResource:@"app" ofType:@"skyx"];
NSString *skyxBundlePath = [[NSBundle mainBundle] pathForResource:@"app" ofType:@"skyx"];
#ifndef NDEBUG
NSFileManager *fileManager = [NSFileManager defaultManager];
NSError *error = nil;
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *skyxDocsPath = [documentsDirectory stringByAppendingPathComponent:@"app.skyx"];

if ([fileManager fileExistsAtPath:skyxDocsPath] == NO) {
if ([fileManager copyItemAtPath:skyxBundlePath toPath:skyxDocsPath error:&error]) {
return skyxDocsPath;
}
NSLog(@"Error encountered copying app.skyx from the Bundle to the Documents directory. Dynamic reloading will not be possible. %@", error);
return skyxBundlePath;
}
return skyxDocsPath;
#endif
return skyxBundlePath;
}

- (void)connectToEngineAndLoad {
Expand All @@ -146,6 +171,12 @@ - (void)connectToEngineAndLoad {

NSString *endpoint = self.skyInitialBundleURL;
if (endpoint.length > 0) {
#ifndef NDEBUG
_document_watcher = [[DocumentWatcher alloc] initWithDocumentPath:endpoint callbackBlock:^{
mojo::String string(endpoint.UTF8String);
_sky_engine->RunFromBundle(string);
}];
#endif
// Load from bundle
mojo::String string(endpoint.UTF8String);
_sky_engine->RunFromBundle(string);
Expand All @@ -165,6 +196,16 @@ - (void)notifySurfaceDestruction {
self.platformView->SurfaceDestroyed();
}

#ifndef NDEBUG
- (void)didMoveToWindow {
if (self.window == nil) {
[_document_watcher cancel];
[_document_watcher release];
_document_watcher = nil;
}
}
#endif

#pragma mark - UIResponder overrides for raw touches

- (void)dispatchTouches:(NSSet*)touches phase:(UITouchPhase)phase {
Expand Down

0 comments on commit e7d1dc7

Please sign in to comment.