PDFViewからcurrentPage()が取れないという、最低最悪レベルのバグが放置されたOSがリリースされ続けて2年。Devlopper Supportに報告しても返事の1つもない今日このごろです。
Apple Developper Connectionのインシデントを消費して質問しても返答がないので、本当に頭にきています。
この、macOS 10.13のBetaでは存在しなかったのにRelease版で作られた画期的なバグを回避するために、いろいろ工夫をしてみました。
テストしてみたところ、Objective-CやSwiftでは発生していないため、Scripting Bridgeのみで発生しているらしきバグのようです。こんな基本的な箇所でバグを作って直さない連中の気が知れません。
AppleのDevelopper Supportが役立たずで仕事をしないのは今日にはじまった話ではないので(Mailing Listが落ちた状態で、報告しても1か月放置した事件など)、仕方なく回避策を検討してみました。
(1)PDFViewまわりのWrapping ClassをObjective-Cで書いて使う
(2)Objective-Cでユーティリティを書いて、パラメータとして与えたPDFViewからObjective-CでcurrentPageを取得する
(3)今後もAppleがバグを作り続けることが予想されるため、サードパーティのPSPDFKitを導入する
といった対策を検討していたのですが、最も手短なものとして、
(4)表示中のページを自前で管理して、PDFViewに指定ページの内容を随時切り出して表示する
という対処を行ってみました。
PDFをオープンしてPDFViewで表示させ、左右の矢印キーでページをめくることができます。なお、macOS 10.14.5beta+Xcode 10.2上でビルドと確認を行いましたが、内容的にはXcodeのバージョンは関係ありません。
–> Download Xcode Project Archive (pdfTestZ)
AppleScript名:AppDelegate.applescript |
— — AppDelegate.applescript — pdfTestZ — — Created by Takaaki Naganoya on 2019/04/09. — Copyright © 2019 Piyomaru Software. All rights reserved. — script AppDelegate property parent : class "NSObject" — IBOutlets property theWindow : missing value property aView : missing value property maxPageNum : 0 property curPageIndex : 0 property aPDFDoc : missing value property pLabelField : missing value on applicationWillFinishLaunching:aNotification end applicationWillFinishLaunching: on applicationShouldTerminate:sender return current application’s NSTerminateNow end applicationShouldTerminate: on clicked:aSender set aTag to (tag of aSender) as integer if aTag = 100 then set aPath to choose file of type {"com.adobe.pdf"} set pPath to POSIX path of aPath set aURL to current application’s |NSURL|’s fileURLWithPath:pPath set my aPDFDoc to current application’s PDFDocument’s alloc()’s initWithURL:aURL set myFileName to (current application’s NSString’s stringWithString:pPath)’s lastPathComponent() theWindow’s setTitle:myFileName set maxPageNum to ((aPDFDoc’s pageCount()) as integer) – 1 set curPageIndex to 0 log {"maxPageNum", maxPageNum} aView’s setAutoScales:true aView’s setDisplaysPageBreaks:true my dispCurPageDoc() set tmpStr to ((maxPageNum + 1) as string) & "/" & ((curPageIndex + 1) as string) pLabelField’s setStringValue:tmpStr else if aTag = 200 then set tmpPage to my (aPDFDoc’s pageAtIndex:(curPageIndex)) set curPageLabel to tmpPage’s label() tell current application display dialog (curPageLabel as string) end tell else if aTag = 1000 then my decPage() my dispCurPageDoc() else if aTag = 1010 then my incPage() my dispCurPageDoc() end if end clicked: on dispCurPageDoc() set tmpPage to my (aPDFDoc’s pageAtIndex:(curPageIndex)) set tmpDoc to (current application’s PDFDocument’s alloc()’s initWithData:(tmpPage’s dataRepresentation())) aView’s setDocument:tmpDoc set tmpStr to ((maxPageNum + 1) as string) & "/" & ((curPageIndex + 1) as string) pLabelField’s setStringValue:tmpStr end dispCurPageDoc on incPage() if curPageIndex = maxPageNum then –何もしない else if curPageIndex < maxPageNum then set curPageIndex to curPageIndex + 1 end if end incPage on decPage() if curPageIndex = 0 then –何もしない else if curPageIndex > 0 then set curPageIndex to curPageIndex – 1 end if end decPage end script |
2019年に書いた価値あるAppleScript – AppleScriptの穴 says:
[…] RectangleBinPackを用いて2D Bin Packを解く Appleがいまだに直さないPDFViewのバグを回避する 2D Bin […]