1 | 2 | 3 | 4 | 5 |最初 次ページ >>
2016-12-25 15:22:15

勉強会のご案内

テーマ:ブログ

参加していた勉強会の運営に変更があり、今年度は、主に池袋と松戸で定期的に勉強会が解されるようになった。

渋谷で開催された勉強会は、以下のとおり。

  • Cocoa Study at Shibuya #1
    日時:2016/03/17(木) 19:30-21:00
    会場:電源カフェbeez 渋谷
  • Cocoa Study at Shibuya #2
    日時:2016/04/14(木) 19:30-21:00
    会場:電源カフェbeez 渋谷

渋谷の会場が都合で使えなくなったため、池袋で開催されるようになった。

松戸でも開催されるようになった。松戸では、今後は、初心者向け、かつ、macOS関連の発表を充実させて行く予定だ。ただ、会の内容を決めるのは発表者なので、参加者次第となるが。

今年度から、NPO法人MOSAの理事になり、MOSA自習室という勉強会を開催。

どんな内容なのかは、各勉強会のページに発表資料のリンクがあるので、それで確認してほしい。

年明けも、以下の勉強会の開催が決まっているので、興味がある方は、申し込みを。

自分が考えている発表は、一つは、よりCoolなSwiftによるプログラミングを調べた『Swiftyを試してみる』と、macOSの開発をしたくなったので、近年、大きく変わったmacOS関連の基本的なアプリケーションについてを考えている。

 

関連情報

Cocoa Study at Ikebukuro #6 (BUKURO.swift)
Cocoa Study (connpass グループ)
Cocoa Study (ATND グループ)
Cocoa勉強会
Cocoa勉強会(関東)
Cocoa勉強会 関東 (connpass グループ)
Cocoa勉強会関西
Cocoa勉強会関西ビギナーズ
MOSA
MOSA (connpass グループ)

 

【Cocoa練習帳】

http://www.bitz.co.jp/weblog/
http://ameblo.jp/bitz/(ミラー・サイト)

AD
いいね!した人  |  コメント(0)  |  リブログ(0)
最近の画像つき記事
 もっと見る >>
2016-12-24 09:10:06

何を学ぶべきか?

テーマ:ブログ

業務上、CやC++、Objective-C、Swift、Java、C#を同時に利用するという機会があるのだが、それで得られた感想は、プログラミング言語の違いによる差はない、だ。単に記法が異なるだけ。

違いが出るのは、どんなフレームワークを使っているかで、そういう意味から、Objective-CとSwiftの差はないと思う。

○○言語の方が簡単で効率的!といわれる場合があるが、ワインバーグさんが言っているように、これは経営側からの視点の言葉だと思う。○○言語の方が安全といわれる場合もあるが、これはあるレベルのスキルがある関係ないと思う。今後定年がなくなると言われる状況で、ずっとプロでやって行くことを考えると、安全なプログラミング言語でないと危険な仕事をしているようではと思う。

自分の経験から、自分がまだプログラミングの仕事ができているのは、以下を学ぶことができたからかなと考えている。

  • Bourne Shell
  • C言語
  • Cocoa

Swiftを知って、あらためてC言語の素晴らしさを実感しているが、C言語のスキルを得るために、Swift主流の時代ににSwiftしか知らないのでObjective-Cを学ぶのは難しいとは思う。かと行って、hello, worldレベルの学習をしてもしょうがない。難しい状況だな。

Cocoaのような本格的で大規模なGUIライブラリを知っておくのは、大事だと思う。違うものが主流になっても、その経験は生きるので。

ソースコード GitHubからどうぞ。
https://github.com/murakami/workbook/tree/master/ios/Hand - GitHub
関連情報 文化を調和させる
【Cocoa練習帳】 http://www.bitz.co.jp/weblog/
http://ameblo.jp/bitz/(ミラー・サイト)
AD
いいね!した人  |  コメント(0)  |  リブログ(0)
2016-12-21 22:54:40

[Swifty]プロトコル指向プログラミング

テーマ:ブログ

今回は、出だしは少し辛口。

MacOS時代、クラスライブラリMacAppを使用したプログラミングの手法として、オブジェクト・プログラミングというのがあった。これは、利用側が、必ずしもオブジェクト指向プログラミングをする必要がない。オブジェクト指向で実装されたライブラリを利用すればいいということだったと思う。

この考えは、NeXTstepでもあったと思っていて、継承以外のクラスを拡張する方法としてデリゲートが用意されていたり、InterfaceBuilderはクラスでなく、インスタンスを生成するところなどがそうではないだろうか?

