no_picture

LT駆動開発で UIDynamics を利用した万華鏡アプリを紹介した

A8D:2 というイベントが2014年8月3日に行なわれます。明日じゃねーか。 そんなことはさておいて、Augment8というグループがあります。 このグループは年に1回、普段作っているものをみんなに体験してもらう場をつくろうというイベントがあるらしく、Augment8 Day を省略して A8D というイベントをしているそうです。 デジタルなガジェットを一般の人に体験していただくイベントだ。 そのイベントに参加することになったので、このために作成したアプリを告知を兼ねてLT駆動開発06で紹介をしました。 というわけでまずスライド。 つづいて、スライド内で利用している動画。 万華鏡のサンプル1 万華鏡のサンプル2 UIDynamicsのサンプル iOS7 からUIKitで物理エンジンが搭載されていて気軽に使えるようになったらしい。 まだ試してなかったのだけど、普通の人にも楽しめそうなものとして万華鏡をつくってみた。 iOSのCoreMotionを使いiOS端末を操作して画面に映る万華鏡が変化するという寸法です。 普段、iOSアプリをつくってるわけではないのでそんなに凝ったことはしていません。 万華鏡といえば三角なのですが四角のものもあるそうで、手抜きで四角の万華鏡になっています。 Apple Swift で作成しているためアプリとして申請するのもできないし、体験できるようにソースコードを公開しておきますね。まだ勉強中でソースコードが汚いですね、わかります。 Augment8/kaleidoscope · GitHub サブディスプレイに対応しているので、プロジェクタに写したり Apple TV で画面に写したりできます。 当日は丸いものにプロジェクトションマップもどきをしたりする予定です。 操作用のiOS端末のために拡張パーツを用意しています。デザイン担当のあきさんが作成しています。これを装着すると…つづきは当日のA8D:2にて体験してください。 デジタルならではなところは動的に反射している数が増えたり、中身が変化したり、マスクが変化したりと用意してみました。 それなりに面白くなったでしょうか。 魅せるためのスキル不足なため、本当に楽しめるものになったのかよくわからないので、みんなの反応が気になります。 今回のLT駆動における初挑戦は「動画をつかってみる」でした。 スライドを公開する際に動画は別のところにアップロードしないといけないのがすこしつらい。 Swiftのコードを書いていて思ったことは、 ブロック構文がなかなか書きなれない 変数宣言で型から書きそうになる なぜか[を入力してしまう なるべつ let で済ませたい病 selector 補完効かない。つらい。(文字列で渡すから当たり前) ヘッダファイルいらないヒャッハー CGFloat が絡む数値計算なんかよくわからない(すぐ型エラーに阻まれる) などなどでしょうか。(咄嗟に思いついたものだけ書いた) UIDynamics で ビヘイビアのインスタンスを節約しようとするとランタイムエラーではまったりしたのも良い思い出です。アニメータごとにインスタンスをつくりましょう。 Viewを触れるようにしてみたけど、移動したViewは元の位置にもどるという残念な結果にもなりました。 最後になりますが、調整するのにBAUHAUSの上原さんやファナフェクトの方々にアドバイスをちょろっともらったりしました。さんきゅーです。

no_picture

iOSアプリでスリープしないようにしても、ホーム画面にもどったらスリープするよね

「iOS スリープしないように」で検索した結果、上位のいくつかの記事に [UIApplication sharedApplication].idleTimerDisabled = YES; とあり、これでうまく動作する。 注意事項として以下のこともかいてある。 上記の処理をするとアプリが終了してもスリープが起こらなくなってしまうため,アプリの終了時には必ず戻すようにします. 逆引きObjective-C for iPhoneアプリ - スリープモード(自動ロック)に移行しないようにする ただし、このまま放っておくとアプリを終わらせてもスリープが起こらなくなるので、アプリの終了時には必ず戻すこと! iPhoneSDKでスリープさせない方法 - 電子ガジェットいろいろ 開発メモ などなど書かれていて、事実なのか気になった。 UIApplication のインスタンスの設定を変えているのに OS の設定が変わるとは思えない。 というわけで、実際に試した。 普通にスリープしました。 記事自体も古いのでOSのバージョンによって違うのかもしれません。

no_picture

iOS でmtimeを設定する

iOS で ファイルの mtime を設定したい事態が発生した。 utimes(2) を利用してもよいのだけど、なるべく Cocoa の領域でコードは書いておきたい。 書き込む前に取得。取得したいファイルパスはわかっているとします。 NSString* path = @"hoge.txt"; NSFileManager* filemngr = [NSFileManager defaultManager]; NSDictionary* attributes = [filemngr attributesOfItemAtPath:path error:nil]; if (attributes) { NSDate *date = [attributes fileModificationDate] } NSFileManager-attributesOfItemAtPath:error で 辞書型でファイルの情報を取得できます。 NSDictionary-fileModificationDate は NSFileManager.h で拡張されたメソッドです。これを使えば取得できます。 書き込みする際は拡張メソッドはないですが、取得した辞書型に値を設定してに書き込みすればできました。 NSString* path = @"hoge.txt"; NSFileManager* filemngr = [NSFileManager defaultManager]; NSDictionary* attributes = [filemngr attributesOfItemAtPath:path error:nil]; if (attributes) { NSMutableDictionary* mattributes = [NSMutableDictionary dictionaryWithDictionary:attributes]; NSDate *date = [NSDate new];

no_picture

UIImage#initWithCGImage:scale:orientation で回転させる話

iOS な作業をしていた。 UImage な画像をてっとり早く回転する方法として、 image = [[UIImage alloc] initWithCGImage:image.CGImage scale:image.scale orientation:UIImageOrientationRight]; というのがある。 みたいなのがあるのですが、2度回転させようとして、下記のように2度呼んで回転しないなぁ、というハマり方をした。 image = [[UIImage alloc] initWithCGImage:image.CGImage scale:image.scale orientation:UIImageOrientationRight]; image = [[UIImage alloc] initWithCGImage:image.CGImage scale:image.scale orientation:UIImageOrientationRight]; 実際に並んでいれば気づくのだけど、違う場所で呼んでる場合は注意。 CIImage の使う向きを変えてCGImageは使いまわしてるだけなので、右に回転させたものを使うだけになる。「右に方向にして使う」という機能なので当たり前なのだけど。 どう対処したかというと、1回目の回転はちゃんと新しい画像をつくって対処した。 CGContextRef context = UIGraphicsGetCurrentContext(); CGContextRotateCTM(context,M_PI); CGContextTranslateCTM(context, -image.size.width, -image.size.height); [image.layer renderInContext:context]; image = UIGraphicsGetImageFromCurrentImageContext(); ちょっと無理矢理感。 移動させてるのは、(0,0) を中心に回転するので、画像が実際にかきこまれる位置が負の領域にいってしまってるから。

no_picture

設定画面で表示する値をアプリ側で設定する - iOS Second Stage Advent Calendar 2013

この記事はiOS Second Stage Advent Calendar 2013の19日目の記事です。 Advent Calendar に参加したのはギャングであるaguuu の中の人に脅されたわけではありません。 iOS のアプリケーションを iOS自体の設定画面で設定を行えるアプリケーション があります。その画面内に稀にバージョン番号が表示されているようなものがあると思います。 これを行うには方法として紹介されているのはビルドする際に値を差し替える方法があります。 ググるとこればっかりでてきます。 参考: アプリのバージョン、ビルドを「設定」の初期値として設定する 今回はそれをせずに、アプリ内で設定できたので紹介しておこうと思います。 動的設定とでも言えばいいのでしょうか。 この設定画面を用意する方法は Settings.bundle を追加し Root.plist を作成することで作ることができます。 今回のゴール バージョンってタイトルには書いてますが、最終起動時刻のほうがわかりやすいので、最終起動時刻に焦点を当てます。 、設定画面に値を表示するには、Setting Bundle を追加します。 root.plist に type を table のアイテムを追加し、DefaultValue を設定します。 DefaultValue を設定します。 大事なことなので強調しておきます。 あとは [NSUserDefaults standardUserDefaults] に値を書き込めばよいです。 NSUserDefaults* userDefaults = [NSUserDefaults standardUserDefaults]; NSDate* now = [[NSDate alloc] initWithTimeIntervalSinceNow:0]; [userDefaults setObject:[now descriptionWithLocale:[NSLocale currentLocale]] forKey:@"lastLaunched"]; とっても簡単ですね。 プロジェクトファイルはこちらにおいておきます たまたま最初に思いつく方法を試したらうまくいきました。(最初は Documents や Cache ディレクトリの中身を確認して plist を直接書き換えたなんて言えない…。しかも、何か勘違いをして UserDefaults

no_picture

UIWebView の UserAgent を変更した時に気をつけたいたった1つのこと

iOS SDK のUIWebView は UserAgent を変更することができます。 [XCODE] UIWebViewを用いる際にUserAgentを独自に設定する方法 UserAgent を変更したときに気をつけておきたいことを書きたいと思います。 UserAgent によって条件分岐する JavaScript ライブラリがあることを忘れないようにしましょう。 3時間以上たたかって、Google検索しても、なんにも情報ないし、「もうわからんわー」って投げ出したくなったところ JavaScript のライブラリのソースコード読み始めて、ようやく気付きました。 なるべくもとの UserAgent を尊重するほうが生きやすい世の中かもしれません。

no_picture

AutoLayout TIPS - 真ん中に固定幅のスペース

AutoLayout になかなか慣れません。 そうは言っても使わなければ、身につかない。 というか久しぶにりiOSのコード書いてるだけな気がする 今回挑戦したのはふたつのViewの間に固定幅をスペースをつくりたい。 具体的には以下の感じ。 書いた VisualFormatLanguage はこんな感じ。 |-[_leftView]-40-[_rightView]-| [_leftView(==_rightView)] V:|-[_leftView]-| V:|-[_rightView]-| 以下のように書いてもよい。 |-[_leftView(==_rightView)]-40-[_rightView]-| V:|-[_leftView]-| V:|-[_rightView]-| やってみると簡単。 プログラムで気軽にレイアウトできる。 具体的なソースコードは Github に アップしています。 主な処理はこの辺にあります。 簡単に解説 頭に V: がついているのは 縦方向に対する設定です。 |- の部分は OS 標準の幅になります。ぴったりつけたいなら、|-0- とします。 縦方向の左側 だけやってみます。 V:|-0-[_leftView]-0-| まとめ なれるまで発想のセンスがいる気がします。 論理的な手順で、作りたいレイアウトをするのはまだまだまだ説明できそうにないです。

no_picture

iOS で Digest認証してみる。 - AFNetworking

iOS で Digest認証するコードを書きました。 サンプルコードの作成は頼まれて作成しただけです。 折角なので、簡単な説明を 記事にしておきます。 サンプルコードはこちら テストサーバ構築 まずは動作確認をできるようにしないといけないので Digest認証 をするためのウェブサーバがないと困ります。Ruby の rack を使いました。 Digest認証をするには Rack のミドルウェア Rack::Auth::Digest::MD5 を使用しました。 Digest認証は ハッシュ化アルゴリズムの選択できるようになっているので、ミドルウェアはこのような名前になっているようです。 Rackのソースコードみにいったら、最初気づかなくて困りました。 config.ru は以下のように書きました。 use Rack::Auth::Digest::MD5, "auth", '' do |username| "password" end run proc { [200, {'Content-Type' => 'text/html'}, ['hoge']] } use の第三引数は opaque となります。デフォルトでは nil で、設定しないと動きません。はまりました。 蛇足ですが、 use の仕組みをよくしらなかったのでソースコードをちら見しました。 lib/builder.rb に実装があります。 def use(middleware, *args, &block) if @map mapping, @map = @map, nil @use << proc { |app| generate_map app, mapping } end @use << proc { |app| middleware.new(app, *args, &block) } end @map が nil の場合は middleware.new する処理が割り込むだけですね。引数はまるまる渡しています。 use する時の引数は 使用するミドルウェア の initialize メソッドをみればよいことがわかります。 Digest認証の場合は (ソースコード) def initialize(app, realm=nil, opaque=nil, &authenticator) @passwords_hashed = nil if opaque.nil?

no_picture

今後のiOSアプリケーションのために Auto Layout を学んだ - 内容編

今後のiOSアプリケーションのために Auto Layout を学んだ - 準備編 につづき勉強した内容をまとめていきたいと思います。 まずは Auto Layoutについて。概ね WWDC 2012 の session 202 のまとめだったり、使ってみた感じでのまとめです。仮説もいっぱい混ざってるので注意してください。 Auto Layout は制約ベースのレイアウトシステム Auto Layout は ふたつのViewの関係を設定していくことでレイアウトを構築します。 例えば ある特定のViewは親のView左から 自分の左端を 20pt あける のような制約をつくります。これらの制約を追加していくことで期待するレイアウトを構築します。 制約が無い場合はそれぞれデフォルトの振舞いがあります。 動きをみつつ上書きしていくような形になります。 制約のでViewのサイズなのが自動的に決定していくのでコードで記述する場合は frame の設定が不要になる書き方ができます。 Auto Resizing Maskの機能を再現することもできる Auto Layout は 以前のレイアウトシステム(?)である Auto Resizing Mask の表現範囲より大きなもので、エミュレートすることができます。Auto Resizing Mask でできることはすべてできますし、コードから利用する場合は今までどおりの挙動をします。 また、デフォルトでは Auto Resizing Mask をエミュレートしています。エミュレートさせたくない場合は translatesAutoresizingMaskIntoConstraints プロパティを NO に設定します。 作成できる制約 制約はふたつのviewに対して item1.attribute1 = multiplier x item2.attribute2 + constant という式を満たすように attribute1 を設定するようです。(たぶん) 等号の部分は不等号を指定することができます。制約はNSLayoutConstraint

no_picture

UITabBarControllerのMoreに表示される edit を消したいなー。

「UITabBarControllerのMoreに表示される edit を消したいなー。」と思いながら、なんてググればいいんだろーと思いつつも、ヘッダファイルをみていたら customizableViewControllers ってプロパティがあった。 迷わずに nil に設定した。うまくいった。 もし、UITabBarControllerを継承してるクラスがあるなら -viewDidLoad で処理してしまうのが早いです。 self.customizableViewControllers = nil; ない場合、用意しましょう。といってもいいんですが、タブ内の UIViewController の viedDidLoadで self.tabBarController.customizableViewControllers = nil; でも、いけました。 「継承してるコントローラあるのにわざわざ試したんだからねっ!」 ちなみに、 このプロパティは nil じゃない場合 "Edit" で表示されるコントローラをカスタマイズできてデフォルトはすべてのコントローラだよ。 的なことが書かれていました。なので空の配列を渡してもOKです。

no_picture

raptureXML でXMLのparse

XMLのパースしなきゃいけなくて、libxmlで処理するのめんどくさいなー。ということで、CocoaPodを探った結果、RaptureXMLを試してみることにしました。 URLから直接XMLを取得するイニシャライザがついていて、とても簡単に利用することができました。 CocoaPodsを使わない場合は libz と libxml2 をリンクしてやるようにして、RXMLElement.hとRXMLElement.mをプロジェクトに追加するだけで使えます。 だいたい以下のように利用してます。 NSURL* url = [NSURL URLWithString:@"http://eiel.info/hoge.xml"]; RXMLElement* root = [RXMLElement elementFromURL:url]; NSMutableArray* schedule = [NSMutableArray array]; [root iterate:@"item" usingBlock: ^(RXMLElement *item) { [schedule addObject:[[ALScheduleItem alloc] initWithRXMLElement:item]]; }]; i_schedule = [NSArray arrayWithArray:schedule]; RXMLElementオブジェクトを配列に格納しておいて利用しようとしたら、失敗したのでモデルオブジェクトを用意してやりました。 値を取り出すには [element child:@"day"].text; とやって取り出せます。DOMのインターフェイスになってますね。XPathも利用できるようです。 ソースコードも500行程度でコンパクトでした。

no_picture

Xcodeのテンプレート

Xcodeが genarate する templateですが、 いつもかきかえる部分があるのでなんとかしたいなーっておもっててしらべたら http://akisute.com/2009/06/xcode.html にかかれているんですが、 /Developer/Platforms/iPhoneOS.platform/Developer/Library/Xcode/ というディレクトリはすでにありません。 現在は /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/Library/Xcode/ あたりにあるようです。

no_picture

iOS24h Vol.1でCocoaPodsの紹介をした

iOS24hという ustream番組で午前3時にCocoaPodsについてしゃべりました。 CocoaPodsはObjective-C用のBunlderみたいなものです。 スライドを下記にあります。 http://eiel.github.com/iOS24h-vol1 impress.jsを使用してみたけどたいへん時間をつかったので次も使うか悩む…。 気合をいれて臨んだ割に人がいなかったかなー。 その他の資料は https://github.com/eiel/iOS24h-vol1

no_picture

iOSでFacebookAPIへのアクセス

最小限のサンプルを作成してみました。 FacebookのSDKいたれりつくせりでそれなりに簡単。 https://github.com/eiel/iOS-FacebookAPISapmle