勝訴 iOS 7へ対応

これまで、iPadローンチ、Retinaディスプレイ対応とiOS デバイスの進化に合わせてリリースしてきた、iPad用アプリ「勝訴」。
iOS 7向けにアップデートを行い、本日よりApp Storeにてダウンロードができるようになりました。また、今回のアップデートにより、64bitプロセッサに対応した、初の「勝訴」となりました。

shouso_ios7

iOS 7と64bitプロセッサ向けの最適化を行ったため、動作にはiOS 7が必要です。iOS 7以前のデバイスをご利用の方は、過去のバージョンを引き続きダウンロード可能です。

以下技術的なお話。

Xcode 3の時代のプロジェクトを引き継いでいたため、最新のアーキテクチャ向けにアップデートできるか心配だったが、以下の修正で対応できた。

・ステータス・バーを非表示にする方法が変更になったため、コードの変更。UIViewControllerの – prefersStatusBarHidden メソッドをオーバーライドして、YESを返すよう変更。

- (BOOL)prefersStatusBarHidden
{    
    return YES
}

・iOS 7用のアイコンを作成。アイコンはAsset Catalogで管理するよう変更。
・32/64bitプロセッサ向けのバイナリを作成。プロジェクト設定の”Architectures”を”Standard Architectures(including 64-bit)”に変更。スクリーンショット 2013-09-26 16.07.05
ただし、64bitプロセッサ向けのバイナリは現時点では必須ではない。将来には必須になる可能性もある。

・プロジェクト設定の”iOS Deployment Target”を”iOS 7″に変更。

本来はiOS 6, iOS 7どちらでも動作するものを目指していたが、64-Bit Transition Guide for Cocoa Touch にもあるように、32/64bit両方に対応したバイナリはDeployment TargetをiOS 7に設定しなければならない。一度ここを見落とし、審査でリジェクトされてしまった。この問題は将来のXcodeのリリースで解消される見込みのようだ。

iOS 6時代のUUID事情

今日リリースされたiOS 6, マップやPassbookが目立った新機能だが、UDID/UUID周りについても重要な変更が行われている。
これらについてまとめておく。

UDIDへのアクセスは基本的にNG.
UDIDへのアクセスはiOS 5から非推奨とされている。
公式リファレンスでは、CFUUIDRefを生成し、アプリ内で保存するなどの方法をこれまでには紹介されていたが、iOS 6ではフレームワーク側でUDIDにかわるID(どれもUUID)を用意している。

+ [NSUUID UUID]
従来のCFUUIDRefのObjective-C版と考えていいだろう。クラス・メソッドの+UUID を呼び出せば、UUIDが新規に生成される。
NSString、バイト列に変換するインスタンス・メソッドも用意されている。
ただし、CFUUIDRefとToll-Free bridgeではない。

UIDevice.identifierForVendor
デバイス固有であるが、ベンダごと(Team IDごと)で異なるUUIDを返す。

ASIdentifierManager.advertisingIdentifier
デバイス固有で、すべてのアプリで共通のUUIDを返す。強力なスーパー・クッキーとして機能する。
広告ネットワークのSDKを開発することを想定されている。
advertisingIdentifierを広告目的で利用する場合、ASIdentifierManager.advertisingTrackingEnabledを参照し、ユーザがトラッキングを許可しているか、確認する必要が有る。ユーザが許可していない場合、このUUIDをトラッキング用途で利用してはならない。
この機能はUIKitには含まれず、利用するにはAdSupport.Frameworksをリンクしなければならない。
なお、advertisingIdentifierをトラッキング目的で提供することは、標準では許可されている。提供を拒否したい場合は、iOSの設定アプリから情報>アドバタイズ>Ad Trackingを制限 でオプト・アウトする必要が有る。

追記

iOS Developer Centerのソースは以下の通り

NSUUID Class Reference

UIDevice Class Reference

Ad Support Framework Reference

追記その2

UIDevice.identifierForVendorとASIdentifierManager.advertisingIdentifierはデバイスの初期化等で再生成され、値が変化する可能性がある。値が変化するタイミングについては、現在調査を進めている。

勝訴 1.0.3(Retina Display対応) リリース

新しい勝訴の登場です。
Retinaディスプレイに対応しました。

新しいiPadの方は「勝ちました! 新しいiPad勝ちました!」といった勢いが文字から伝わってくるが、初代iPadの方は文字にいまひとつ勢いが足りない。もしかすると本当は敗訴なんじゃないかと思えてくるほどだ。

ITmedia ガジェット 「新しいiPad」がどれくらい美しいか、試してみたら一目瞭然だった

新しい勝訴は、App Storeで。

追記:「iOSの教科書」印刷製本プロジェクト開始!しました。ご支援ご協力よろしくお願い申し上げます。

