トップ 追記

Cocoa練習帳

iOS/iPhone/iPad/watchOS/tvOS/MacOSX/Android プログラミング, Objective-C, Cocoa, Swiftなど

2012|01|02|03|04|05|06|07|08|09|10|11|12|
2013|01|02|03|04|05|06|07|08|09|10|11|12|
2014|01|02|03|04|05|06|07|08|09|10|11|12|
2015|01|02|03|04|05|06|07|08|09|10|11|12|
2016|01|02|03|04|05|06|07|08|09|10|11|12|
2017|01|02|03|04|05|06|07|08|09|10|11|12|
2018|01|02|03|04|

2018-04-12 PubHack.swift 2018-04に行ってきた

2018年4月12日(木)の夜間、東京都豊島区のTHE DUBLINERS' IRISH PUB 新宿店におきまして、「PubHack.swift 2018-04」を開催致しました。

PubHack.swift 2018-04

PubHack.swiftは今年からはじめました新しい形のイベントで、飲み会イベントを通じて、macOS/iOS/tvOS/watchOS/Androidエンジニアの人たちの交流を目的としています。
名前の由来を説明しますと、PubHackは英国 Pub Rock からとりました。
Pubは飲み会、Hackはプログラミング、.swiftはmacOS/iOS/tvOS/watchOS系です。

始めたばっかりということで、正直、浸透していませんが、それでも参加人数は7名と、予想した人数より多くなり大変嬉しいです。
また、参加された方のバックグラウンドも多彩で、新しいイベントとしては、よかったのではないかと思っています。

PubHack.swift 2018-04

純粋な飲み会イベントということで、長々と文章で説明するのも野暮だと思いますが、出てきた話題を何個かピックアップしますと、以下のとおりです。

  • ブロックチェーンの採掘についての理論と実装について。自分はこうしてます。
  • ブロックチェーン関連の開発で収入を得る方法。
  • Mac App Storeで食っていけますか?
  • App Storeで上位にランキングされるということ。
  • 公式に認められた副業について。誰か受注してくれませんか?
PubHack.swift 2018-04

次回は5月開催を予定しています!


2018-04-04 BUKURO.swift 2018-04

22018年4月4日(水)の夜間、東京都豊島区の池袋コワーキングスペース OpenOffice FORESTにおきまして、「BUKURO.swift 2018-04」を開催致しました。

BUKURO.swiftも浸透して来たようで、先月と同様に多くの方が申し込まれました。
初めて参加される方に、どうやってBUKURO.swiftを知ったのか伺ったところ、会社でmacOSプログラミングで悩んでいたところ、同僚から紹介されたとのこと。
ありがとうございます。
これからもアプリケーション・プログラマの方々が役立つ勉強会になるよう精進いたします!
そして、今回の発表はどれもプログラマの好奇心をくすぐるものでした。
よし、自分も頑張ろう!という気持ちにさせていただきました!

BUKURO.swift 2018-04

_ イベント概要

  • 東京 池袋で開催される Cocoa勉強会 と MOSA の合同勉強会です。
  • macOS/iOS/watchOS/tvOSプログラマーのための勉強会です。
  • 初心者大歓迎です。
  • 関連があれば、他の環境についてもOKです。
  • プログラマーが楽しくプログラミングできるようにサポートする場を提供したい
    • 勉強会に参加された方全員が学びを得られる様にサポートします!
    • 勉強会に参加できない方にも学び得られるよう、勉強会の成果を可能な限りアウトプットします!
    • プログラマの拠り所となる場を目指します!

Cocoa勉強会 関東には、以下のFacebookグループから、ご参加ください。

https://www.facebook.com/groups/cocoa.kanto/

MOSAのconnpassグループには、以下から、ご参加ください。

https://mosa.connpass.com/

発表資料はconnpassページからどうぞ!
また、会場の様子は、ハッシュタグ『#cocoastudy #mosa #bukuroswift』でtweetしています。

