Permalink
Browse files

Show progress of syncing

  • Loading branch information...
1 parent 0dc20af commit 7b3169d2b88f73813ae4d5f804e9b67b9c5399f0 @snej snej committed Aug 15, 2011
@@ -355,6 +355,7 @@
buildSettings = {
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
GCC_C_LANGUAGE_STANDARD = c99;
+ GCC_PREPROCESSOR_DEFINITIONS = "DEBUG=1";
GCC_TREAT_WARNINGS_AS_ERRORS = YES;
GCC_VERSION = com.apple.compilers.llvm.clang.1_0;
GCC_WARN_ABOUT_RETURN_TYPE = YES;
@@ -6,8 +6,6 @@
<string>English</string>
<key>CFBundleDisplayName</key>
<string>Grocery Sync</string>
- <key>CFBundleDocumentTypes</key>
- <array/>
<key>CFBundleExecutable</key>
<string>${EXECUTABLE_NAME}</string>
<key>CFBundleIconFile</key>
@@ -22,8 +20,6 @@
<string>APPL</string>
<key>CFBundleSignature</key>
<string>codm</string>
- <key>CFBundleURLTypes</key>
- <array/>
<key>CFBundleVersion</key>
<string>1.0</string>
<key>LSRequiresIPhoneOS</key>
@@ -32,11 +28,5 @@
<string>MainWindow</string>
<key>UISupportedInterfaceOrientations</key>
<array/>
- <key>UTExportedTypeDeclarations</key>
- <array/>
- <key>UTImportedTypeDeclarations</key>
- <array/>
- <key>UIApplicationExitsOnSuspend</key>
- <true/>
</dict>
</plist>
View
@@ -56,6 +56,7 @@ @implementation DemoAppDelegate
// Override point for customization after application launch.
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
+ NSLog(@"------ application:didFinishLaunchingWithOptions:");
#ifdef kDefaultSyncDbURL
// Register the default value of the pref for the remote database URL to sync with:
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
@@ -128,14 +129,27 @@ -(void)couchbaseDidStart:(NSURL *)serverURL {
}
+- (void)applicationWillResignActive:(UIApplication *)application {
+ NSLog(@"------ applicationWillResignActive");
+}
+
- (void)applicationDidEnterBackground:(UIApplication *)application {
+ NSLog(@"------ applicationDidEnterBackground");
// Make sure all transactions complete, because going into the background will
// close down the CouchDB server:
[RESTOperation wait: self.database.activeOperations];
}
+- (void)applicationWillEnterForeground:(UIApplication *)application {
+ NSLog(@"------ applicationWillEnterForeground");
+}
+
+- (void)applicationDidBecomeActive:(UIApplication *)application {
+ NSLog(@"------ applicationDidBecomeActive");
+}
- (void)applicationWillTerminate:(UIApplication *)application {
+ NSLog(@"------ applicationWillTerminate");
// Make sure all transactions complete before quitting:
[RESTOperation wait: self.database.activeOperations];
}
@@ -163,7 +177,7 @@ -(void)removeSplash {
// If 'fatal' is true, the app will quit when it's pressed.
- (void)showAlert: (NSString*)message error: (NSError*)error fatal: (BOOL)fatal {
if (error) {
- message = [NSString stringWithFormat: @"%@\n\n%@", message, error.localizedFailureReason];
+ message = [NSString stringWithFormat: @"%@\n\n%@", message, error.localizedDescription];
}
UIAlertView* alert = [[UIAlertView alloc] initWithTitle: (fatal ? @"Fatal Error" : @"Error")
message: message
@@ -20,16 +20,19 @@
#import <UIKit/UIKit.h>
#import <CouchCocoa/CouchUITableSource.h>
-@class CouchDatabase;
+@class CouchDatabase, CouchReplication;
@interface RootViewController : UIViewController <CouchUITableDelegate, UITextFieldDelegate>
{
CouchDatabase *database;
NSURL* remoteSyncURL;
+ CouchReplication* _pull;
+ CouchReplication* _push;
- UIActivityIndicatorView *activity;
UITableView *tableView;
+ IBOutlet UIProgressView *progress;
+ BOOL showingSyncButton;
IBOutlet UITextField *addItemTextField;
IBOutlet UIImageView *addItemBackground;
}
View
@@ -28,18 +28,20 @@
@interface RootViewController ()
-@property(nonatomic, retain)UIActivityIndicatorView *activity;
@property(nonatomic, retain)CouchDatabase *database;
@property(nonatomic, retain)NSURL* remoteSyncURL;
+- (void)updateSyncURL;
+- (void)showSyncButton;
+- (void)showSyncStatus;
- (IBAction)configureSync:(id)sender;
+- (void)stopSync;
@end
@implementation RootViewController
@synthesize dataSource;
-@synthesize activity;
@synthesize database;
@synthesize tableView;
@synthesize remoteSyncURL;
@@ -59,20 +61,7 @@ - (void)viewDidLoad {
action: @selector(deleteCheckedItems:)];
self.navigationItem.leftBarButtonItem = [deleteButton autorelease];
- UIBarButtonItem* syncButton = [[UIBarButtonItem alloc] initWithTitle: @"Sync"
- style:UIBarButtonItemStylePlain
- target: self
- action: @selector(configureSync:)];
- self.navigationItem.rightBarButtonItem = [syncButton autorelease];
-
- /*
- self.activity = [[[UIActivityIndicatorView alloc]
- initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleWhite] autorelease];
- [self.activity startAnimating];
- UIBarButtonItem* activityButtonItem = [[UIBarButtonItem alloc] initWithCustomView:activity];
- activityButtonItem.enabled = NO;
- self.navigationItem.rightBarButtonItem = [activityButtonItem autorelease];
- */
+ [self showSyncButton];
[self.tableView setBackgroundView:nil];
[self.tableView setBackgroundColor:[UIColor clearColor]];
@@ -85,54 +74,20 @@ - (void)viewDidLoad {
- (void)dealloc {
+ [self stopSync];
[database release];
[super dealloc];
}
-- (void)showErrorAlert: (NSString*)message forOperation: (RESTOperation*)op {
- NSLog(@"%@: op=%@, error=%@", message, op, op.error);
- [(DemoAppDelegate*)[[UIApplication sharedApplication] delegate]
- showAlert: message error: op.error fatal: NO];
-}
-
-
-- (void)updateSyncURL {
- if (!self.database)
- return;
- NSURL* newRemoteURL = nil;
- NSString *syncpoint = [[NSUserDefaults standardUserDefaults] objectForKey:@"syncpoint"];
- if (syncpoint.length > 0)
- newRemoteURL = [NSURL URLWithString:syncpoint];
-
- if (newRemoteURL != remoteSyncURL && ![newRemoteURL isEqual: remoteSyncURL]) {
- // Set up synchronization to/from a remote database:
- NSLog(@"Changing sync to <%@>", newRemoteURL.absoluteString);
- self.remoteSyncURL = newRemoteURL;
- RESTOperation *pull = [database pullFromDatabaseAtURL: newRemoteURL
- options: kCouchReplicationContinuous];
- [pull onCompletion:^() {
- if (pull.isSuccessful)
- NSLog(@"continous sync triggered from %@", syncpoint);
- else
- [self showErrorAlert: @"Unable to sync with the server. You may still work offline."
- forOperation: pull];
- }];
-
- RESTOperation *push = [database pushToDatabaseAtURL: newRemoteURL
- options: kCouchReplicationContinuous];
- [push onCompletion:^() {
- if (push.isSuccessful)
- NSLog(@"continous sync triggered to %@", syncpoint);
- else
- [self showErrorAlert: @"Unable to sync with the server. You may still work offline."
- forOperation: push];
- }];
- }
+- (void)viewWillAppear:(BOOL)animated {
+ [super viewWillAppear: animated];
+ // Check for changes after returning from the sync confic view:
+ [self updateSyncURL];
}
--(void)useDatabase:(CouchDatabase*)theDatabase {
+- (void)useDatabase:(CouchDatabase*)theDatabase {
self.database = theDatabase;
CouchLiveQuery* query = [[database getAllDocuments] asLiveQuery];
query.descending = YES; // Sort by descending ID, which will imply descending create time
@@ -142,32 +97,16 @@ -(void)useDatabase:(CouchDatabase*)theDatabase {
}
-- (void)viewWillAppear:(BOOL)animated {
- [super viewWillAppear: animated];
- // Check for changes after returning from the sync confic view:
- [self updateSyncURL];
-}
-
-
-- (IBAction)configureSync:(id)sender {
- UINavigationController* navController = (UINavigationController*)self.parentViewController;
- ConfigViewController* controller = [[ConfigViewController alloc] init];
- [navController pushViewController: controller animated: YES];
- [controller release];
+- (void)showErrorAlert: (NSString*)message forOperation: (RESTOperation*)op {
+ NSLog(@"%@: op=%@, error=%@", message, op, op.error);
+ [(DemoAppDelegate*)[[UIApplication sharedApplication] delegate]
+ showAlert: message error: op.error fatal: NO];
}
#pragma mark - Couch table source delegate
-- (void)couchTableSource:(CouchUITableSource*)source
- willUpdateFromQuery:(CouchLiveQuery*)query
-{
- // Turn off the activity indicator as soon as we get results on the initial load.
- [self.activity stopAnimating];
-}
-
-
// Customize the appearance of table view cells.
- (void)couchTableSource:(CouchUITableSource*)source
willUseCell:(UITableViewCell*)cell
@@ -323,4 +262,99 @@ -(void)textFieldDidEndEditing:(UITextField *)textField {
}
+#pragma mark - SYNC:
+
+
+- (IBAction)configureSync:(id)sender {
+ UINavigationController* navController = (UINavigationController*)self.parentViewController;
+ ConfigViewController* controller = [[ConfigViewController alloc] init];
+ [navController pushViewController: controller animated: YES];
+ [controller release];
+}
+
+
+- (void)updateSyncURL {
+ if (!self.database)
+ return;
+ NSURL* newRemoteURL = nil;
+ NSString *syncpoint = [[NSUserDefaults standardUserDefaults] objectForKey:@"syncpoint"];
+ if (syncpoint.length > 0)
+ newRemoteURL = [NSURL URLWithString:syncpoint];
+
+ if (newRemoteURL != remoteSyncURL && ![newRemoteURL isEqual: remoteSyncURL]) {
+ // Set up synchronization to/from a remote database:
+ NSLog(@"Changing sync to <%@>", newRemoteURL.absoluteString);
+ self.remoteSyncURL = newRemoteURL;
+ [self stopSync];
+ _pull = [[database pullFromDatabaseAtURL: newRemoteURL
+ options: kCouchReplicationContinuous] retain];
+ [_pull addObserver: self forKeyPath: @"status" options: 0 context: NULL];
+
+ _push = [[database pushToDatabaseAtURL: newRemoteURL
+ options: kCouchReplicationContinuous] retain];
+ [_push addObserver: self forKeyPath: @"status" options: 0 context: NULL];
+ }
+
+ database.server.activityPollInterval = 0.5;
+}
+
+
+- (void) stopSync {
+ [_pull removeObserver: self forKeyPath: @"status"];
+ [_pull stop];
+ [_pull release];
+ _pull = nil;
+ [_push removeObserver: self forKeyPath: @"status"];
+ [_push stop];
+ [_push release];
+ _push = nil;
+}
+
+
+- (void)showSyncButton {
+ if (!showingSyncButton) {
+ showingSyncButton = YES;
+ UIBarButtonItem* syncButton =
+ [[UIBarButtonItem alloc] initWithTitle: @"Configure"
+ style:UIBarButtonItemStylePlain
+ target: self
+ action: @selector(configureSync:)];
+ self.navigationItem.rightBarButtonItem = [syncButton autorelease];
+ }
+}
+
+
+- (void)showSyncStatus {
+ if (showingSyncButton) {
+ showingSyncButton = NO;
+ if (!progress) {
+ progress = [[UIProgressView alloc] initWithProgressViewStyle:UIProgressViewStyleBar];
+ CGRect frame = progress.frame;
+ frame.size.width = self.view.frame.size.width / 4.0;
+ progress.frame = frame;
+ }
+ UIBarButtonItem* progressItem = [[UIBarButtonItem alloc] initWithCustomView:progress];
+ progressItem.enabled = NO;
+ self.navigationItem.rightBarButtonItem = [progressItem autorelease];
+ }
+}
+
+
+- (void) observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object
+ change:(NSDictionary *)change context:(void *)context
+{
+ if (object == _pull || object == _push) {
+ unsigned completed = _pull.completed + _push.completed;
+ unsigned total = _pull.total + _push.total;
+ NSLog(@"SYNC progress: %u / %u", completed, total);
+ if (total > 0 && completed < total) {
+ [self showSyncStatus];
+ [progress setProgress:(completed / (float)total) animated:NO];
+ } else {
+ [self showSyncButton];
+ }
+ }
+}
+
+
@end

0 comments on commit 7b3169d

Please sign in to comment.