投稿

2013の投稿を表示しています

iPod library access クラウド音源への対応

iOS 6よりMPMediaItemのプロパティに MPMediaItemPropertyIsCloudItem というものが追加されました。 これはデバイス内にはなく、クラウド上にある曲の場合にYES(を包んだNSNumber)が返されます。 このクラウド上にある曲というのは、私のデバイスですとiTunes Storeで購入したがデバイスには入っていない曲が該当しました。説明によるとiTunes Matchがどうこうと書いてありますが、現在日本ではiTunes Matchが使えないので確認はしていません。 (この段落の話はiOS 7)iOSに付属のミュージックアプリでは設定項目にこれを表示するかしないかを選択するところがあり、選択した場合はデバイスに入ってなくてもクラウドにあれば一覧に表示され、再生操作をするとダウンロード(ストリーミング?)されて再生します。選択しなければ表示されません。また、クラウド曲を再生した時にデバイス内にデータが残るようで、これは設定を選択しない方に切り替えても表示されます。ところが、自作アプリ内からライブラリにアクセスし、データを取得するとこの設定に関わらず全てのクラウド上の曲が得られる(得られてしまう)ようです(もしかしたらどこかで変更が出来るかもしれない)。インターネット上から取得するとどうしてもレスポンス遅延がありますので、排除したいというときはMPMediaItemPropertyIsCloudItemがYESを返すアイテムを排除する処理が必要になります。

SilentBonusTrack申請

SilentBonusTrackというアプリを申請しました。 すがすがしい気持ちよりも、やっとここまで来たかという安堵と大きな不具合が無いようにという気持ちのほうがある。 旬らしいということであまちゃんをスクリーンショットで使わせてもらった。 SilentBonusTrackのコンセプトはタイトルから予想できる通り、「カセットでアルバムを聞く時は、各面の終わりの無音部分もそのアルバムに含まれる」というもの。 制作動機の中心がこのコンセプトです。無音部分をコンセプトにしたアプリを出したかった。ただ実際のカセットプレーヤの通りに作ったらそれ以上特別なことはなにもすることがない。せいぜいアプリのタイトルに反映するくらい。

iOSアプリ開発に関する細かいこと Objective-C編

個別に記事にまとめるほどでもないiOSアプリ開発に関する細かいこと 画像の端をにじませる Renders with edge antialiasing 画像の端をにじませる info.plistで設定する Localizable.strings NSLocalizedString(@"distanceLabel", nil); Localizable.strings "distanceLabel" = "距離"; なぜDeployment Targetの設定箇所は2つあるのか Deployment Target(アプリ動作可の最低ライン)はPROJECTとTARGETにそれぞれあり、2つあることになる。TARGETのほうは初めは薄い色になってる。PROJECTで設定するとそれに伴いTARGETの値も変わる。別にするメリットも殆ど無いと思うので、設定はPROJECTだけにすればよいと思われる。一度TARGETを何かに設定してしまうと「連携モード」に戻す手段がわからないので、「連携モード」を解除したくないなら触らないほうがいい。 Build SettingsのCode Signing IdentityとProvisioning Profile Code Signing Identity 証明書の選択。Provisioning fileではない。証明書を選べば対応するProvisioning fileも選ばれることになるので、Provisioning fileの選択と解説される場合もある。Automaticの欄にあるiOS DeveloperやiOS Distributionを選んでおけばその名前で始まるものが自動で選ばれる。 Provisioning Profile Automaticになっていれば自動で選ばれる(上で指定されている証明書とBundle Identifierを基に選ばれるのかと思われる)。 statusBarOrientation [[UIApplication sharedApplication] statusBarOrientation] viewDidLoadで正確な値が取得出来るかどうかは要調査。 複数引数メソッドの遅延処理 doubl

iPod library access