_ 矩形の移動

NSMatrixが非推奨になっているそうです。そこで、代替機能として、同じ大きさの矩形を整列させるための支援コードの発表です!

_ Swiftの文字列

以前、Cocoa勉強会 関東で発表されましたが、その後の状況の変化を加味した発表でした。
自分自身も、その後、経験を積み、前回と比較して理解度も上がり、プログラマの好奇心をくすぐる内容に楽しまさせていただきました。
SwiftのStringがUnicodeに高い割合で準拠しているのは知っていたのですが、例えば、文字をどういう用語で扱っているのか説明できずもどかしかったのですが、拡張書記素クラスタ(CodePoint)というのですね。そして、例えば、RubyはUnicodeスカラーで、JavaはUTF-16、PythonはUTF-8で扱うため、得られる文字列長が異なるとか、macOSのファイルシステムでの文字列がModified NFDとなっている理由。それから得られる日本語としての恩恵。文字の比較でUnicodeの一貫性のなさからNFDで比較すればいいという訳でない事。
曖昧に理解していた事が再確認できて、とても有益でした。

_ 個人製作Unityゲームのデモ

Unityを使った2Dと3DのWebGLアプリのデモです。十分遊べる完成度に驚かされました。やりますね!

本日は、ここで時間切れ。今回発表できなかった資料は次回の勉強会で!

次回は5月11日(金)開催を予定しています!
また、4月12日(木)にエンジニア飲み会 PubHack.swift 2018-04 を開催しますので、ご都合が宜しければ是非!待ってます!


2018-03-16 [BUKURO.swift]関東swift勉強会2018–03

画像の説明

2018年3月16日(金)の夜間、東京都豊島区の池袋コワーキングスペース OpenOffice FORESTにおきまして、「関東swift勉強会2018-03」を開催致しました。

画像の説明

_ イベント概要

  • 東京 池袋で開催される Cocoa勉強会 と MOSA の合同勉強会です。
  • macOS/iOS/watchOS/tvOSプログラマーのための勉強会です。
  • 初心者大歓迎です。
  • 関連があれば、他の環境についてもOKです。
  • プログラマーが楽しくプログラミングできるようにサポートする場を提供したい
    • 勉強会に参加された方全員が学びを得られる様にサポートします!
    • 勉強会に参加できない方にも学び得られるよう、勉強会の成果を可能な限りアウトプットします!
    • プログラマの拠り所となる場を目指します!

Cocoa勉強会 関東には、以下のFacebookグループから、ご参加ください。

https://www.facebook.com/groups/cocoa.kanto/

MOSAのconnpassグループには、以下から、ご参加ください。

https://mosa.connpass.com/

発表資料はconnpassページからどうぞ!
また、会場の様子は、ハッシュタグ『#cocoastudy #mosa #bukuroswift』でtweetしています。

_ キーイベント処理

スライドが用意できなかったということでホワイトボードを使った発表となりました。
macOSのアプリで、標準的なショートカットでない手段でキーボード操作を実現するための方法。例えばCMDキーの二重押下や長押しに対応するために行った手法が説明されました。
macOSアプリについて詳しくないので、自分もちょっと調べて見ようかなと思って聞いていたのですが、やりたい事ばかりなので、果たしていつ実現できるのか?

画像の説明

_ 独自Documentクラス

発表者のTIPSとして、独自のDocumentクラスを用意する方法が紹介されました。

_ NSTableVIew macOS 10.7以降

行をドラッグ&ドロップで入れ替える操作の対応について、macOS 10.7以降のモダンな手法が紹介されました。資料とサンプルコードは、AirDropで配布となりました。

_ Developer's Tech Lab 『Swiftでフレームワークを作る方法について』

MOSA de BBで質問があって、Swiftでフレームワーを作る方法について、調べたことの発表について、参加者と意見を交換しました。

_ Developer's Tech Lab 『DocumentクラスとNSFileWrapperについて』

