{"action":"created","comment":{"url":"https://api.github.com/repos/owncloud/ios/pulls/comments/65230069","id":65230069,"diff_hunk":"@@ -0,0 +1,242 @@\n+//\n+//  InstantUpload.h\n+//  Owncloud iOs Client\n+//\n+\n+/*\n+ Copyright (C) 2016, ownCloud, Inc.\n+ This code is covered by the GNU Public License Version 3.\n+ For distribution utilizing Apple mechanisms please see https://owncloud.org/contribute/iOS-license-exception/\n+ You should have received a copy of this license\n+ along with this program. If not, see <http://www.gnu.org/licenses/gpl-3.0.en.html>.\n+*/\n+\n+#import <CoreLocation/CoreLocation.h>\n+#import <Photos/Photos.h>\n+\n+#import \"InstantUpload.h\"\n+\n+#import \"AppDelegate.h\"\n+#import \"constants.h\"\n+\n+#import \"ManageAppSettingsDB.h\"\n+#import \"ManageUsersDB.h\"\n+#import \"UserDto.h\"\n+\n+#define ACTIVE_USER ((AppDelegate *)[[UIApplication sharedApplication] delegate]).activeUser\n+\n+@interface InstantUpload () <CLLocationManagerDelegate, PHPhotoLibraryChangeObserver>\n+\n+@property (strong, nonatomic) CLLocationManager *locationManager;\n+\n+@end\n+\n+@implementation InstantUpload\n+\n++ (instancetype) instantUploadManager {\n+    static dispatch_once_t once;\n+    static InstantUpload *__instantUploadManager;\n+    dispatch_once(&once, ^{\n+        __instantUploadManager = [[InstantUpload alloc] init];\n+    });\n+    return __instantUploadManager;\n+}\n+\n+- (instancetype) init {\n+    if (self = [super init]) {\n+        self.locationManager = [[CLLocationManager alloc] init];\n+        self.locationManager.delegate = self;\n+        [PHPhotoLibrary.sharedPhotoLibrary registerChangeObserver:self];\n+        [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(appLifecycleShouldTriggerInstantUpload:) name:UIApplicationWillEnterForegroundNotification object:nil];\n+    }\n+    return self;\n+}\n+\n+- (void) dealloc {\n+    [[NSNotificationCenter defaultCenter] removeObserver:self];\n+}\n+\n+- (BOOL) enabled {\n+    return ACTIVE_USER.instantUpload;\n+}\n+\n+- (BOOL) backgroundInstantUploadEnabled {\n+    return ACTIVE_USER.backgroundInstantUpload;\n+}\n+\n+- (void) setEnabled:(BOOL)enabled {\n+    @synchronized (self) {\n+        if (enabled != self.enabled) {\n+            if (enabled) {\n+                if ([PHPhotoLibrary authorizationStatus] == PHAuthorizationStatusAuthorized) {\n+                    ACTIVE_USER.instantUpload = YES;\n+                    [ManageAppSettingsDB updateInstantUploadTo:YES];\n+                    [self attemptUpload];","path":"Owncloud iOs Client/InstantUpload/InstantUpload.m","position":74,"original_position":74,"commit_id":"c83332cc106615c5d51301a3af45b0d34826e52f","original_commit_id":"c83332cc106615c5d51301a3af45b0d34826e52f","user":{"login":"Jon-Schneider","id":2467701,"avatar_url":"https://avatars.githubusercontent.com/u/2467701?v=3","gravatar_id":"","url":"https://api.github.com/users/Jon-Schneider","html_url":"https://github.com/Jon-Schneider","followers_url":"https://api.github.com/users/Jon-Schneider/followers","following_url":"https://api.github.com/users/Jon-Schneider/following{/other_user}","gists_url":"https://api.github.com/users/Jon-Schneider/gists{/gist_id}","starred_url":"https://api.github.com/users/Jon-Schneider/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/Jon-Schneider/subscriptions","organizations_url":"https://api.github.com/users/Jon-Schneider/orgs","repos_url":"https://api.github.com/users/Jon-Schneider/repos","events_url":"https://api.github.com/users/Jon-Schneider/events{/privacy}","received_events_url":"https://api.github.com/users/Jon-Schneider/received_events","type":"User","site_admin":false},"body":"So that images taken before instant upload is enabled aren't uploaded? I believe the behavior of Dropbox and similar apps (Google Photos) is to upload your entire history, but I'm not sure what OwnCloud has done in the past.","created_at":"2016-05-31T17:46:59Z","updated_at":"2016-05-31T17:46:59Z","html_url":"https://github.com/owncloud/ios/pull/666#discussion_r65230069","pull_request_url":"https://api.github.com/repos/owncloud/ios/pulls/666","_links":{"self":{"href":"https://api.github.com/repos/owncloud/ios/pulls/comments/65230069"},"html":{"href":"https://github.com/owncloud/ios/pull/666#discussion_r65230069"},"pull_request":{"href":"https://api.github.com/repos/owncloud/ios/pulls/666"}}},"pull_request":{"url":"https://api.github.com/repos/owncloud/ios/pulls/666","id":71139428,"html_url":"https://github.com/owncloud/ios/pull/666","diff_url":"https://github.com/owncloud/ios/pull/666.diff","patch_url":"https://github.com/owncloud/ios/pull/666.patch","issue_url":"https://api.github.com/repos/owncloud/ios/issues/666","number":666,"state":"open","locked":false,"title":"Instant upload","user":{"login":"Jon-Schneider","id":2467701,"avatar_url":"https://avatars.githubusercontent.com/u/2467701?v=3","gravatar_id":"","url":"https://api.github.com/users/Jon-Schneider","html_url":"https://github.com/Jon-Schneider","followers_url":"https://api.github.com/users/Jon-Schneider/followers","following_url":"https://api.github.com/users/Jon-Schneider/following{/other_user}","gists_url":"https://api.github.com/users/Jon-Schneider/gists{/gist_id}","starred_url":"https://api.github.com/users/Jon-Schneider/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/Jon-Schneider/subscriptions","organizations_url":"https://api.github.com/users/Jon-Schneider/orgs","repos_url":"https://api.github.com/users/Jon-Schneider/repos","events_url":"https://api.github.com/users/Jon-Schneider/events{/privacy}","received_events_url":"https://api.github.com/users/Jon-Schneider/received_events","type":"User","site_admin":false},"body":"### This Pull Request Does the Following:\r\n1) Moves Instant Upload Management logic out of SettingsViewController into a new InstantUpload class.\r\n2) Separates Background Instant Upload from Instant Upload. If Background Instant Upload is disabled and Instant Upload enabled, upload just takes place when you first open the app, the app enters the foreground, or new photos are taken while the app is running in the background.\r\n3) Adds a migration to add a background instant upload enabled field to the users table, used to implement the user preference for Background Instant Upload.\r\n4) Migrates Instant Upload to use the new PHPhotoLibrary api rather than the deprecated ALAssetLibrary API for photo access. This means Instant Upload can now work independent of whether location permission has been granted to the app or not.\r\n5) Deletes ManageLocation class. InstantUpload.m implements background upload by subscribing to CLLocationManager significant location change updates.\r\n\r\n### NEEDS:\r\n#### Translations:\r\n- __\"message_location_not_enabled\"__ has been changed in English to \"Please go to Settings and turn on Location Services to enable instant photo uploads in the background.\" This is the text of the alert when a user tries to enable Background Instant Upload and location permissions are denied.\r\n- Added string __\"title_background_instant_upload\"__, which in English is \"Background Instant Upload\". This is the text of the Background Instant Upload cell on the SettingsViewController.\r\n\r\n#### Possible Needs:\r\n- Will not work with iOS 7 due to use of PHPhotoLibrary. If you want iOS 7 to still be supported in the app I can some preprocessing directives that disables Instant Upload on SettingsViewController, but with iOS 10 around the corner I don't see a need to maintain a whole additional code path using ALAssetLibrary.\r\n\r\n\r\n\r\nTASKS\r\n- [X] [DEV] Code review @javiergonzper @nasli \r\n- [ ] [DEV] Update changes @Jon-Schneider [WIP]\r\n- [ ] [QA] Create test plan\r\n- [ ] [QA] Validate test plan","created_at":"2016-05-24T00:02:13Z","updated_at":"2016-05-31T17:46:59Z","closed_at":null,"merged_at":null,"merge_commit_sha":"8f9219ece40c17a2581d31f78b6123f16df82135","assignee":{"login":"Jon-Schneider","id":2467701,"avatar_url":"https://avatars.githubusercontent.com/u/2467701?v=3","gravatar_id":"","url":"https://api.github.com/users/Jon-Schneider","html_url":"https://github.com/Jon-Schneider","followers_url":"https://api.github.com/users/Jon-Schneider/followers","following_url":"https://api.github.com/users/Jon-Schneider/following{/other_user}","gists_url":"https://api.github.com/users/Jon-Schneider/gists{/gist_id}","starred_url":"https://api.github.com/users/Jon-Schneider/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/Jon-Schneider/subscriptions","organizations_url":"https://api.github.com/users/Jon-Schneider/orgs","repos_url":"https://api.github.com/users/Jon-Schneider/repos","events_url":"https://api.github.com/users/Jon-Schneider/events{/privacy}","received_events_url":"https://api.github.com/users/Jon-Schneider/received_events","type":"User","site_admin":false},"milestone":{"url":"https://api.github.com/repos/owncloud/ios/milestones/11","html_url":"https://github.com/owncloud/ios/milestones/3.5.0-current","labels_url":"https://api.github.com/repos/owncloud/ios/milestones/11/labels","id":1751236,"number":11,"title":"3.5.0-current","description":"","creator":{"login":"rperezb","id":1846927,"avatar_url":"https://avatars.githubusercontent.com/u/1846927?v=3","gravatar_id":"","url":"https://api.github.com/users/rperezb","html_url":"https://github.com/rperezb","followers_url":"https://api.github.com/users/rperezb/followers","following_url":"https://api.github.com/users/rperezb/following{/other_user}","gists_url":"https://api.github.com/users/rperezb/gists{/gist_id}","starred_url":"https://api.github.com/users/rperezb/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/rperezb/subscriptions","organizations_url":"https://api.github.com/users/rperezb/orgs","repos_url":"https://api.github.com/users/rperezb/repos","events_url":"https://api.github.com/users/rperezb/events{/privacy}","received_events_url":"https://api.github.com/users/rperezb/received_events","type":"User","site_admin":false},"open_issues":15,"closed_issues":8,"state":"open","created_at":"2016-05-06T10:09:11Z","updated_at":"2016-05-31T08:32:29Z","due_on":null,"closed_at":null},"commits_url":"https://api.github.com/repos/owncloud/ios/pulls/666/commits","review_comments_url":"https://api.github.com/repos/owncloud/ios/pulls/666/comments","review_comment_url":"https://api.github.com/repos/owncloud/ios/pulls/comments{/number}","comments_url":"https://api.github.com/repos/owncloud/ios/issues/666/comments","statuses_url":"https://api.github.com/repos/owncloud/ios/statuses/c83332cc106615c5d51301a3af45b0d34826e52f","head":{"label":"Jon-Schneider:instant_upload","ref":"instant_upload","sha":"c83332cc106615c5d51301a3af45b0d34826e52f","user":{"login":"Jon-Schneider","id":2467701,"avatar_url":"https://avatars.githubusercontent.com/u/2467701?v=3","gravatar_id":"","url":"https://api.github.com/users/Jon-Schneider","html_url":"https://github.com/Jon-Schneider","followers_url":"https://api.github.com/users/Jon-Schneider/followers","following_url":"https://api.github.com/users/Jon-Schneider/following{/other_user}","gists_url":"https://api.github.com/users/Jon-Schneider/gists{/gist_id}","starred_url":"https://api.github.com/users/Jon-Schneider/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/Jon-Schneider/subscriptions","organizations_url":"https://api.github.com/users/Jon-Schneider/orgs","repos_url":"https://api.github.com/users/Jon-Schneider/repos","events_url":"https://api.github.com/users/Jon-Schneider/events{/privacy}","received_events_url":"https://api.github.com/users/Jon-Schneider/received_events","type":"User","site_admin":false},"repo":{"id":58345130,"name":"ios","full_name":"Jon-Schneider/ios","owner":{"login":"Jon-Schneider","id":2467701,"avatar_url":"https://avatars.githubusercontent.com/u/2467701?v=3","gravatar_id":"","url":"https://api.github.com/users/Jon-Schneider","html_url":"https://github.com/Jon-Schneider","followers_url":"https://api.github.com/users/Jon-Schneider/followers","following_url":"https://api.github.com/users/Jon-Schneider/following{/other_user}","gists_url":"https://api.github.com/users/Jon-Schneider/gists{/gist_id}","starred_url":"https://api.github.com/users/Jon-Schneider/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/Jon-Schneider/subscriptions","organizations_url":"https://api.github.com/users/Jon-Schneider/orgs","repos_url":"https://api.github.com/users/Jon-Schneider/repos","events_url":"https://api.github.com/users/Jon-Schneider/events{/privacy}","received_events_url":"https://api.github.com/users/Jon-Schneider/received_events","type":"User","site_admin":false},"private":false,"html_url":"https://github.com/Jon-Schneider/ios","description":":iphone: iOS app for ownCloud","fork":true,"url":"https://api.github.com/repos/Jon-Schneider/ios","forks_url":"https://api.github.com/repos/Jon-Schneider/ios/forks","keys_url":"https://api.github.com/repos/Jon-Schneider/ios/keys{/key_id}","collaborators_url":"https://api.github.com/repos/Jon-Schneider/ios/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/Jon-Schneider/ios/teams","hooks_url":"https://api.github.com/repos/Jon-Schneider/ios/hooks","issue_events_url":"https://api.github.com/repos/Jon-Schneider/ios/issues/events{/number}","events_url":"https://api.github.com/repos/Jon-Schneider/ios/events","assignees_url":"https://api.github.com/repos/Jon-Schneider/ios/assignees{/user}","branches_url":"https://api.github.com/repos/Jon-Schneider/ios/branches{/branch}","tags_url":"https://api.github.com/repos/Jon-Schneider/ios/tags","blobs_url":"https://api.github.com/repos/Jon-Schneider/ios/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/Jon-Schneider/ios/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/Jon-Schneider/ios/git/refs{/sha}","trees_url":"https://api.github.com/repos/Jon-Schneider/ios/git/trees{/sha}","statuses_url":"https://api.github.com/repos/Jon-Schneider/ios/statuses/{sha}","languages_url":"https://api.github.com/repos/Jon-Schneider/ios/languages","stargazers_url":"https://api.github.com/repos/Jon-Schneider/ios/stargazers","contributors_url":"https://api.github.com/repos/Jon-Schneider/ios/contributors","subscribers_url":"https://api.github.com/repos/Jon-Schneider/ios/subscribers","subscription_url":"https://api.github.com/repos/Jon-Schneider/ios/subscription","commits_url":"https://api.github.com/repos/Jon-Schneider/ios/commits{/sha}","git_commits_url":"https://api.github.com/repos/Jon-Schneider/ios/git/commits{/sha}","comments_url":"https://api.github.com/repos/Jon-Schneider/ios/comments{/number}","issue_comment_url":"https://api.github.com/repos/Jon-Schneider/ios/issues/comments{/number}","contents_url":"https://api.github.com/repos/Jon-Schneider/ios/contents/{+path}","compare_url":"https://api.github.com/repos/Jon-Schneider/ios/compare/{base}...{head}","merges_url":"https://api.github.com/repos/Jon-Schneider/ios/merges","archive_url":"https://api.github.com/repos/Jon-Schneider/ios/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/Jon-Schneider/ios/downloads","issues_url":"https://api.github.com/repos/Jon-Schneider/ios/issues{/number}","pulls_url":"https://api.github.com/repos/Jon-Schneider/ios/pulls{/number}","milestones_url":"https://api.github.com/repos/Jon-Schneider/ios/milestones{/number}","notifications_url":"https://api.github.com/repos/Jon-Schneider/ios/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/Jon-Schneider/ios/labels{/name}","releases_url":"https://api.github.com/repos/Jon-Schneider/ios/releases{/id}","deployments_url":"https://api.github.com/repos/Jon-Schneider/ios/deployments","created_at":"2016-05-09T03:12:27Z","updated_at":"2016-05-09T03:12:32Z","pushed_at":"2016-05-31T13:35:47Z","git_url":"git://github.com/Jon-Schneider/ios.git","ssh_url":"git@github.com:Jon-Schneider/ios.git","clone_url":"https://github.com/Jon-Schneider/ios.git","svn_url":"https://github.com/Jon-Schneider/ios","homepage":"https://itunes.apple.com/app/owncloud/id543672169","size":71399,"stargazers_count":0,"watchers_count":0,"language":"Objective-C","has_issues":false,"has_downloads":true,"has_wiki":false,"has_pages":false,"forks_count":0,"mirror_url":null,"open_issues_count":0,"forks":0,"open_issues":0,"watchers":0,"default_branch":"master"}},"base":{"label":"owncloud:clear_cache_button","ref":"clear_cache_button","sha":"2a9a714144f1b945bfe6ab618d129f46cdf2f7f2","user":{"login":"owncloud","id":1645051,"avatar_url":"https://avatars.githubusercontent.com/u/1645051?v=3","gravatar_id":"","url":"https://api.github.com/users/owncloud","html_url":"https://github.com/owncloud","followers_url":"https://api.github.com/users/owncloud/followers","following_url":"https://api.github.com/users/owncloud/following{/other_user}","gists_url":"https://api.github.com/users/owncloud/gists{/gist_id}","starred_url":"https://api.github.com/users/owncloud/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/owncloud/subscriptions","organizations_url":"https://api.github.com/users/owncloud/orgs","repos_url":"https://api.github.com/users/owncloud/repos","events_url":"https://api.github.com/users/owncloud/events{/privacy}","received_events_url":"https://api.github.com/users/owncloud/received_events","type":"Organization","site_admin":false},"repo":{"id":6402099,"name":"ios","full_name":"owncloud/ios","owner":{"login":"owncloud","id":1645051,"avatar_url":"https://avatars.githubusercontent.com/u/1645051?v=3","gravatar_id":"","url":"https://api.github.com/users/owncloud","html_url":"https://github.com/owncloud","followers_url":"https://api.github.com/users/owncloud/followers","following_url":"https://api.github.com/users/owncloud/following{/other_user}","gists_url":"https://api.github.com/users/owncloud/gists{/gist_id}","starred_url":"https://api.github.com/users/owncloud/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/owncloud/subscriptions","organizations_url":"https://api.github.com/users/owncloud/orgs","repos_url":"https://api.github.com/users/owncloud/repos","events_url":"https://api.github.com/users/owncloud/events{/privacy}","received_events_url":"https://api.github.com/users/owncloud/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/owncloud/ios","description":":iphone: iOS app for ownCloud","fork":false,"url":"https://api.github.com/repos/owncloud/ios","forks_url":"https://api.github.com/repos/owncloud/ios/forks","keys_url":"https://api.github.com/repos/owncloud/ios/keys{/key_id}","collaborators_url":"https://api.github.com/repos/owncloud/ios/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/owncloud/ios/teams","hooks_url":"https://api.github.com/repos/owncloud/ios/hooks","issue_events_url":"https://api.github.com/repos/owncloud/ios/issues/events{/number}","events_url":"https://api.github.com/repos/owncloud/ios/events","assignees_url":"https://api.github.com/repos/owncloud/ios/assignees{/user}","branches_url":"https://api.github.com/repos/owncloud/ios/branches{/branch}","tags_url":"https://api.github.com/repos/owncloud/ios/tags","blobs_url":"https://api.github.com/repos/owncloud/ios/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/owncloud/ios/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/owncloud/ios/git/refs{/sha}","trees_url":"https://api.github.com/repos/owncloud/ios/git/trees{/sha}","statuses_url":"https://api.github.com/repos/owncloud/ios/statuses/{sha}","languages_url":"https://api.github.com/repos/owncloud/ios/languages","stargazers_url":"https://api.github.com/repos/owncloud/ios/stargazers","contributors_url":"https://api.github.com/repos/owncloud/ios/contributors","subscribers_url":"https://api.github.com/repos/owncloud/ios/subscribers","subscription_url":"https://api.github.com/repos/owncloud/ios/subscription","commits_url":"https://api.github.com/repos/owncloud/ios/commits{/sha}","git_commits_url":"https://api.github.com/repos/owncloud/ios/git/commits{/sha}","comments_url":"https://api.github.com/repos/owncloud/ios/comments{/number}","issue_comment_url":"https://api.github.com/repos/owncloud/ios/issues/comments{/number}","contents_url":"https://api.github.com/repos/owncloud/ios/contents/{+path}","compare_url":"https://api.github.com/repos/owncloud/ios/compare/{base}...{head}","merges_url":"https://api.github.com/repos/owncloud/ios/merges","archive_url":"https://api.github.com/repos/owncloud/ios/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/owncloud/ios/downloads","issues_url":"https://api.github.com/repos/owncloud/ios/issues{/number}","pulls_url":"https://api.github.com/repos/owncloud/ios/pulls{/number}","milestones_url":"https://api.github.com/repos/owncloud/ios/milestones{/number}","notifications_url":"https://api.github.com/repos/owncloud/ios/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/owncloud/ios/labels{/name}","releases_url":"https://api.github.com/repos/owncloud/ios/releases{/id}","deployments_url":"https://api.github.com/repos/owncloud/ios/deployments","created_at":"2012-10-26T10:25:42Z","updated_at":"2016-05-30T04:45:38Z","pushed_at":"2016-05-31T13:33:25Z","git_url":"git://github.com/owncloud/ios.git","ssh_url":"git@github.com:owncloud/ios.git","clone_url":"https://github.com/owncloud/ios.git","svn_url":"https://github.com/owncloud/ios","homepage":"https://itunes.apple.com/app/owncloud/id543672169","size":76088,"stargazers_count":226,"watchers_count":226,"language":"Objective-C","has_issues":true,"has_downloads":true,"has_wiki":false,"has_pages":false,"forks_count":378,"mirror_url":null,"open_issues_count":150,"forks":378,"open_issues":150,"watchers":226,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/owncloud/ios/pulls/666"},"html":{"href":"https://github.com/owncloud/ios/pull/666"},"issue":{"href":"https://api.github.com/repos/owncloud/ios/issues/666"},"comments":{"href":"https://api.github.com/repos/owncloud/ios/issues/666/comments"},"review_comments":{"href":"https://api.github.com/repos/owncloud/ios/pulls/666/comments"},"review_comment":{"href":"https://api.github.com/repos/owncloud/ios/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/owncloud/ios/pulls/666/commits"},"statuses":{"href":"https://api.github.com/repos/owncloud/ios/statuses/c83332cc106615c5d51301a3af45b0d34826e52f"}}}}
{"actor":{"display_login":"Jon-Schneider"}}