iPodライブラリアクセスを使う上での注意点のメモです。 使用バージョン:iOS 5あるいはiOS 6 特徴 iPodプレーヤである曲を再生中にその曲を含むコレクションを設定しても曲は途切れることがない。 説明ではMPMusicPlayerControllerはMPMediaPlaybackデリゲートを実装している。このデリゲートの中でprepareToPlayはrequiredとなっているが対応してないようだ。 (追記2014/12)Base SDKがiOS5.0ではprepareToPlayでアラームが発生する。これはそのバージョンのMPMusicPlayerControllerがMPMediaPlaybackデリゲートを実装していないため。それより後のどこかのバージョンで実装されている模様。 使うプレーヤの選択 オーディオを再生できるのは一度に1つのミュージックプレーヤーのみです。ミュー ジックプレーヤーは、アプリケーションのメインスレッドでのみ使用できます。2種類あります。 iPodMusicPlayer-バックグラウンドで再生可(追記2014/12 iOS 8よりsystemMusicPlayerに変更) applicationMusicPlayer-バックグランドで再生不可 listenerの設定 ライブラリ更新 曲が変わった時 曲の再生状態が変わった時 ボリュームが変わった時 大量の曲を更新する時はライブラリ更新のメソッドがかなり頻繁によばれます。 iPod再生中にライブラリから曲を削除すると、現在再生中の曲と次の曲は再生されますが、その次の曲は再生されません。エラーも出ません。 停止状態からある曲を再生させた時に呼ばれる順番は 1アイテムチェンジのメソッド(このとき再生状態はstop) 2再生状態変更のメソッド(このとき再生状態はplay) の順です。 逆に再生状態(または一時停止)から停止させた時は 1再生状態変更のメソッド 2アイテムチェンジのメソッド の順。 再生状態と一時停止の変更では 再生状態変更のメソッド のみです。 デバイスで新規プレイリストを作成したときにもライブラリ更新のコールバックが呼ばれます。 Sessionの設定 セッションの設定がしてあると思います。

iOS 7について

気になるのはC言語ベースのAudioSessionが非推奨になったこと。 AVAudioSessionを使え、とのこと。 以前、AVAudioSessionの一部分が非推奨になったために、アプリを作る際はAudioSessionのほうに統一した方がいいんじゃないかという内容を書きましたが、こんどはAVAudioSessionの方を推奨するようです。 他に気付いたもの AVSpeechSynthesizer AVSpeechUtterance しゃべらせることが出来る?

LadderTouchのカテゴリ変更

教育から仕事効率化にしました。 だいぶカテゴリー内順位が上がりました。 教育は層が厚いですね。 「幼児向け」「義務教育」「専門」ぐらいに分けたらちょうどよくなるような感じがします。 もしくは「技術」カテゴリーがあればLadderTouchにとってはいいかもしれません。

iOS 7 Design Resources

iOS7のいろいろな資料を読んでのメモ書き。 iOS7はこれまでのバージョンアップより資料が多い気がする。 iOS 7 UI Transition Guide 起動画面 以前からiPhone用の起動画面は画面全体を覆うものだったがiPad版のほうはステータスバーの領域をカットする1004x768のような中途半端なものだった。これがiOS7からはiPad iPhone共にステータスバーの領域をカットしないものになった。画面全体を覆う画像を用意すればいい。 アイコン iOS7で使用するアイコンの大きさは変更になった。 120 x 120 iPhone iPod touch 76 x 76と152 x 152 iPad 120 120の場合、枠のカーブはだいたい34から10へのベジエ曲線。 76 76の場合、枠のカーブはだいたい22から6へのベジエ曲線。 起動画面、アイコン共に、Xcodeでどのファイルをどれとして使用するかを関連付けるようになった。前までは名前の決まりがあったがなくなったかもしれない。 ステータスバーが非表示に出来なくなったようです。

SilentBonusTrackを作成するのに使ったフレームワーク