独自のDocumentクラスでもNSFileWapperを使いたいのですが、その方法について、参加者と意見を交換しました。

_ Developer's Tech Lab 『iPhone X画面対応について』

iPhone X画面対応について、参加者と意見を交換しました。

次回もCocoa勉強会 関東との合同勉強会を4月に予定しています!
勉強したい方や、同じ業界の方々と情報交換したい方、お待ちしています!


2018-02-28 [macOS][iOS]SwiftでFrameworkを実装する

サンプル・コードの構成を説明すると、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するだけでアクセスできた。

_ ソースコード

GitHubからどうぞ。
https://github.com/murakami/workbook/tree/master/mac/Bedrock - GitHub

2018-02-26 [macOS][iOS]独自Documentクラス

Traditional version of MVC as a compound pattern

MVC

Cocoa version of MVC as a compound design pattern

Cocoa
NS
  • iOS 5 からUIDocumentクラスが用意されたが、少々、オーバースペック。
  • 筆者は、以前から、独自のDocumentクラスを用意していた。

Documentクラスはモデル・コントローラ

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)

2018-02-16 第108回 Cocoa勉強会 関東 BUKURO.swift 2018-02 レポート(2/16)

2018年2月16日(金)の夜間、東京都豊島区の池袋コワーキングスペース OpenOffice FORESTにおきまして、「BUKURO.swift 2017-12」を開催致しました。

_ イベント概要

  • Cocoa勉強会 関東とMOSAの合同勉強会です。
  • macOS/iOS/watchOS/tvOSプログラマーのための勉強会です。
  • 初心者大歓迎です。
  • 関連があれば、他の環境についてもOKです。
  • プログラマーが楽しくプログラミングできるようにサポートする場を提供したい
    • 勉強会に参加された方全員が学びを得られる様にサポートします!
    • 勉強会に参加できない方にも学び得られるよう、勉強会の成果を可能な限りアウトプットします!
    • プログラマの拠り所となる場を目指します!

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というゲーム制作のコーナーを設ける予定です!


2018-01-17 [macOS][iOS]サーバーレスアーキテクチャで悩んでます

今回は、AKIBA.swift 第12回 質疑トーク回! で発表した内容だ。この回は、発表者の課題を参加者とディスカッションして解決するという内容のため、この投稿には結論はないので悪しからず。

作りたいアプリは
  • サーバを避けたい
    • プログラム作成が面倒
    • 維持費がかかる
    • アプリがヒットしてしまい、サーバへのアクセスが増えると、開発者の負担がます
    • 規模が大きくなると、性能問題や、ダウンした際の対応など、課題が出てくる
  • 必要な機能は?
    • データの読み書きの機能が用意されている。
    • バックアップとしても利用できる。
    • 持っている複数の機器で共有できる。
    • 容量制限を超えたら、ユーザに料金の請求が行く。
    • 他ユーザと共有できる機能があると嬉しい。
  • 検討しているサービス
    • iCloudストレージサービス
      • キー値ストレージ
      • ドキュメントストレージ
      • CloudKit
    • Firebase
      • Realtime Database
      • Cloud Firestore
      • Cloud Storage
    • IBM Cloud (Bluemix) は?
    • AWS は?
  • iCloudキー値ストレージ
    • UserDefaultsのクラウド版。
    • ユーザごとに1 MB以内。
    • 指定できるキーは1024個まで。
    • 各キーに対応する値のサイズはそれぞれ1 MB以内。
  • iCloudドキュメントストレージ
    • macOSの場合、~/Library/Mobile Documents/iCloud~バンドルID/ 配下に格納される。
    • Info.plist に NSUbiquitousContainersキー を追加すれば、iCloud Driveに格納される。
      
