iOSデベロッパーからのiOS7以降への改善希望する点

「iOS 7」で予想される全面刷新–アップルとJ・アイブ氏がMySpaceから学ぶべき教訓 – CNET Japan
WWDCへ約1ヶ月となりました。iOS7関連の記事も増えてきていますね。現状のiOS, Android (その他OS)のモバイルOSを見ていくと、Androidユーザー、開発者からすると、iOSは遅れているという見方があるのは事実です。確かに、iOSを見て、それにないところを追加しようとしてきたAndroidが、多くの機能を持っているのは事実です。例えば

  • バックグラウンド対応
  • アプリケーション間の連携
  • IMEの自由度
  • アプリが前面にないときに、ウィジェットのように表示が出来る

などは、Androidの優位点として挙げられます。しかし、Androidにも弱点(iOSの優位点)が多くあります。例えば、

などです。簡単にまとめると、”Androidは何でも出来て、iOSはそうでもないけど、iOSは出来る事がサクサク出来る”という感じでしょうか。

しかし、2007年のオリジナルiPhoneに載っていたiPhone OS(1)から基本的に変わっていない、SpringBoard(ホーム画面アプリ) などはその典型と言えます。当時はタッチでアイコンを押して簡単にアプリを起動出来る、先進のものでしたが、やはり改善するとよい点がたくさんあると思います。

最初の記事では、

「iOS 7」がいつ登場するかは分からないが、1つ分かっていることがある。iOS 7がこの数年で最も大規模なiOSの刷新になるということだ。もしかすると過去最大の変更となるかもしれない。

と予想されています。iOSの大きな変更を挙げると、

  1. iPhone OS2でAppStoreに対応し、サードパーティーアプリ開発者コミュニティが形成された – 2008年
  2. iOS4 でマルチタスク、限定的なバックグラウンドに対応 – 2010年

になるでしょう。これらと比べると、その他のメジャーアップデートは小さのものと言えます。

  1. iPhone OS3で対応する機能が増えた – 2009年
  2. iOS5 で、Storyboardなどによる開発効率向上 – 2011年
  3. iOS6 で、AutoLayoutなどにより、デバイスサイズの多様化の準備 – 2012年

僕は個人的にはiOS6でメジャーアップデートが行われると思っていたのですが、比較的内部的な方向だったので、iOS7では、もう少し脱旧世代モバイルOSを計ってもらえればと思っています。記事で述べられているような、デザイン的な変更も興味があります(iOSの将来、”Objectified”という映画 | Zero4Racer PRO Developer’s Blog )が、API的な変更を期待しています。

APIとして追加してほしいのは、ぱっと思い浮かぶのは以下のものでしょうか。

  1. Push Notificationからのバックグラウンド動作
  2. これは欲しいですね。アプリを起動しなくても、アプリ内のSQLiteDBやCoreDataを更新する事によって、実際起動したときにデータを素早く起動したり、Push Notification → バックグラウンド動作 → Local Notification という事も可能になります。アプリが常に待機しなくてもよいので、電池の持ちもそこまで悪くないと思います。

  3. アクティブなアイコン、Notification Center
  4. 現状アプリのアイコンをアクティブに変える事が出来ませんが、カレンダーのアイコンだけは、日付によって数字を変えています。これと同じ事を各アプリが出来れば、タスクの内容を表示したり、注意を喚起したり出来ると思います。また、天気アプリや株価アプリのように動的な Notification Center をアプリが対応出来れば、キラーアプリも増えるでしょう。

  5. アプリケーションから、他のアプリケーションの一部の機能をバックグラウンド呼び出す
  6. これは現在でもある程度は可能ですが、別アプリを呼び出すと最前面のアプリが変わってしまいます。そうではなくて、バックグラウンドで別のアプリを呼び出して、その結果を表示するという事が出来れば、データの処理だけを別のアプリに任せる事も可能になります。

  7. サードパーティーIME、サードパーティーブラウザのデフォルト化
  8. iOSのデフォルトブラウザ、デフォルトIMEはよいものですが、しかしやはり機能の制限はあります。それで、MacがそうであるようにIMEなどのAPIアクセスを可能にし、ATOKのようなIMEをインストール可能にすれば、特に日本ではいろいろなアイディアが出て、iOSとしての進歩にもつながると思います。

  9. 汎用的な外部アプリ呼び出し
  10. 例えば、GoodReaderから、PhotoShopを呼び出して、保存をするとGoodReader側に保存出来るような仕組みが、両方のアプリが対応しなくても、それぞれのアプリがAPIに対応すれば対応出来るような変更が必要になると思います。

  11. Siri, Voice Inputのサポート拡大
  12. Siri, Voiceによる入力は、現状ではアクセシビリティの設定や、ユーザーがキーボードから入力をしたときに限られますが、アプリ側で常にvoiceコマンドを受け入れるモードを対応出来たり、siriが受け取ったコマンドをアプリに送る事が出来たりすれば、フィジカルコンピューティングデバイスとしてのiOSの機能が増えていくと思います。

  13. 下位互換サポート
  14. これはこれまでのアプリがある程度でも動くという事ですが、これまでのiOSもうまくやってきているので問題無いと思います。

