viva CocoaさんのコードサンプルMemo Padにおけるアップデート内容
主題
viva CocoaさんのXcodeとSwiftで作るMac OS Xアプリ開発
のサンプルプログラムMemo Padにおけるコードサンプルについて、アップデートした内容を説明する。
背景
今まで3個のmacOS用アプリを公開してきた。しかしながら、その多くにおいて取ってきた手法は、Web上に公開されているサンプルコードを組み合わせるというものだった。この辺りで軌道修正したいと思いつつも、新しいアプリでもサンプルコードを求める癖は抜けなかった。
そこで見つけたのがviva CocoaさんのXcodeとSwiftで作るMac OS Xアプリ開発
の最終章にあるMemo Pad
であった。そこから逆にリンクを辿ってたどり着いたコンテンツはかなり体系的に整理されているようだった。これはうってつけだと思い、第1章から勉強し直すことにした。だが考え方は今でも全く問題なく通じるものの、掲載のコードサンプルにdeprecateされた内容などがあり、アップデートが必要なことが分かった。
-
AddOneクラスコードサンプル
変更点は、コメントにて説明している。import Cocoa @objc(AddOne) class AddOne: ValueTransformer { /* 元のコード override func transformedValue(value: AnyObject?) -> AnyObject? { var num = value!.intValue num! += 1 return NSNumber.init(int: num) } */ // 関数の形が変わった // override func transformedValue(value: AnyObject?) -> AnyObject? override func transformedValue(_ value: Any?) -> Any? { // 後でpowの結果と比較するため、倍精度型で定義 var num:Double = 0.0 // valueのnilチェック if let theValue = value { num = (theValue as AnyObject).doubleValue } else { return num = 0 } /* 最初の9223372036854775807=(pow(2,63) - 1)を防ぐ。 numを倍精度型にする理由は、ここでの比較のため。 また92233…はpowでしか作れない(StackOverFlowにあった 整数型powではEXC_BAD_INSTRUCTIONで落ちる)ため */ if num < (pow(2,63) - 1) { num += 1 } else { num = 0 } return NSNumber.init(value: num) } }
-
Modelクラスコードサンプル
変更点は、コメントにて説明している。import Cocoa @objc(Model) // class Model: NSObject, NSCodingから変更 class Model: NSObject, NSSecureCoding { // NSSecureCodingにより追加 static var supportsSecureCoding: Bool = true // Cocoa-Bindingsでは、init()は、この形。それ以外はダメ override init() { super.init() } // @objcコンパイラディレクティブは必要。ないと落ちる。 @objc var note: AnyObject = String() as AnyObject // encodeWithCoder(aCoder: NSCoder)から // encode(with aCoder: NSCoder)に変更 func encode(with aCoder: NSCoder) { aCoder.encode(note, forKey: "note") } // decodeObjectForKey("note")!から // decodeObject(forKey: "note")!に変更 required init?(coder aDecoder: NSCoder) { note = aDecoder.decodeObject(forKey: "note")! as AnyObject } }
-
ViewControllerクラスコードサンプル
変更点は、コメントにて説明している。import Cocoa class ViewController: NSViewController { // @objcコンパイラディレクティブは必要。ないと落ちる。 @objc dynamic var notes:[AnyObject] = [] // deprecateに伴い廃止。 // var filePath:String = String() func save() { // archiveRootObject(_:toFile:) // はmacOS10.14でdeprecatedされた。 guard let archiveData = try? NSKeyedArchiver.archivedData(withRootObject: notes, requiringSecureCoding: true ) else { fatalError("Archive failed") } UserDefaults.standard.set(archiveData, forKey: "notes") } func read() { // unarchiveObject(with:) // はmacOS10.14でdeprecatedされた。 if let loadedData = UserDefaults().data(forKey: "notes") { if let file = try! NSKeyedUnarchiver.unarchiveTopLevelObjectWithData(loadedData) { notes = file as! [AnyObject] } } } override func viewWillAppear() { super.viewWillAppear() read() /* deprecateに伴い廃止。 filePath = NSHomeDirectory() + "/Library/Application Support/viva Cocoa" do { try NSFileManager.defaultManager().createDirectoryAtPath( filePath, withIntermediateDirectories: true, attributes: nil) } catch { print("Error") } filePath += "/Memo Pad.data" */ } override func viewWillDisappear() { super.viewWillDisappear() save() } override func viewDidLoad() { super.viewDidLoad() // Do any additional setup after loading the view. } override var representedObject: Any? { didSet { // Update the view, if already loaded. } } }
以上。
この投稿へのトラックバック
トラックバックはありません。
- トラックバック URL
この投稿へのコメント