Xcode 4.3インストール後、xcodebuildが動作しない場合の修復方法

コマンドラインでXcodeのプロジェクトをビルドするxcodebuildコマンドが動作しなくなってしまった。具体的には次のようなエラーが表示される。
xcodebuild: error: developer tools not installed;
download from http://developer.apple.com

原因はこれまで/DeveloperにインストールされていたXcodeがXcode 4.3より/Applicationsにインストールされるようになったため。
これまでの/Developerに相当するものは、/Applications/Xcode.appのパッケージに内包されるようになった。

xcode-selectコマンドを使用して、Xcodeのインストール先を指定することでxcodebuildコマンドの修復に成功した。

以下手順

  1. ターミナルを開く。
  2. 以下のコマンドを入力する。
  3. sudo xcode-select -switch /Applications/Xcode.app/Contents/Developer

  4. パスワード入力が求められるので、管理者のパスワードを入力する。

参考文献
xcode-select で Xcode の保存先を変更
http://d.hatena.ne.jp/watanata2000/20111028/1319808003

追記:「iOSの教科書」印刷製本プロジェクト開始!しました。ご支援ご協力よろしくお願い申し上げます。

Xcode 4でプロジェクトの名称変更

Xcode4で○○はどこへ行った?シリーズ 第2弾です。
Xcode 4でプロジェクト名を変更する場合は、Fileインスペクタを使用します。

手順は次のような感じ。

  • プロジェクト・ナビゲータ最上部のプロジェクトを選択する。
  • Fileインスペクタを表示する。
  • IdentityのProject Nameに新しいプロジェクト名を入力する。
  • 名称変更の影響が出る範囲が表示される。変更して問題ない場合は「Rename」をクリックする。
  • 広範囲に影響が出る操作をした際に、スナップショットを自動的に作成するか尋ねられる。作成する場合は「Enable」をクリックする。

Xcode4でフレームワークの追加はどこへ行った?

ついにリリースされたXcode4でプロジェクトへのフレームワーク追加で大幅にはまったのでメモ。

Xcode3で既存のフレームワークを追加するにはこんな感じで

プロジェクト・ウィンドウのコンテキストメニューから追加していました。

が、Xcode4に移行してからこの項目が見あたらない。

いろいろ試したところ、Project Editorから追加したところうまくリンクが出来ました。
ただ、もっと簡単な方法はないものかと模索中です。
手順としては

  • Project Navigatorの最上部にあるプロジェクトファイルをクリックしてProject Editorを開く。
  • Targetsからフレームワークを追加するターゲットを選択する。
  • Build Pheseパネルを開く。
  • Link Binary With Librariesのディスクロージャトライアングル(三角ボタン)をクリックして展開する。
  • +ボタンをクリックしてフレームワークを追加する。

Xcode4で○○はどこへ行った?シリーズはもう少し続きます。

 

AVAudioPlayerでパン

iOS 4.0でAVAudioPlayerにpanのプロパティが追加された。
プロパティに値を設定するだけで、簡単にパンニングができる。
設定できる値は-1.0~1.0。
-1.0で左寄りに、0.0で中央に、1.0で右寄りになる。


//  AVPlayerViewController.m
//  AVPlayer
//
//  Created by nori on 10/12/01.
//  Copyright 2010 __MyCompanyName__. All rights reserved.
//

#import "AVPlayerViewController.h"
#import 
@implementation AVPlayerViewController

@synthesize avPlayer;





- (void)viewDidLoad {
    [super viewDidLoad];
	NSError *error = nil;
	NSString *path = [[NSBundle mainBundle] pathForResource:@"sample" ofType:@"mp3"];
	NSURL *url = [NSURL fileURLWithPath:path];
	self.avPlayer = [[[AVAudioPlayer alloc] initWithContentsOfURL:url error:&error] autorelease];

	UISlider *slider = [[UISlider alloc] initWithFrame:CGRectMake(0, 0, 320, 30)];
	slider.minimumValue = -1.0;
	slider.maximumValue = 1,0;
	slider.value = 0.0;
	slider.continuous = YES;
	[slider addTarget:self action:@selector(sliderDidChange:) forControlEvents:UIControlEventValueChanged];
	[self.view addSubview:slider];
	[slider release];
	
	[self.avPlayer play];
}

- (void)sliderDidChange:(UISlider *)slider{
	self.avPlayer.pan = slider.value;
}








- (void)didReceiveMemoryWarning {
	// Releases the view if it doesn't have a superview.
    [super didReceiveMemoryWarning];
	
	// Release any cached data, images, etc that aren't in use.
}

- (void)viewDidUnload {
	// Release any retained subviews of the main view.
	// e.g. self.myOutlet = nil;
}


- (void)dealloc {
	self.avPlayer = nil;
    [super dealloc];
}

@end