iPod Library Access [MPMusicPlayerController applicationMusicPlayer]を使うか[MPMusicPlayerController iPodMusicPlayer]を使うか。 音楽を流しながら、他のアプリを実行する使い方も出来るようにしようと思っていました。 バックグラウンドでも動作させたかったので[MPMusicPlayerController iPodMusicPlayer]にしました。[MPMusicPlayerController applicationMusicPlayer]はバックグランドでの動作は出来ません。 「頭The抜き」「頭a抜き」「頭an抜き」は自作で行っています。 AVQueuePlayer アプリがバックグラウンドになった時には主導権を剥奪されるので細かい制御をさせることが出来ない。バックグラウンドでA面の曲、空白、AB切り替え、空白、B面の曲という流れを行おうとすると、iPod Libraryの曲と自分で用意した音(形式は曲、中身は空)を一緒のリストにあらかじめ入れて置かないといけない。これがiPod Library Accessの機能でどうやるのかやりかたが見つからず、それらを同列に扱えるものとして、AVQueuePlayerを使う。 こちらに一つのアプリをほぼまるごと解説しているサイトがある。 http://mtl.recruit.co.jp/blog/2012/07/iphone_dev_jpup.html AudioSession カテゴリはMediaPlayback。そしてmixOthersプロバティを1にする。 再生すべきものは AVAudioPlayer-操作音 AVQuerePlayer-空き時間を含めたファイル iPodからの再生音。 バックグランドになっても再生したかったので、この設定になった。 Core Animation カセットテープの動きを表現するのに使用。 リールの回転と、テープ巻き込み、白テープと黒テープの切り替え。 Core Text カセットケースについているインデックスカードで曲の情報を表示します。 やりたいことは 余ったスペースに再生時間表示。スペースが小さい時は次の行へ。 長い曲名は

AVQueuePlayer

AVQueuePlayer AVPlayerのサブクラス。 複数のアイテム(曲)を登録しておき一度の指令でそれらを連続再生出来る。 インスタンス生成時、または生成後の初期化時に、AVPlayerItemを含んだNSArrayを渡す。 再生途中に他のアイテムの追加が出来るのがすばらしい。再生が途切れることがない。 seekToTime:という指定した場所に再生場所を移動させるメソッドがある。これはAVPlayerから継承している。このメソッドでの指令の仕方の時間は1曲目の頭からの時間ではなく、その曲の頭からの時間。つまり5曲目再生中にseekToTime:で5秒を指定すると、5曲目の5秒のところに移る。 インスタンス作成 queuePlayerWithItems: 曲追加 insertItem:afterItem: プロパティ currentItem これはAVPlayerから継承。割り込みによる停止中でもnilにはならない。 全部の曲の再生が終わるとnilになる。 AVPlayerItem インスタンス生成時、または生成後の初期化時に、NSURLかAVAssetを渡す。 AVPlayer CMTime time = CMTimeMake(1800, 600); CMTimeGetSeconds(time)

Audio Session細かいことまとめ