まだ何かあった気がしたけど、とりあえずこんなところと思います。ようはiPhoneが最初に発売されたときに、シングルコア400MHz、メモリ128MBくらいでのスタートだったと思いますが、今では、デュアルコア1GHz、メモリ1GBと、ちょっと前のデスクトップくらいのスペックになっている訳です。以前は、モバイルのために色々制限をする事に多くのメリットがあったのですが、モバイルデバイスの使用が多様化したため、電池を消費してもバックグラウンドで使用したいとか、画面を更新したいとかのニーズが増えています。デベロッパーがユーザーのニーズに応えて、工夫してユーザーがびっくりするようなアプリを作る事が出来る環境をiOSが整えてくれるのが、開発者としての一番の願いですね。そうすれば、ユーザーがiOS、またそのなかでのお気に入りアプリを使い、そしてそれを皆に勧めるはずなので、iOS全体の活性化になると思います。

それを見るためにWWDCに行きたかったのですが、今回は色々な状況を見てあきらめました。ただ、チケット争奪戦を見てみたくて、チケット開始のときにログインして、結局チケット買わなかったのですが、どうもチケット確保されていたみたいです。決済しなかったら自動キャンセルになるとの事なので、同じような状況でキャンセル待ちが繰り上がってくれればいいなと願う次第です。。。

CFNetworkを使用したFTP接続のiOS6でのエラーに関して

ちょっと面倒なエラーが出たので備忘として記録しておきます。プロジェクトで使用している自作のFTPクラスでは、CFNetworkで作成したFTPストリームを、NSInputStreamに変換して、FTPの接続を行っています。メインキュー以外から呼ばれる前提で、非同期ではなく、同期的に呼ぶようにしています。

- (void) startGetSynchronous {
self.sema = dispatch_semaphore_create(0);
self.myFTPType = kFTPTypeGet;
CFReadStreamRef ftpStream;

NSInputStream * networkStream;

assert(networkStream == nil); // don't tap receive twice in a row!

ftpStream = CFReadStreamCreateWithFTPURL(NULL, (__bridge CFURLRef) self.ftpURL);
assert(ftpStream != NULL);

networkStream = (__bridge_transfer NSInputStream *) ftpStream;
[networkStream setProperty:(id)kCFBooleanTrue forKey:(id)kCFStreamPropertyFTPUsePassiveMode];

networkStream.delegate = self;
dispatch_async(dispatch_get_main_queue(), ^{
[networkStream scheduleInRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];
[networkStream open];
});

// Have to release ftpStream to balance out the create. self.networkStream
// has retained this for our persistent use.

self.error = nil;
self.dataReceived = [NSMutableData dataWithLength:0];

dispatch_semaphore_wait(self.sema, DISPATCH_TIME_FOREVER);
#if OS_OBJECT_USE_OBJC!=1
dispatch_release(self.sema);
#endif
}

このサンプルは、Appleのsampleに基づいて作っていました。SimpleFTPSample: Document Revision History SimpleFTPSampleでも、依然はこのように、InputStream自体は、retainせずに、RunLoopに追加する事によってオブジェクトが生存する形となっていました。
これで、iOS5でも問題無く動いていました。ただiOS6で基本的に動くのですが、ときどきエラーが起きてFTPが接続出来なくなったりしていました。エラーログを見ると、