自分はたいした職歴でないが、過去を思い出すと、継承を多用したプロジェクトは、必ず、スパゲッティになっていた。何が問題なのかなとボンヤリと思うと、継承をコードの共通化として利用し、オブジェクトとしての構成がよくなかったのではないか?では、そこを頑張ればいいのかというと頑張ると変な方向に行ってしまうような。

なかなか、この考えに考え抜いたスパゲティを生産される方は、その主張がパッと聞くと正論のように思われ、止めることはできず。逆に止めようとすると、論争になり、ますます、泥沼にはまっていたよな〜。

恐ろしいのは、この設計論争は、何もモノを生み出さない。趣味ですね。

Swiftでclass出なくstructを。継承でなくプロトコルを勧めているのも、多くの方々が、このスパゲティ・クラスに疲れ果ててしまったからかな思う。

イカンイカン。脱線しているので本題に戻る。

今回取り上げるのはWWDC2015のセッション『Protocol-Oriented Programming in Swift』。

課題を3つ挙げている。

  • Implicit Sharing
  • Inheritance All Up In Your Business
  • Lost Type Relationships

一つ目は、リファレンス型のことを言っているようで、値を変えると、他で所有しているところで驚くという内容だ。ただ、これは、以前も説明した通りモジュール化の問題で、Model(Dataコントローラ)を用意するとか、必要な複製は行うとかすれば問題ないと考えている。

二つ目は、継承の問題で、パッと思いついたのは、親でreadonlyにしたが、一部の子でwriteしたくなり、そのためにそれ専用のメソッドを用意したり、逃げで苦労するということか。継承しすぎ、Baseクラスやめたら、ですね。

最後は型の問題で、親子で方がうまくいかず、他の子のことを考慮したり、親で子を考慮したりということか。

ということで、推奨されたのが以下の7つ。

  • Supports value types (and classes)
  • Supports static type releationships (and dynamic dispatch)
  • Non-monolithic
  • Supports retroactive modeling
  • Doesn't impose instance data on models
  • Doesn't impose initialization burdens on models
  • Makes clear what to implement

詳細は割愛するが、それでプロトコル指向プログラミングということだが、何とか指向というと、スパゲティの悪夢が蘇って腰が引けてしまうが、まずは、自称オブジェクト指向プログラミングを制限するというのは、いいかも。

これで、悲劇が繰り返さないことを願う。

ソースコード GitHubからどうぞ。
https://github.com/murakami/workbook/tree/master/ios/Hand - GitHub
関連情報 文化を調和させる
【Cocoa練習帳】 http://www.bitz.co.jp/weblog/
http://ameblo.jp/bitz/(ミラー・サイト)
AD
いいね!した人  |  コメント(0)  |  リブログ(0)
2016-12-20 23:16:30

[Swifty]Self要件

テーマ:ブログ

本件、プロジェクトの構成の違いから、最後はグダグダになってしまったので、一通り巡ったということで、その中で気になったことを調べてみることにする。

プロトコルでSelfを返すように変更したが、何となく意味は分かるのだが、何なんだろう。The Swift Programming Languageを読み返してみたが、それらしい記述がない。検索したところ、おそらく、WWDCの発表からだろうか。Self要件と説明しているサイトを見つけた。

protocol DataType {
    var numberOfItems: Int {get}
    func addNewItemAtIndex(index: Int) -> Self
    func deleteItemAtIndex(index: Int) -> Self
    func moveItem(fromIndex: Int, toIndex: Int) -> Self
}

このプロトコルを適用したクラスの型として扱われるということのようだ。

ただ、これはプロトコルでのみ許されているようで、適用したクラスでは、そのクラスで宣言しないとエラーとなった。

struct Hand: DataType {
    public var numberOfItems: Int {
        return cards.count
    }
    
    public func addNewItem(at index: Int) -> Hand {
        return insertCard(card: deck.nextCard(), at: index)
    }
    
    private func insertCard(card: Card, at index: Int) -> Hand {
        var mutableCards = cards
        mutableCards.insert(card, at: index)
        return Hand(deck: deck, cards: mutableCards)
    }
    
    public func deleteItem(at index: Int) -> Hand {
        var mutableCards = cards
        mutableCards.remove(at: index)
        return Hand(deck: deck, cards: mutableCards)
    }
    
    public func moveItem(fromIndex: Int, toIndex: Int) -> Hand {
        return deleteItem(at: fromIndex).insertCard(card: cards[fromIndex], at: toIndex)
    }
}