<key>NSUbiquitousContainers</key>
      
 <dict>
      
 <key>iCloud.com.example.MyApp</key>
      
 <dict>
      
 <key>NSUbiquitousContainerIsDocumentScopePublic</key>
      
 <true/>
      
 <key>NSUbiquitousContainerSupportedFolderLevels</key>
      
 <string>Any</string>
      
 <key>NSUbiquitousContainerName</key>
      
 <string>アプリ名など</string>
      
 </dict>
      
 </dict>
  • iCloud CloudKit
    • 容量制限があり、超えると開発者の負担となる。
    • アプリケーションのモデルの格納先を想定していない。
    • 差分などのデータの受け渡しや、ユーザ間でのデータの共有のためのサービス。
  • Firebase Realtime Database
    • データの保存と同期がリアルタイムで。
    • クロスプラットフォーム(iOSやAndroid)。
    • 料金プラン
      
開発者の負担の上限が設定できる。
      • 無料
        同時に100接続。1GB。10GB/月。
      • 月額固定($25/月)
        
同時に100k接続。2.5GB。20GB/月。
      • 従量課金
        
同時に100k/db。$5/GB。$1/GB。
  • Firebase Cloud Firestore
    • Realtime Databaseの次のデータベース。
    • Realtime Databaseと比較すると、階層的なデータに対応している。
  • Firebase Cloud Strage
    • ストレージ。
    • 共有できる
    • 料金プラン
      • 無料
        
5GB。1GB/日。2万操作/日。5万取得操作/日。
      • 月額固定($25/月)
        
50GB。50GB/日。100k操作/日。25万取得操作/日。
      • 従量課金
        
$0.026/GB。$0.12/GB。$0.05/10k。$0.004/10k。

2017-12-25 [BUKURO.swift]振り返りと目標

二年前に勉強会の運営方法が変わり一時は活動が停止しそうな状況となりましたが、皆さんのご協力のもと何とか継続してきました。最近は開催頻度を下げ発表の質を高め、他勉強会にも積極的に参加し、内容を見直しして結果なのか、新たな参加者も増えてきました。

来年も、勉強会の活動を通じてプログラマーが楽しくプログラミングできるよう目標を掲げて活動していきたいと思いますので、宜しくお願いします!

  • 勉強会に参加された方全員が学び得る場を提供!
  • 勉強会に参加できない方も学び得るよう、勉強会の成果をアウトプットする!
  • プログラマの拠り所となる!

_ 【Cocoa練習帳】

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

2017-12-24 [macOS][iOS]iCloud Driveに文書を格納する

前回のおさらいから。

ADC文書によると、iCloudストレージを利用する方法は以下となる。

  • キー値ストレージ
  • iCloudドキュメントストレージ
  • Core Dataストレージ
  • CloudKitストレージ

前回、iCloudドキュメントストレージに読み書きしたが、macOSだと ~/Library/Mobile Documents/iCloud~バンドルID/ 配下だった。

iCloud Drive配下でないのだが、どうやればiCloud Driveに読み書きできるのか?調べてみた。

CapabilitiesでiCloudを有効にし、Info.plist に NSUbiquitousContainersキー を追加すればいいようだ。

<key>NSUbiquitousContainers</key>
    <dict>
        <key>iCloud.com.example.MyApp</key>
        <dict>
            <key>NSUbiquitousContainerIsDocumentScopePublic</key>
            <true/>
            <key>NSUbiquitousContainerSupportedFolderLevels</key>
            <string>Any</string>
            <key>NSUbiquitousContainerName</key>
            <string>アプリ名など</string>
        </dict>
    </dict>

NSUbiquitousContainersキー には、コンテナ識別子を設定する。

_ ソースコード

GitHubからどうぞ。
https://github.com/murakami/KeepADiary - GitHub

_ 【Cocoa練習帳】

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

2017-12-22 [macOS][OpenGL]OpenGLに再挑戦(其の弐)

前回の続き。

まず、分かったのは、こまめにglGetError()でエラーが発生しているのか確認すること。その結果、glVertexPointer()の呼び出しで、GL_INVALID_ENUM が発生していることが分かった。

