I am trying to implement an iOS Clipboard Listener using Objective C which runs in the background listening for copies anywhere outside the app.
The logic I am using is implemented in https://github.com/vitoziv/VIClipboardListener, the main points are:
Add an observer for the
UIPasteboardChangedNotification
event[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(pasteboardChanged:) name:UIPasteboardChangedNotification object:nil];
Start a background task which will watch for changes to the
UIPasteboard
UIApplication* app = [UIApplication sharedApplication]; _bgTask = [app beginBackgroundTaskWithExpirationHandler:^{ [app endBackgroundTask:_bgTask]; _bgTask = UIBackgroundTaskInvalid; }]; dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ [self checkPasteBoardCount]; [app endBackgroundTask:_bgTask]; _bgTask = UIBackgroundTaskInvalid; });
Inside the
checkPasteBoardCount
method, watch for changes to theUIPasteboard
by checking thepasteboard.changeCount
every second and comparing to the last valueUIPasteboard *pasteboard = [UIPasteboard generalPasteboard]; NSInteger changeCount = pasteboard.changeCount; NSInteger bgTaskTime = BACKGROUND_TIME; while (bgTaskTime >= 0) { //NSLog(@"app in background, left %i second.",bgTaskTime); if (changeCount != pasteboard.changeCount) { [[NSNotificationCenter defaultCenter] postNotificationName:UIPasteboardChangedNotification object:nil]; changeCount = pasteboard.changeCount; } [NSThread sleepForTimeInterval:SLEEP_TIME]; bgTaskTime -= SLEEP_TIME; }
This should cause our observer's pasteboardChanged
method to be called every time there is a change in the UIPasteboard
contents. That change should be accessible using the UIPasteboard.string
etc. methods.
Running this on an emulator gives perfect results, the pasteboardChanged
method gets called on every copy from any app while the app runs in the background, and the contents of the [UIPasteboard generalPasteboard]
always contain the copied content.
However, when running this on a real device, despite the fact that the observer is indeed called on every copy, the content of the [UIPasteboard generalPasteboard].string
property is almost always nil
. On some rare occasions (maybe when quickly reopening the app after copying from outside) the actual value was there, but it seems random.
Are there any context-related rules to accessing the Pasteboard data on a real device, such as only being able to read content created from within the same app? Or could there be differences in thread management between the emulator and a real device?
Any help would be appreciated. Thanks!
P.S. I was only able to test on the one device so far, will try another one to confirm the behavior.