Self要件によって、プロトコルは、総称型のように、適用した型を抽象的に記述できるということのようだ。

ソースコード GitHubからどうぞ。
https://github.com/murakami/workbook/tree/master/ios/Hand - GitHub
関連情報 文化を調和させる
【Cocoa練習帳】 http://www.bitz.co.jp/weblog/
http://ameblo.jp/bitz/(ミラー・サイト)
いいね!した人  |  コメント(0)  |  リブログ(0)
2016-12-19 23:25:33

[Swifty]総称型

テーマ:ブログ

ギブアップ。そもそもの構造が違うので、発表のとおりの修正は無理。

発表では、DataSourceに総称型を導入。

class DataSource: NSObject, UITableViewDataSource, SourceType {
    var dataObject: DataType
    
    init(dataObject: A) {
        self.dataObject = dataObject
    }
}

そうすると、初期化は以下のようになる。

class HandDataSource: DataSource {
    init() {
        super.init(dataObject: Hand())
    }
}

ただ、何度も言い訳をして苦しいが、自分のプロジェクトでは、Model(Dataコントローラ)のクラスを用意しているので、こうはならない。

ソースコード GitHubからどうぞ。
https://github.com/murakami/workbook/tree/master/ios/Hand - GitHub
関連情報 文化を調和させる
【Cocoa練習帳】 http://www.bitz.co.jp/weblog/
http://ameblo.jp/bitz/(ミラー・サイト)
いいね!した人  |  コメント(0)  |  リブログ(0)
2016-12-19 23:13:34

[Swifty]DataSourceのサブクラス

テーマ:ブログ

今回も辛いはず!

DataSourceを継承したHandDataSourceを作る。

class HandDataSource: DataSource {
    override init() {
        super.init()
    }
    
    override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        guard let cell = tableView.dequeueReusableCell(withIdentifier: "Cell", for: indexPath as IndexPath) as? CardCell else {
            return UITableViewCell()
        }
        let card = document.getItem(at: indexPath.row)
        cell.fillWith(card: card)
        return cell
    }
}

ハンドビューコントローラがこれを利用するようにする。

class HandVC: UITableViewController {
    private var dataSource = HandDataSource()
}

スーパークラスを変更する。

class DataSource: NSObject, UITableViewDataSource, SourceType {
    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        fatalError("This method must be overriden")
    }
}

継承されなかったら、エラーにするということだ。

ソースコード GitHubからどうぞ。
https://github.com/murakami/workbook/tree/master/ios/Hand - GitHub
関連情報 文化を調和させる
【Cocoa練習帳】 http://www.bitz.co.jp/weblog/
http://ameblo.jp/bitz/(ミラー・サイト)
いいね!した人  |  コメント(0)  |  リブログ(0)
2016-12-19 22:52:14

[Swifty]計算済みプロパティの追加

テーマ:ブログ

かなり無理をしている状態になってきたが、それだけ、試行錯誤しないといけないので、得るものはある。

今回は、計算済みプロパティの追加だ。今回も、無理がありそう!

やはり、これは無理。

protocol SourceType: UITableViewDataSource {
    //var dataObject: DataType {get set}
    //var conditionForAdding: Bool {get}
}

Model(Dataコントローラ)に計算済みプロパティを追加することに変更。

class Document: NSObject {
    private var dataObject: DataType = Hand()
    
    var conditionForAdding: Bool {
        return dataObject.numberOfItems < 5
    }
}

すると、こうなる。

class DataSource: NSObject, UITableViewDataSource, SourceType {
    private var document = Document.sharedInstance
    
    func addItemTo(tableView: UITableView) {
        if document.conditionForAdding {
            document.addNewItem(at: 0)
            insertTopRowIn(tableView: tableView)
        }
    }
}

条件判定はプロパティになっている。

ソースコード GitHubからどうぞ。
https://github.com/murakami/workbook/tree/master/ios/Hand - GitHub
関連情報 文化を調和させる
【Cocoa練習帳】 http://www.bitz.co.jp/weblog/
http://ameblo.jp/bitz/(ミラー・サイト)
いいね!した人  |  コメント(0)  |  リブログ(0)
2016-12-19 22:38:19

[Swifty]Handを取り除く

テーマ:ブログ

今回は難航した。元の発表はViewControllerでHandなどのデータ型に依存したコードを取り除くという内容だったが、自分のコードは、Model(Dataコントローラ)を用意しているので、データ型に依存していない。無理やり、Modelに適用してみたが、ちょっと、辛い。

DataTypeによって、CardがItemと、特定のデータ型に依存しないものになる。