そして、OpenGLのバージョンが2.1だったのが、以下の設定で4.1になることが分かった。設定してしまうと、古いAPIが使えなくなるので、一旦、見送るが。

glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE | GLUT_3_2_CORE_PROFILE);

エラーの内容から、バッファオブジェクトを使用しない方法だったが、使用する方法でないと弾かれるのではと考え、試してみることにした。

GLuint  bufferID;
 
void init(void)
{
    assert(glGetError() == GL_NO_ERROR);
    
    /* ディザ処理を無効にする */
    glDisable(GL_DITHER);
    assert(glGetError() == GL_NO_ERROR);
    
    std::string ver((const char*)glGetString(GL_VERSION));
    assert(! ver.empty());
    std::istringstream verStream(ver);
    
    int major, minor;
    char dummySep;
    verStream >> major >> dummySep >> minor;
    const bool useVertexArrays = ((major >= 1) && (minor >= 1));
    NSLog(@"OpenGL Ver. %d.%d", major, minor);
    
    /* 三角形の頂点を定義する */
    const GLfloat data[] = {
        -1.0f, -1.0f, 0.0f,
        1.0f, -1.0f, 0.0f,
        0.0f, 1.0f, 0.0f
    };
    
    if (useVertexArrays) {
        /* バッファIDを取得する */
        glGenBuffers(1, &bufferID);
        
        /* バッファオブジェクトをバインドする */
        glBindBuffer(GL_ARRAY_BUFFER, bufferID);
        
        /* 配列の値をバッファオブジェクトにコピーする */
        glBufferData(GL_ARRAY_BUFFER, 3 * 3 * sizeof(GLfloat), data, GL_STATIC_DRAW);
        
        glEnableClientState(GL_VERTEX_ARRAY);
        assert(glGetError() == GL_NO_ERROR);
        
        glVertexPointer(3, GL_FLAT, 0, bufferObjectPtr(0));
        
        GLenum glErrorCode = glGetError();
        NSLog(@"%s (error code:0x%x)", __func__, glErrorCode);
        assert(glErrorCode == GL_NO_ERROR);
    }
    assert(glGetError() == GL_NO_ERROR);
    
    /* ディスプレイリストを作成する。 */
    gListID = glGenLists(1);
    glNewList(gListID, GL_COMPILE);
    assert(glGetError() == GL_NO_ERROR);
    
    if (useVertexArrays) {
        glDrawElements(GL_TRIANGLES, 3, GL_UNSIGNED_INT, &gListID);
    }
    else {
        glBegin(GL_TRIANGLES);
        glVertex3fv(&data[0]);
        glVertex3fv(&data[3]);
        glVertex3fv(&data[6]);
        glEnd();
    }
    assert(glGetError() == GL_NO_ERROR);
    
    glEndList();
    
    //NSLog(@"%s (error code:0x%x)", __func__, glGetError());
    assert(glGetError() == GL_NO_ERROR);
    
    /* 描画 */
    glutDisplayFunc(display);
    
    /* リサイズ処理 */
    glutReshapeFunc(resize);
    
    /* キーボード */
    glutKeyboardFunc(keyboard);
    
    /* 特殊キー */
    glutSpecialFunc(special);
    
    /* マウス */
    glutMouseFunc(mouse);
    
    /* ドラッグ */
    glutMotionFunc(motion);
    
    /* バックグランド処理 */
    glutIdleFunc(idle);
    
    /* コンテキスト・メニュー */
    glutCreateMenu(main_menu_callback);
    glutAddMenuEntry("Quit", QUIT_VALUE);
    glutAttachMenu(GLUT_RIGHT_BUTTON);
}

ダメだ。やはり、glVertexPointer() を呼んだ後にエラーだ。

_ ソースコード

GitHubからどうぞ。
https://github.com/murakami/workbook/tree/master/mac/IRIS - GitHub

_ 【Cocoa練習帳】

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