Error: request (0x______) other than the current request(0x0) signalled it was complete on connection 0x_______

のようなエラーが出ていました。このメッセージで検索してみると、別のFTPマネージャーでも同じようなエラーが出ている模様。
Error: request (0x989dd00) other than the current request(0x0) signalled it was complete on connection 0x9b8c6e0 · Issue #5 · nkreipke/FTPManager

ここでは、ARC環境においてのメモリ管理が関係しているのではないか、そしてオブジェクトをstrongプロパティにすればよいのではないかという議論が行われていたので、僕の個人のクラスも、NSStreamオブジェクトをクラスのプロパティに変更して見たところ、エラーが発生しないようになっていました。

self.networkStreamInput = CFBridgingRelease(ftpStream);
[self.networkStreamInput setProperty:(id)kCFBooleanTrue forKey:(id)kCFStreamPropertyFTPUsePassiveMode];

self.networkStreamInput.delegate = self;
dispatch_async(dispatch_get_main_queue(), ^{
[self.networkStreamInput scheduleInRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];
[self.networkStreamInput open];
});

SimpleFTPSample自体も、2013/4/12に修正されています。その修正履歴には、SimpleFTPSample: Document Revision History

2013-04-12 Fixed a bug that caused an incompatibility with iOS 6 (r. 13171568), along with other minor changes including (r. 12478239).

となっていて、iOS 6との互換性問題のバグによって修正されたとありますね。最初からクラスのプロパティか、strongのインスタンス変数にしておけばよかったと思いましたが、サンプル通りに作っていたので、サンプルと同じ問題にぶつかっていました。ただ、CFNetworkによるFTPの動作がiOS5以前とiOS6で変更されたというのは事実のようですので、もし使っている方はご注意を。

ちなみに、参考にしたページには僕からもgitHubのissuesページに問題が解決した事を伝え、こちらのクラスもiOS6対応版に修正されたようです。まさに問題を共有して改善していくソーシャルコーディングですね。
Error: request (0x989dd00) other than the current request(0x0) signalled it was complete on connection 0x9b8c6e0 · Issue #5 · nkreipke/FTPManager

URL の分かっているALAssetをキューの流れを崩さずに取得する方法

iOS4でiOS SDKにも追加されたBlocksは、いまでは多くのiOS標準ライブラリで使われています。バックグラウンドで作業を行わせて、作業が終わったときのコールバックや結果を取得する事が出来ます。確かに、スムーズなUIを実現するのに便利なのですが、ときどき、プログラムの流れを崩したくないので、順序立てて動作してほしいと思うときがありますね。例えば、ALAssetで画像を取得するときも、画像を順番にアップロードしたいなどの要望があります。そのときにALAssetをsyncronizeに取得するメソッドを書きました。
“URL の分かっているALAssetをキューの流れを崩さずに取得する方法” の続きを読む

「iPhoneアプリ開発エキスパートガイド iOS 6対応」詳細目次の紹介

iPhoneアプリ開発エキスパートガイド iOS 6対応
インプレスダイレクトのウェブサイトを見てみたら、詳細の目次が上がっていたので、ご紹介します。
impress Direct:iPhoneアプリ開発エキスパートガイド iOS 6対応

“「iPhoneアプリ開発エキスパートガイド iOS 6対応」詳細目次の紹介” の続きを読む

「iPhoneアプリ開発エキスパートガイド iOS 6対応」を執筆しました

追記 2013/3/21:詳細の目次情報を別エントリに追加しました。「iPhoneアプリ開発エキスパートガイド iOS 6対応」詳細目次の紹介 | Zero4Racer PRO Developer’s Blog

iPhoneアプリ開発エキスパートガイド iOS 6対応

長い執筆期間が終わってもう少しで発売になります。わたしを含むiOS5プログラミングブックの執筆陣による、iOS6の最新機能を含む活用方法が書かれた書籍です。

Amazonからの内容紹介と目次はこちらです。

“「iPhoneアプリ開発エキスパートガイド iOS 6対応」を執筆しました” の続きを読む

自宅オフィス作り進捗ーThunderbolt”代替”ディスプレイを4万で買いました