class Document: NSObject {
    private var dataObject: DataType = Hand()
    
    public var numberOfItems: Int {
        return dataObject.numberOfItems
    }
    
    public func addNewItem(at index: Int) {
        dataObject = dataObject.addNewItem(at: index)
    }
    
    public func getItem(at index: Int) -> Card {
        guard let hand = dataObject as? Hand else {
            fatalError("Could not create Card Cell or Hand instance")
        }
        return hand[index]
    }
    
    public func deleteCard(at index: Int) {
        dataObject = dataObject.deleteItem(at: index)
    }
}

かなり、辛い。

protocol SourceType: UITableViewDataSource {
    //var dataObject: DataType {get set}
    func insertTopRowIn(tableView: UITableView)
    func deleteRowAtIndexPath(indexPath: NSIndexPath, from tableView: UITableView)
}
 
extension SourceType {
    func insertTopRowIn(tableView: UITableView) {
        let indexPath = IndexPath(row: 0, section: 0)
        tableView.insertRows(at: [indexPath], with: .fade)
    }
    
    func deleteRowAtIndexPath(indexPath: NSIndexPath, from tableView: UITableView) {
        tableView.deleteRows(at: [indexPath as IndexPath], with: .fade)
    }
}
class DataSource: NSObject, UITableViewDataSource, SourceType {
    private var document = Document.sharedInstance
    
    func addItemTo(tableView: UITableView) {
        if document.numberOfItems < 5 {
            document.addNewItem(at: 0)
            insertTopRowIn(tableView: tableView)
        }
    }
    
    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return document.numberOfItems
    }
    
    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCell(withIdentifier: "Cell", for: indexPath) as! CardCell
        let card = document.getItem(at: indexPath.row)
        cell.fillWith(card: card)
        return cell
    }
    
    func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCellEditingStyle, forRowAt indexPath: IndexPath) {
        if editingStyle == .delete {
            document.deleteCard(at: indexPath.row)
            tableView.deleteRows(at: [indexPath], with: .fade)
        } else if editingStyle == .insert {
            // Create a new instance of the appropriate class, insert it into the array, and add a new row to the table view.
        }
    }
}
class MasterViewController: UITableViewController {
 
    private var dataSource = DataSource()
    var detailViewController: DetailViewController? = nil
 
    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view, typically from a nib.
        tableView.dataSource = dataSource
        self.navigationItem.leftBarButtonItem = self.editButtonItem
 
        let addButton = UIBarButtonItem(barButtonSystemItem: .add, target: self, action: #selector(MasterViewController.addNewCard(sender:)))
        self.navigationItem.rightBarButtonItem = addButton
        if let split = self.splitViewController {
            let controllers = split.viewControllers
            self.detailViewController = (controllers[controllers.count-1] as! UINavigationController).topViewController as? DetailViewController
        }
    }
 
    override func viewWillAppear(_ animated: Bool) {
        self.clearsSelectionOnViewWillAppear = self.splitViewController!.isCollapsed
        super.viewWillAppear(animated)
    }
 
    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }
 
    @IBAction private func addNewCard(sender: UIBarButtonItem) {
        dataSource.addItemTo(tableView: tableView)
    }
 
    // MARK: - Segues
 
    override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
        if segue.identifier == "showDetail" {
            if let indexPath = self.tableView.indexPathForSelectedRow {
                let card = Document.sharedInstance.getItem(at: indexPath.row)
                let controller = (segue.destination as! UINavigationController).topViewController as! DetailViewController
                controller.detailItem = card
                controller.navigationItem.leftBarButtonItem = self.splitViewController?.displayModeButtonItem
                controller.navigationItem.leftItemsSupplementBackButton = true
            }
        }
    }
 
    // MARK: - Table View
 
    override func numberOfSections(in tableView: UITableView) -> Int {
        return 1
    }
 
    override func tableView(_ tableView: UITableView, canEditRowAt indexPath: IndexPath) -> Bool {
        // Return false if you do not want the specified item to be editable.
        return true
    }
}

今回は、効果がよく分からないものになってしまった。

ソースコード GitHubからどうぞ。
https://github.com/murakami/workbook/tree/master/ios/Hand - GitHub
関連情報 文化を調和させる
【Cocoa練習帳】 http://www.bitz.co.jp/weblog/
http://ameblo.jp/bitz/(ミラー・サイト)
いいね!した人  |  コメント(0)  |  リブログ(0)
2016-12-18 16:38:14

[Swifty]モデルもプロトコルへ

テーマ:ブログ

