iOS/iPhone/iPad/watchOS/tvOS/MacOSX/Android プログラミング, Objective-C, Cocoa, Swiftなど
2018年2月16日(金)の夜間、東京都豊島区の池袋コワーキングスペース OpenOffice FORESTにおきまして、「BUKURO.swift 2017-12」を開催致しました。
_ イベント概要
Cocoa勉強会 関東には、以下のFacebookグループから、ご参加ください。
MOSAのconnpassグループには、以下から、ご参加ください。
発表資料はconnpassページからどうぞ!
また、会場の様子は、ハッシュタグ『#cocoastudy #mosa #bukuroswift』でtweetしています。
_ デザイン・パターン
iOSアプリケーション開発の現場ではデザインパターンが話題となっていますが、最近の傾向では、Microsoftの.NETフレームワーク由来のものが流行っているようです。
でも、そもそも異なる環境向けのものを無理やり適用しようとしているように見えますし、そこで説明されるMVCはCocoaとは異なるものです。
この発表は、とはいっても現場で.NET由来のデザインパターンが選択されたら従うしかないということで、それぞれのフレームワークの内容を発表者が理解するために、資料化したものです。
_ NSDcoument複数ファイルフォーマット その2
意図せず、今回は『Document-based Application特集』になってしまいました。
発表者が製作中のアウトラインプロセッサにOPML形式ファイルのサポートを追加する際の試行錯誤の発表です。
自動保存機能が追加された事による「Save To...」と「Export...」のメニュー項目問題が勉強になりました。
_ NSDcoument複数ファイルフォーマット その3
新規ドキュメントの機能にテンプレートを組み込むお話です。
これについては、他で説明されているのを見たことがないので、貴重だと思います。
_ Developer's Tech Lab
_ Document-based Applicationについて
MOSA de BB掲示板であった質問を切っ掛けに、取り上げることにして見ました。
ホストも興味がある項目なので勉強になったのと、参加者のコメントから、認識に間違いがないか確認できたのがよかったです。
_ BUKURO.makers
BUKURO.swiftの運営が軌道に乗ってきたということで、今後、色々と挑戦して見たいと思っています。その一つに、ある分野に特化した勉強会で、以下を考えています。
* BUKURO.makers
ものづくり
* BUKURO.games
ゲーム開発
* BUKURO.ai
人工知能
* BUKURO.blockchain
ブロックチェーン
今回はその第一弾でMakers関連をやってみました。将来的には独立した勉強会にしたいのですが、まだ早いと思うので、BUKURO.swiftに間借りしてやってみました。
_ コピー機を作る
BUKURO.makersの第一回の発表を参加された方が事前に用意していくれたのが嬉しいです。
なんと、コピー機を自作するという内容でした。今後が楽しみです。
_ Arduino UNOにESP-WROOM-02をつなぐ
水位計を自作するため、Auduino UnoにWiFiシールドを繋ぐという発表でした。
次回もCocoa勉強会 関東との合同勉強会を3月に予定しています!
BUKURO.gamesというゲーム制作のコーナーを設ける予定です!
Traditional version of MVC as a compound pattern
Cocoa version of MVC as a compound design pattern
Documentクラスはモデル・コントローラ
Documentクラスの例
class Document {
var version: String
private var _uniqueIdentifier: String
var uniqueIdentifier: String {
return _uniqueIdentifier
}
static let sharedInstance: Document = {
let instance = Document()
return instance
}()
init() {
let infoDictionary = Bundle.main.infoDictionary! as Dictionary
self.version = infoDictionary["CFBundleShortVersionString"]! as! String
self._uniqueIdentifier = ""
}
deinit {
}
func load() {
loadDefaults()
}
func save() {
updateDefaults()
}
private func clearDefaults() {
let userDefaults = UserDefaults.standard
if userDefaults.object(forKey: "version") != nil {
userDefaults.removeObject(forKey: "version")
}
if userDefaults.object(forKey: "uniqueIdentifier") != nil {
userDefaults.removeObject(forKey: "uniqueIdentifier")
}
}
private func updateDefaults() {
let userDefaults = UserDefaults.standard
var versionString: String = ""
if userDefaults.object(forKey: "version") != nil {
versionString = userDefaults.object(forKey: "version") as! String
}
if versionString.compare(self.version) != .orderedSame {
userDefaults.setValue(self.version, forKey: "version")
userDefaults.synchronize()
}
var uniqueIdentifier: String = ""
if userDefaults.object(forKey: "uniqueIdentifier") != nil {
uniqueIdentifier = userDefaults.object(forKey: "uniqueIdentifier") as! String
}
if uniqueIdentifier.compare(self.uniqueIdentifier) != .orderedSame {
userDefaults.setValue(self.uniqueIdentifier, forKey: "uniqueIdentifier")
userDefaults.synchronize()
}
}
private func loadDefaults() {
let userDefaults = UserDefaults.standard
var versionString: String = ""
if userDefaults.object(forKey: "version") != nil {
versionString = userDefaults.object(forKey: "version") as! String
}
if versionString.compare(self.version) != .orderedSame {
/* バージョン不一致対応 */
clearDefaults()
_uniqueIdentifier = UUID.init().uuidString
}
else {
/* 読み出し */
if userDefaults.object(forKey: "uniqueIdentifier") != nil {
_uniqueIdentifier = userDefaults.object(forKey: "uniqueIdentifier") as! String
}
}
}
private func modelDir() -> String {
let paths = NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true)
if paths.count < 1 {
return ""
}
var path = paths[0]
path = path.appending(".model")
return path
}
private func modelPath() -> String {
let path = modelDir().appending("/model.dat")
return path;
}
}
シングルトンを使わない例
@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {
public let document = Document()
:
}
let delegate = UIApplication.shared.delegate as! AppDelegate
let document = delegate.document
print(document)
サンプル・コードの構成を説明すると、macOSアプリケーションにEmbedded Frameworkを組み込んで確認を行った。
Embedded Frameworkに以下の内容のクラスを追加する。
public class QuickDraw: NSObject {
@objc public func dbgmsg() {
print("QuickDraw")
}
}
アプリケーション側のObjective-Cコードから呼び出す例は以下となる。
@import Toolbox;
@implementation Exam
- (void)dbgmsg
{
NSLog(@"%s", __func__);
QuickDraw *qd = [QuickDraw new];
[qd dbgmsg];
}
@end
Swiftコードから呼び出す例は以下となる。
import Toolbox
class ViewController: NSViewController {
override func viewDidLoad() {
super.viewDidLoad()
let exam = Exam()
exam.dbgmsg()
let qd = QuickDraw()
qd.dbgmsg()
}
override var representedObject: Any? {
didSet {
// Update the view, if already loaded.
}
}
}
Frameworkはモジュールということになるので、モジュール内で定義したクラスを外部からアクセスするためには、openまたはpublicで宣言されている必要がある。
Frameworkのクラスは、Objective-CでもSwiftでも、モジュールをimportするだけでアクセスできた。