自宅オフィス
自宅オフィス

1月に引っ越して実家のある福岡に帰ってきました。以前も自宅オフィスの記事を書いて好評だったのでまたまたシェアしたいと思います。
自宅作業が多い方にオススメ!IKEA で作った快適自宅オフィス | Zero4Racer PRO Developer’s Blog
“自宅オフィス作り進捗ーThunderbolt”代替”ディスプレイを4万で買いました” の続きを読む

iOS6 でのタイムアウト挙動の改善とAFNetworkingでのタイムアウトの設定方法

備忘として記録しときます。iOSでNSURLRequestを使用して、PostでPostBodyを設定したときに、timeoutIntervalを設定たらタイムアウトが240秒固定になってしまう以下に設定出来ない仕様(バグ)があったのですが、iOS6では改善されているようです。ちなみに標準のタイムアウトは60秒です。
iphone – NSURLConnection timeout? – Stack Overflow
それをふまえて、AFNetworking でのタイムアウトの設定方法です。
“iOS6 でのタイムアウト挙動の改善とAFNetworkingでのタイムアウトの設定方法” の続きを読む

グランドキャニオンHDR壁紙を公開

Twitter の プロファイル写真を変えるときに、グランドキャニオンでとったHDR写真をプロファイル写真のバックグラウンドにしてみました。

iPhone 4Sの壁紙にしたらこんな感じ
iPhone 4Sの壁紙にしたらこんな感じ

グランドキャニオンの景色がとても好きで、いつも行くたび”おお!すげー”となるのですが、写真で見るとそれなりにしか見えず、感動が薄れてしまいます。それでHDR写真加工をして、すごい感じを出してみました。HDR写真については、以下のWikipediaで説明されています。

ハイダイナミックレンジ合成(ハイダイナミックレンジごうせい、英語:high dynamic range imaging、略称:HDRI、HDR)、とは、通常の写真技法に比べてより幅広いダイナミックレンジを表現するための写真技法の一種。
例えば風景のダイナミックレンジ(最も明るい部分と最も暗い部分の明暗の比)は広く、しばしばコントラスト比100000:1を軽く超える。フィルムやCMOSイメージセンサなどの一般的な記録手段のダイナミックレンジは狭く、せいぜい11段、すなわちコントラスト比2000:1程度しかない。[1]。 また、一般的なモニタのコントラスト比も1000:1程度である。[2]そのため、現実の風景などの持つ広いダイナミックレンジをそのまま記録、表示することができない場合がある。
そこで、非常に大きなコントラストの元画像(現実)を、1000:1程度のコントラストになるように、コントラストを落とした画像に変換するのが、ハイダイナミックレンジ合成である。それは、新画像のコントラストを圧縮することで、元画像(現実)の広いコントラストを収納することを意味する。それができない場合には、元画像(現実)における明暗の一部が収納されずに、つぶれてしまうことになる。
つまり、ハイダイナミックレンジ合成は、幅広いダイナミックレンジを記録、表示するために開発された画像合成手法である。


“グランドキャニオンHDR壁紙を公開” の続きを読む

4歳のこどもが遊んでるiPadアプリ、子ども”と”遊べるiPadアプリ

うちの子(最近4歳になった)も、他の子どもたちと違わず、iPadを渡したらいつまでも遊んでいます。あまり長く遊びすぎると目が悪くなったりするのが心配なので、大体一日1回から2回、30分から1時間にとどめるようにしています。英語ネイティブなので、ちょっと日本の子たちと遊ぶアプリが違うかもしれません。

“4歳のこどもが遊んでるiPadアプリ、子ども”と”遊べるiPadアプリ” の続きを読む

Objective-C の instancetype キーワードが面白い + typeof(self)の考察

Appleのサンプルコード、iAdSuite を見ていたら見慣れない表現が出てきたので、調べて見ました。

@implementation TextViewController

- (instancetype)init
{
self = [super initWithNibName:@"TextViewController" bundle:nil];
if (self) {
//...
}
return self;
}

こんな感じ、”- (instancetype)init”と書いているのを見て、なんで”-(id) init”じゃないのかなと思いました。
“Objective-C の instancetype キーワードが面白い + typeof(self)の考察” の続きを読む