モデルのHandをDataTypeプロトコル適用ということにして、項目名をCardから汎用的なItemに変更する。

protocol DataType {
    var numberOfItems: Int {get}
    func addNewItem(at index: Int) -> Self
    func deleteItem(at index: Int) -> Self
    func moveItem(fromIndex: Int, toIndex: Int) -> Self
}
struct Hand: DataType {
    private var deck = Deck()
    private var cards = [Card]()
    
    public init() {
    }
    
    public init(deck: Deck, cards: [Card]) {
        self.deck = deck
        self.cards = cards
    }
    
    public var numberOfItems: Int {
        return cards.count
    }
    
    public func addNewItem(at index: Int) -> Hand {
        return insertCard(card: deck.nextCard(), at: index)
    }
    
    private func insertCard(card: Card, at index: Int) -> Hand {
        var mutableCards = cards
        mutableCards.insert(card, at: index)
        return Hand(deck: deck, cards: mutableCards)
    }
    
    public func deleteItem(at index: Int) -> Hand {
        var mutableCards = cards
        mutableCards.remove(at: index)
        return Hand(deck: deck, cards: mutableCards)
    }
    
    public func moveItem(fromIndex: Int, toIndex: Int) -> Hand {
        return deleteItem(at: fromIndex).insertCard(card: cards[fromIndex], at: toIndex)
    }
    
    subscript(index: Int) -> Card {
        return cards[index]
    }
}
ソースコード GitHubからどうぞ。
https://github.com/murakami/workbook/tree/master/ios/Hand - GitHub
関連情報 文化を調和させる
【Cocoa練習帳】 http://www.bitz.co.jp/weblog/
http://ameblo.jp/bitz/(ミラー・サイト)
いいね!した人  |  コメント(0)  |  リブログ(0)
2016-12-14 23:50:25

[Swifty]プロトコルを導入する

テーマ:ブログ

テーブルビュー関連のコードを切り離す。

SourceTypeというプロトコルを作り、プロトコルエクステンションとして中身を実装する。

protocol SourceType: UITableViewDataSource {
    func insertTopRowIn(tableView: UITableView)
    func deleteRowAtIndexPath(indexPath: NSIndexPath, from tableView: UITableView)
}
 
extension SourceType {
    func insertTopRowIn(tableView: UITableView) {
        let indexPath = IndexPath(row: 0, section: 0)
        tableView.insertRows(at: [indexPath], with: .fade)
    }
    
    func deleteRowAtIndexPath(indexPath: NSIndexPath, from tableView: UITableView) {
        tableView.deleteRows(at: [indexPath as IndexPath], with: .fade)
    }
}

データソースクラスに組み込む。

class DataSource: NSObject, UITableViewDataSource, SourceType {
    private var document = Document.sharedInstance
    
    func addItemTo(tableView: UITableView) {
        if document.numberOfCards < 5 {
            document.addNewCard(at: 0)
            insertTopRowIn(tableView: tableView)
        }
    }
    
    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return document.numberOfCards
    }
    
    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCell(withIdentifier: "Cell", for: indexPath) as! CardCell
        let card = document.getCard(at: indexPath.row)
        cell.fillWith(card: card)
        return cell
    }
    
    func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCellEditingStyle, forRowAt indexPath: IndexPath) {
        if editingStyle == .delete {
            document.deleteCard(at: indexPath.row)
            tableView.deleteRows(at: [indexPath], with: .fade)
        } else if editingStyle == .insert {
            // Create a new instance of the appropriate class, insert it into the array, and add a new row to the table view.
        }
    }
}
ソースコード GitHubからどうぞ。
https://github.com/murakami/workbook/tree/master/ios/Hand - GitHub
関連情報 文化を調和させる
【Cocoa練習帳】 http://www.bitz.co.jp/weblog/
http://ameblo.jp/bitz/(ミラー・サイト)
いいね!した人  |  コメント(0)  |  リブログ(0)
1 | 2 | 3 | 4 | 5 |最初 次ページ >>

AD

Ameba人気のブログ

Amebaトピックス

      ランキング

      • 総合
      • 新登場
      • 急上昇
      • トレンド

      ブログをはじめる

      たくさんの芸能人・有名人が
      書いているAmebaブログを
      無料で簡単にはじめることができます。

      公式トップブロガーへ応募

      多くの方にご紹介したいブログを
      執筆する方を「公式トップブロガー」
      として認定しております。

      芸能人・有名人ブログを開設

      Amebaブログでは、芸能人・有名人ブログを
      ご希望される著名人の方/事務所様を
      随時募集しております。