SessionActive化のタイミング 電話がかかってきて電話に出た時は、End Interruptionが呼ばれないそうなので、どこでSessionをActiveにするか、検討する必要がある。 割り込みのタイミング アプリをバックグラウンドにしたときに音楽を再生していない場合は割り込みが入る(イニシャライズ時に指定した関数が走る)。再生している時は入らない。「何もしていないなら切りますよ」的なニュアンスで何かの処理が走る模様。割り込み関数が実際に走るのはフォアグラウンドにしたとき。begin分とend分の2回走る。 バックグラウンド機能のON OFFやmixWithOthersのON OFFも関係あります。 AVPlayerの割り込みメソッド呼び出しについて AudioSessionのイニシャライズ時に指定する割り込みメソッドは再生中で無くても呼ばれるが、AVPlayerの割り込みメソッドはplay中でないと呼ばれない。(検証不十分) AVPlayerの自動SessionActive機能について AVPlayerには割り込み完了時にSessionActiveをYESにする機能があるのだが、この機能が少し癖があるので気を付けたい。 まずはいろいろなパターンを調べた。割り込みはiOSに付属しているアラームを使った。ちなみにタイマーだと1つしか登録できないが、アラームだと複数登録できる。 パターン1:初めにアラーム設定し、アプリを起動する アラーム設定する アプリ起動 AVPlayerインスタンス作成 セッション初期化 セッションアクティブ化 アラーム発生 アラーム処理(OKをタップ) 次のアラーム発生で割り込みメソッドが呼ばれない → 自動でアクティブ化されない パターン2:アプリを起動してから一旦バックグラウンドにして、アラーム設定し、再びアプリを起動する アプリ起動 AVPlayerインスタンス作成 セッション初期化 セッションアクティブ化 アラーム設定する アプリ起動 AVPlayerインスタンス作成(viewDidLoadに入れていたので再び処理が走った) セッション初期化(viewDidLoadに入れていたので再び処理が走った) セッションアクティブ化(viewDidLoadに入れ

Affine行列の適用順序

イメージ
しょっちゅう忘れてしまうので… 基本 CGではAffine行列は3x3の行列で a b 0 c d 0 tx ty 1 で表される。 この行列は元データである個々の座標に対して後ろから掛かり、適用後の座標を出す。 これは行列の中の移動を表すtx,tyの位置から明らか。 前から掛けると(行列)(縦表現座標)となり、結果は(ax+by,cx+dy,tx+ty+1)。これは求めたい結果ではない。 後ろから掛けると(横表現座標)(行列)となり、結果は(ax+cy+tx,bx+dy+ty,1)。こちらが求めたい結果。 ちなみに座標は(x,y,1)となる。最後の1は必要。 ということで 個々の座標データに行列を適用させるというのが行列の使われ方 座標に対して後ろから掛かる という前程で進める。 複数の行列の適用順序 CGAffineTransform t = CGAffineTransformIdentity; t = CGAffineTransformScale(t, 0.5, 2.0); t = CGAffineTransformTranslate(t, 100.0, 100.0); t = CGAffineTransformRotate(t, 1.0); とプログラムを書いた場合、最終的な行列tは (Rotate演算行列)(Translate演算行列)(Scale演算行列) の結果となる。 つまり、行列追加関数は既存の行列の前に新しい行列を挿入する。 これが座標に後ろから掛かるので、個々の座標データにRotate演算、Translate演算、Scale演算の順に実行されたことと同じ結果(実際には先に適用行列の積が計算されていて、その結果を座標データに適用すると思う)。この順番は関数が書かれている順番と反対。 上のはCGAffineTransformの場合だが、 drawRect内でCGContextRefに行列を与える関数 CGContextScaleCTM(context, 0.5, 2.0); CGContextTranslateCTM(context, 100,100); CGContextRotateCTM(context, 1.0); も同様の法則。 また、view.layerに与え

C言語系のいろいろ

charを8ビットフルに正数として使う場合にunsignedは必要か char型をint型に何かの理由でキャストするときにcharの最上位ビットが1だとマイナスの値のintになってしまう。 charは文字なんだから正数(と0)しか扱わない前程で処理してくれるかと早とちりすると危険。 NSLogやprintfの引数として渡すときに、値を見ようとして%dを使った時も同様。ちなみに%uにするとめちゃくちゃデカイ値が表示されてかなりわけのわからん状態になる。 iOSアプリの開発だとcharを使う機会はかなり少ないので見落としやすい。 また、unicharというのもあって、そっちはもとからunsignedで宣言されていて紛らわしい。 ということで正数と0のみの場合はcharでもunsignedは必要。

Mac Fanの表紙が動きます(Mac Fan X ARART)

イメージ
Mac Fanの表紙が動きます。 Mac Fan (マックファン) 2013年 06月号の表紙がアマゾンで見れるようになりました。表紙の前田敦子さんの右肩あたりに 表紙が動き出す!! iPhoneアプリ「Mac Fan X ARART」で表紙を覗いてみよう という文字が見えます。どういうことでしょうか? このARARTとは iPhoneのカメラで取得した映像がディスプレイの中で動き出す というアート作品です。 例えば、花のつぼみの絵にカメラを向けてディスプレイに映すと、アプリの中でその映像を分析し、つぼみの位置のところを開花する花の動画に変換し表示します。ユーザーには現実の世界(つぼみ)とは違う別の世界(開花の様子)がディスプレイの中に見えます(まあこの拡張世界をどううまく作るかはセンスが必要ですが)。 下のが公式のビデオです。 ARARTチームはいろいろな会社の宣伝活動に技術を提供しているようです(たぶん)。 今回、このARARTがMac Fanの表紙で体験できるようになります。 Mac Fanの表紙用に作ったアプリ「Mac Fan X ARART」をダウンロードして紙面に向けて実行すれば出来ます。 Mac Fanがどのような世界を用意しているかは見てのお楽しみということで、とりあえずこのARARTというのをやってみます。 アプリはこちらで取得出来ます。(Mac Fan + ARARTのアプリとは別) ARART やり方は アプリをダウンロードとインストール 絵画が置いてあるサイトを表示 アプリを実行 です。 詳しく説明していきます。 アプリをダウンロードとインストール アプリを起動後に追加でインストールするデータがかなりあります。そちらは回線に余裕のある環境でダウンロードしてください。 サイトを表示 パソコンでこちらのサイトを表示します。 http://arart.info/museum/ 絵を紙に印刷してもアプリを実行できます。 アプリを実行 アプリを起動するとカメラ機能が有効になり、画面にはカメラに取り込んだ映像が表示されます。 まずは絵画が画面に入るようにして下さい。停止させた状態で少し(1〜2秒)経つと動画が始まります。 無理な体勢で全部の絵画を見ていくと手が疲れる

Form Sheetの画面回転処理

あるViewControllerから別のViewControllerをモーダルで呼び出すときにform sheetという表示方法がある。このform sheetというのは画面全体を覆うのではなく"回"のように中央に小さなViewを表示するタイプ。 この呼びだされたもの自体もViewControllerなので、デバイス回転に対するメソッドを持つことが出来るが、form sheetの場合はその回転メソッドは無視して、呼び出し(親)の向きに従うようである。 iOS View Controllerプログラミングガイドにこう書かれています。 画面全体を占めないView Controllerは一般に、向きを考慮しなくても構いません。親View Controllerか ら描画領域を指定されるので、その中に描画すればよいのです。一方、ルートView Controller(ある いは画面全体を表すView Controller)は、デバイスの向きを意識することが多いでしょう。 ということで「親View Controllerか ら描画領域を指定される」に「向き」も含まれていると解釈すれば、親ViewControllerに従うという理解で良さそうです。 ただ、 iOS5とiOS6で挙動が若干違うようです。 記述してある対応画面が親コントローラと子コントローラで同じならばいいんですが、問題となるのはiOS5で違う場合の処理です。いろいろやってみたのですが、どうも法則がつかめず。 パターン1 親の対応方向が子の対応方向を含む わからない (例) 親コントローラ:全方向 子コントローラ:rightのみ iOS5 親は回転に反応せず。子はrightのみ。 iOS6 親が全方向に対応し、それに子も従う (例) 親コントローラ:全方向 子コントローラ:UpSideDownのみ iOS5 親は回転に反応せず。子はUpSideDownのみ。 iOS6 親が全方向に対応し、それに子も従う (例) 親コントローラ:全方向 子コントローラ:rightとUpSideDownのみ iOS5 親も子もrightとUpSideDown。 iOS6 親が全方向に対応し、それに子も従う (例) 親コントローラ:全方向 子コントローラ:portraitとUpSideDownのみ iOS5 親も子もpor

NSStringいろいろ

NSStringについてのいろいろ。 記事を書いた時のiOSバージョンはiOS6.1.3です。 初期化時の複数バイトエンコーディングの扱い - (id)initWithCString:(const char *)nullTerminatedCString encoding:(NSStringEncoding)encoding; は引数にencodingがあるが、複数バイトエンコーディングのものを指定すると、全て0となっているバイトで文字列末端とみなされるようだ。 例えば2バイトで 00000000 10101010 と表される文字があるとすると00000000のバイトを文字列末端とみなすらしい。 長い文字列のはずが、いきなり初めのほうで文字列が終わってしまう。 + (id)stringWithCString:(const char *)cString encoding:(NSStringEncoding)enc も同様。 上位8ビットが0の時だけでなく下位8ビットが0の時でも末端と見るようだ。 おそらく 8ビット毎に取り出して char selectedChar = 取り出し関数(); if(selectedChar == 0){ 末端処理 }else{ switch(エンコード){ 各エンコード別の処理 } } のような処理だ。 そもそも8ビットの0を内部に含むエンコーディングはC言語文字列の定義から外れるという考え方なんだろう。 対策は – initWithBytes:length:encoding:(これはどのエンコードでもいけそう) - initWithCharacters:length:(UTF-16限定?) + stringWithCharacters:length:(UTF-16限定?) などを使う。 第3水準、第4水準の漢字に対応しているか まず、漢字の分類方法なのだが、第1、第2、第3、第4とあり、数字が大きいほうに使用頻度の低い漢字が割り当てられている。 第4水準の初めの文字は「毎」のカンムリだけを取り出したようなもの。読み方はわからず。このブログでは表示出来ない。 で、この漢字をiOSで扱えるのか? Unicodeに含まれていれば対応しているんではないか?と思うかもしれ

Unicodeについて

Unicodeで日本語が該当する箇所 Unicodeの中で日本語が該当する所を調べてみました。 漢字は基本的に、日本語で使われるか中国語で使われるかは区別されません。ですからこれらの範囲の中には中国でしか使われない漢字も含まれています。 ここでは割り当てられている領域を書いています。実際に文字が割り当てられている範囲が書かれている資料とは終わりの値が若干異なることがあります。 ひらがなU+3040~U+309F(ひらがな文字は U+3041~U+3096) カタカナU+30A0~U+30FF(カタカナ文字はU+30A1~U+30FA) 「CJK統合漢字」U+4E00~U+9FFFに、約20,000字 「CJK統合漢字拡張A」U+3400~U+4DBFに、6,500字強 「CJK統合漢字拡張B」U+20000~U+2A6DFに、約42,000字 「CJK統合漢字拡張C」U+2A700~U+2B73F(2009年10月制定のUnicode5.2.0) 「CJK統合漢字拡張D」U+2B740~U+2B81F(2010年10月制定のUnicode6.0) また、一覧の中から私が目視で日本語ぽいと判断したものに U+2E80-2EFF CJK部首補助 U+2F00-2FDF 康熙部首 U+3000-303F CJKの記号及び句読点 U+31F0-31FF 片仮名拡張 U+3200-32FF 囲みCJK文字・月 U+3300-33FF CJK互換用文字 U+FE30-FE4F CJK互換形(たてがき?) U+FE50-FE6F小字形(たてがき?) U+FF00-FFEF半角・全角形 があります。 漢字ではこれらの「CJK統合漢字」や「CJK統合漢字拡張A~D」とは別に、 U+F900~U+FAFFとU+2F800~U+2FA1Fに「互換漢字」 U+E0100〜U+E01EFにIVS用のバリエーション符号 があります。 Objective-CでのUnicode文字列の扱い iOSの文字列の文字コードはUnicodeです。Unicodeには表現方法がいくつかあって、おそらく、UTF-16という方法を用いていると思います。(はっきりした資料が見当たらず予想という前程) このUTF-16はほとんどの文字を2バイトで表現

konashi 1.0を詳しく見てみる

Getting started サイトにある Getting started を読んでみます。 最初にkonashiライブラリを取得します。 githubから取得するか「こちらから最新版のライブラリをダウンロード」からzipファイルをダウンロードすればOKです。 手元にkonashiがありませんので、プロジェクトの作成はしませんが、引き続きGetting startedに目を通してみます。 核になる部分は2つのメソッド [Konashi pinMode:LED2 mode:OUTPUT]; [Konashi digitalWrite:LED2 value:HIGH]; です。 上のコードで「pin番号がLED2のものをOUTPUTに設定」して 下のコードで「LED2にHIGHを書き込み」しています。 ちなみにLED2 OUTPUT HIGHはint型に#defineされています。 LED2が点灯すれば成功となります。 このGetting startedで行うことは全部でviewDidLoadに3行追加と、konashiReadyメソッドの追加。たったこれだけでLEDを点灯させることが出来ます。 Documents Documents を見ます。 ピン、端子の種類について デジタル、アナログ、PWM、I2C、UARTとあります。一つの端子がいろいろ兼用していますので言葉でまとめるのは困難です。表があるとわかりやすいかもしれません。 専門用語 わからない専門用語をいくつか調べました。内部プルアップ、I2C、UARTなど。 サンプルコード PioDrive デジタル入出力のサンプルです。 これが一番わかりやすいので、最初に試すといいと思います。 konashi本体上のスイッチとLEDを使ってデータを送受信します。 本体のスイッチによってLED1を制御。LED2から4はアプリの画面より制御します。 (本体のスイッチとLEDを使う時は本体のジャンパーのショートをする必要があります。) AioSample アナログ入出力のサンプルです。 AIO0(エーアイオーゼロ)に入力、AIO1に出力します。 HardwareSample konashiの電波強度とバッテリーの状況を取得するサンプルです。 電波はiO