EBPocket for iOS クリップボード変更検知によるクリップボード検索
クリップボード検索というと、たいていの方は、「他のアプリと辞書アプリを同時に立ち上げて、他アプリでテキストをコピーすれば即座に辞書引きができる」という利用方法を期待するのではないだろうか。
だが、EBPocketのクリップボード検索は、アプリケーションがアクティブになるタイミングでしか検索できなかった。
このたび、iPad のSplit Viewによるマルチタスク環境において、EBPocket for iOS のクリップボード変更検知によるクリップボード検索が、やっとできるようになった。
iOSのペーストボードには、次のように変更を検知する機能が元々ある。
[[NSNotificationCenter defaultCenter]
addObserver:self
selector:@selector(pasteboardChanged:)
name:UIPasteboardChangedNotification
object:[UIPasteboard generalPasteboard]];
ところが、Split Viewで別のアプリがペーストボードを変更しても、このNotificationは発火しない。このため、てっきり変更検知はできないと思い込んでいた。
ところが最近、「物書堂の辞書アプリではできている」という報告をいただいた。物書堂さんができているなら、EBPocketでもできないはずはない。
色々方法を探ったところ、結局、次の記事の方法で解決した。単純にタイマーで定期的にペーストボードの内容をチェックするだけだ。
1つ注意点は、iOS14以来、他のアプリが書き込んだペーストボードの情報を読み込むと、"EBPocketに○○からペースト"みたいなアラートが表示されることである。
このため、実際に変更された場合だけ読み込むようにしないと、タイマーの間隔毎にアラートが表示されることになってしまう。そこで、ペーストボードのchangeCountを見て、数字が変わったときだけデータを取得する。
実は上記の記事のコードには、一部コンパイルできない箇所があるので、実際に使ったコードを以下に示す。
クリップボード監視を開始するときにstartCheckingPasteboardを呼び、終了時にstopCheckingPasteboardを呼ぶ。
@property (strong, nonatomic) NSTimer *pasteboardCheckTimer;
@property (assign, nonatomic) NSUInteger pasteboardchangeCount;
- (void) startCheckingPasteboard{_pasteboardchangeCount = [[UIPasteboard generalPasteboard] changeCount];
//Start monitoring the paste board
_pasteboardCheckTimer = [NSTimer scheduledTimerWithTimeInterval:1 // 1s間隔
target:self
selector:@selector(monitorBoard:)
userInfo:nil
repeats:YES];
}- (void) stopCheckingPasteboard{
[_pasteboardCheckTimer invalidate];
_pasteboardCheckTimer = nil;
}- (void) monitorBoard:(NSTimer*)timer{
UIPasteboard *_pasteboard = [UIPasteboard generalPasteboard];
NSUInteger changeCount = [_pasteboard changeCount];
if (changeCount != _pasteboardchangeCount) { // means pasteboard was changed
_pasteboardchangeCount = changeCount;if ([_pasteboard hasStrings]){
NSString *newContent = _pasteboard.string;[self tryToDoSomethingWithTextContent:newContent];
}
}
}- (void)tryToDoSomethingWithTextContent:(NSString*)string{
// 取得したペーストボードの内容で処理を行う。}