(BOOL)resetDatastore
{
[[self managedObjectContext] lock];
[[self managedObjectContext] reset];
NSPersistentStore *store = [[[self persistentStoreCoordinator] persistentStores] lastObject];
BOOL resetOk = NO;
if (store)
{
NSURL *storeUrl = store.URL;
NSError *error;
if ([[self persistentStoreCoordinator] removePersistentStore:store error:&error])
{
[[self persistentStoreCoordinator] release];
__persistentStoreCoordinator = nil;
[[self managedObjectContext] release];
__managedObjectContext = nil;
if (![[NSFileManager defaultManager] removeItemAtPath:storeUrl.path error:&error])
{
NSLog(@"\nresetDatastore. Error removing file of persistent store: %@",
[error localizedDescription]);
resetOk = NO;
}
else
{
//now recreate persistent store
[self persistentStoreCoordinator];
[[self managedObjectContext] unlock];
resetOk = YES;
}
}
else
{
NSLog(@"\nresetDatastore. Error removing persistent store: %@",
[error localizedDescription]);
resetOk = NO;
}
return resetOk;
}
else
{
NSLog(@"\nresetDatastore. Could not find the persistent store");
return resetOk;
}
}
2012年10月29日月曜日
CoreDataのデータを全て削除
2012年10月28日日曜日
半透明のviewを重ねる
半透明のviewの上にviewを以下のように重ねると
子のviewのalphaも親のalphaに引きづられてしまい、子のviewのalphaを1.0に設定してもどちらも半透明になってしまう。
子のviewのalphaも親のalphaに引きづられてしまい、子のviewのalphaを1.0に設定してもどちらも半透明になってしまう。
UIView* view = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 100,100)];
view.alpha = 0.5;
[self.navigationController.view addSubview:view];
UIView* childView = [[UIView alloc] initWithFrame:CGRectMake(25, 25, 50,50)];
childView.backgroundColor = [UIColor whiteColor];
childView.alpha = 1.0;
これを解決するにはviewではなく、background colorのUIColorのalphaを変える必要がある。
UIView* view = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 100,100)];
view.backgroundColor = [[UIColor blackColor] colorWithAlphaComponent:0.5];
[self.navigationController.view addSubview:view];
UIView* childView = [[UIView alloc] initWithFrame:CGRectMake(25, 25, 50,50)];
childView.backgroundColor = [UIColor whiteColor];
2012年10月14日日曜日
iOS6変わったとこなど
相当すぎてますが、NDAも解禁ということで、、
UIViewControllerでメソッドがDeprecateされた
http://developer.apple.com/library/ios/#documentation/uikit/reference/UIViewController_Class/DeprecationAppendix/AppendixADeprecatedAPI.html
modalView系が他のメソッドに完全に置き換わったのと、回転系のメソッドが変わったのと、unload系が呼ばれなくなってます。
Deprecateされたメソッドとその対策
廃止:modalViewController
代替手段:presentedViewController
廃止:automaticallyForwardAppearanceAndRotationMethodsToChildViewControllers
代替手段:shouldAutomaticallyForwardRotationMethods とshouldAutomaticallyForwardAppearanceMethods
廃止:dismissModalViewControllerAnimated:
代替手段:dismissViewControllerAnimated:completion:
廃止:presentModalViewController:animate
代替手段:presentViewController:animated:completion:
廃止:shouldAutorotateToInterfaceOrientation:
代替手段:supportedInterfaceOrientations と preferredInterfaceOrientationForPresentation をオーバーライド
Default-568h@2x.png
UIViewControllerでメソッドがDeprecateされた
http://developer.apple.com/library/ios/#documentation/uikit/reference/UIViewController_Class/DeprecationAppendix/AppendixADeprecatedAPI.html
modalView系が他のメソッドに完全に置き換わったのと、回転系のメソッドが変わったのと、unload系が呼ばれなくなってます。
Deprecateされたメソッドとその対策
廃止:modalViewController
代替手段:presentedViewController
廃止:automaticallyForwardAppearanceAndRotationMethodsToChildViewControllers
代替手段:shouldAutomaticallyForwardRotationMethods とshouldAutomaticallyForwardAppearanceMethods
廃止:dismissModalViewControllerAnimated:
代替手段:dismissViewControllerAnimated:completion:
廃止:presentModalViewController:animate
代替手段:presentViewController:animated:completion:
廃止:shouldAutorotateToInterfaceOrientation:
代替手段:supportedInterfaceOrientations と preferredInterfaceOrientationForPresentation をオーバーライド
廃止:viewDidUnload
廃止:viewWillUnload
廃止:viewWillUnload
viewUnload系はメモリが少なくなった場合でも呼ばれなくなった。
view**Unloadについてはこちらによく書かれています。
view**Unloadについてはこちらによく書かれています。
回転についてはこちらなど
縦長対応
iPhone5が 640 * 1136 になったのでそれに対応せねばならない。
スプラッシュ画像の対応
以下の名前のファイルを追加すればいい
storyboardの変更
storyboardの画面右下の画面の ○ボタンを押せば画面が縦長になる
armv7sの追加
3rdParty性のライブラリを使ってたりしない限りはあまり関係ないですが、使っている場合はそのライブラリがarmv7s用のバイナリを含んでいない場合は、ビルドするときにarmv7sを消さないとだめです。
UICollectionViewが追加
データの一覧表示するのにこれまではTableViewしかなかったのが、UICollectionViewという別の表現手段が用意されました。使い方はパッと見UITableViewとかなり酷似しているのでそれほど難しくはなさそう。
UIRefreshControlが追加
引っ張って更新するのがフレームワークに導入された
これまではEGOTableViewPullRefreshさんにお世話になってましたが、iOS6からはオワコンになります。
UIRefreshControlはもちろんiOS6でしか動かないので、しばらくはまだオープンソースのほうが使われるでしょう。
NSHashTable, NSMapTable, NSPointerArray, NSPointerFunctions,とか増えた
この理解であっているかはちと怪しいが
NSHashTableはNSSetのweak reference版
NSMapTableはNSDictionaryのweak reference版
NSPointerArrayはNSArrayのweak reference版(ただしARC環境ではサポートしないと書いてある)
2012年9月18日火曜日
Objective-Cのクラスメソッドの差し替え
テストのときにUIAlertViewの表示を消してくれるライブラリで
どうやってUIAlertViewのメソッドをフックしてるのかと調べてみたところ
method_exchangeImplementations()を使って実装されてた。
どうやってUIAlertViewのメソッドをフックしてるのかと調べてみたところ
method_exchangeImplementations()を使って実装されてた。
+ (void)swapInstanceMethodsForClass: (Class) cls selector: (SEL)sel1 andSelector: (SEL)sel2 {Method method1 = class_getInstanceMethod(cls, sel1);Method method2 = class_getInstanceMethod(cls, sel2);method_exchangeImplementations(method1, method2);}method_exchangeImplementations()を使えばこのようにクラスメソッドを差し替えられるのでテストでは便利。
2012年9月16日日曜日
XP祭り2012に参加してきた
XP祭り2012に参加してきました。
去年は参加だけだったので、今回はアウトプットをしようということで
LTで登壇してきました。
去年は参加だけだったので、今回はアウトプットをしようということで
LTで登壇してきました。
Xp祭り2012 lt leanstartup from Yasuharu Yanamura
これはUT Startup gymという半年間でアイデアをローンチまでするというプログラムの一プロジェクトとして僕が体験したことを簡単にお話しました。
実際のところ僕らのサービスは、まだローンチまでには至っていないので「やった」とはいいきれないし、
リーンスタートアップを教科書通りにやったわけではなく、考え方などを参考にしてやった程度なので、いろいろつっこみどころはあるとは思いますが、それでも実際にやってみたことで思ったとおりにはいかないことはたくさんあったので、「ひとつの失敗事例」としては他の人にも価値があるのではないかと考え発表させていただきました。
リーンスタートアップもアジャイルもこれといった答えはなく、あくまで「考え方」や「姿勢」のフレームワークだと僕は思っているので、この発表でお話した、「こうすればよかった」や「こうすべき」という意見は、あくまで「この家計簿プロジェクトに限る話」なので、全てに通じるわけでは全くないと思っています。
ソフトウェア開発と同様にスタートアップにも銀の弾丸はないので、試行錯誤してやっていくしかない。なので「超早く回す」ってことが一番重要だと思いますので、実際リーンスタートアップなことをやる場合はそうしたほうがいいのではないかと思います。
これはUT Startup gymという半年間でアイデアをローンチまでするというプログラムの一プロジェクトとして僕が体験したことを簡単にお話しました。
実際のところ僕らのサービスは、まだローンチまでには至っていないので「やった」とはいいきれないし、
リーンスタートアップを教科書通りにやったわけではなく、考え方などを参考にしてやった程度なので、いろいろつっこみどころはあるとは思いますが、それでも実際にやってみたことで思ったとおりにはいかないことはたくさんあったので、「ひとつの失敗事例」としては他の人にも価値があるのではないかと考え発表させていただきました。
リーンスタートアップもアジャイルもこれといった答えはなく、あくまで「考え方」や「姿勢」のフレームワークだと僕は思っているので、この発表でお話した、「こうすればよかった」や「こうすべき」という意見は、あくまで「この家計簿プロジェクトに限る話」なので、全てに通じるわけでは全くないと思っています。
ソフトウェア開発と同様にスタートアップにも銀の弾丸はないので、試行錯誤してやっていくしかない。なので「超早く回す」ってことが一番重要だと思いますので、実際リーンスタートアップなことをやる場合はそうしたほうがいいのではないかと思います。
2012年9月14日金曜日
iOSでKiwiでテストする【基本編2】
つぎはテストコードの中身の書き方です。
it のBlocksの中にテストコードを書きます。
[テスト対象のオブジェクト should] マッチャー:期待される値];
という書き方が基本です。
マッチャーはequalなどですが、詳細はこちらを参照してください。
https://github.com/allending/Kiwi/wiki/Expectations
注意する点としては、
Objective-Cではプリミティブな型(intなど)はオブジェクトではないので、
theValue()で囲ってやることによってオブジェクトにしないとだめです。
beforeAll(^{ // Occurs once
});
afterAll(^{ // Occurs once });
beforeEach(^{ // Occurs before each enclosed "it" variable = [MyClass instance]; });
afterEach(^{ // Occurs after each enclosed "it" });
・ヘルパーメソッドの書き方
例えばこのような場合青字のところはヘルパーメソッドに置き換えたいといった場合の対応ですが、
it のBlocksの中にテストコードを書きます。
[テスト対象のオブジェクト should] マッチャー:期待される値];
という書き方が基本です。
マッチャーはequalなどですが、詳細はこちらを参照してください。
https://github.com/allending/Kiwi/wiki/Expectations
注意する点としては、
Objective-Cではプリミティブな型(intなど)はオブジェクトではないので、
theValue()で囲ってやることによってオブジェクトにしないとだめです。
SPEC_BEGIN(NSDateSpec)
describe (@"NSDate", ^{
context (@"When October", ^{
describe (@"NSDate#lastDate", ^{
context (@"With year:2012", ^{
it (@"should be 30", ^{
describe (@"NSDate", ^{
context (@"When October", ^{
describe (@"NSDate#lastDate", ^{
context (@"With year:2012", ^{
it (@"should be 30", ^{
// ここにテストコードを書く
NSDate* date = [NSDate dateWithGivenYear:2012 month:10];
[[theValue([date lastDay]) should] equal:theValue(30)];
});
});
});
});
NSDate* date = [NSDate dateWithGivenYear:2012 month:10];
[[theValue([date lastDay]) should] equal:theValue(30)];
});
});
});
});
});
SPEC_END
SPEC_END
・各テストで共通の前処理、後処理の書き方
以下を必要な階層に入れればよいはずです。
afterAll(^{ // Occurs once });
beforeEach(^{ // Occurs before each enclosed "it" variable = [MyClass instance]; });
afterEach(^{ // Occurs after each enclosed "it" });
・ヘルパーメソッドの書き方
例えばこのような場合青字のところはヘルパーメソッドに置き換えたいといった場合の対応ですが、
SPEC_BEGIN(NSDateSpec)
describe (@"NSDate", ^{
context (@"When October", ^{
describe (@"NSDate#lastDate", ^{
context (@"With year:2012", ^{
it (@"should be 30", ^{
describe (@"NSDate", ^{
context (@"When October", ^{
describe (@"NSDate#lastDate", ^{
context (@"With year:2012", ^{
it (@"should be 30", ^{
NSDate* date = [NSDate dateWithGivenYear:2012 month:10];
// 何か処理がいろいろ
// ...
[[theValue([date lastDay]) should] equal:theValue(30)];
});
});
});
// 何か処理がいろいろ
// ...
[[theValue([date lastDay]) should] equal:theValue(30)];
});
});
context (@"With year:1979", ^{
it (@"should be 30", ^{
it (@"should be 30", ^{
NSDate* date = [NSDate dateWithGivenYear:1979 month:10];
// 何か処理がいろいろ
// ...
[[theValue([date lastDay]) should] equal:theValue(30)]; });
});
});// 何か処理がいろいろ
// ...
[[theValue([date lastDay]) should] equal:theValue(30)]; });
});
});
});
SPEC_END
SPEC_END
これはBlocksを定義して、呼び出せばよいです。
SPEC_BEGIN(NSDateSpec)
describe (@"NSDate", ^{
context (@"When October", ^{
describe (@"NSDate#lastDate", ^{
//Helper Method.
NSNumber* (^helpMethodWithCount)(int) = ^NSNumber* (int count) {
// 何か処理がいろいろ
// ...
};
context (@"With year:2012", ^{
it (@"should be 30", ^{
describe (@"NSDate", ^{
context (@"When October", ^{
describe (@"NSDate#lastDate", ^{
//Helper Method.
NSNumber* (^helpMethodWithCount)(int) = ^NSNumber* (int count) {
// 何か処理がいろいろ
// ...
};
context (@"With year:2012", ^{
it (@"should be 30", ^{
NSDate* date = dateWithGivenYear:2012 month:10];
helpMethodWithCount(100);
[[theValue([date lastDay]) should] equal:theValue(30)];
});
});
});
helpMethodWithCount(100);
[[theValue([date lastDay]) should] equal:theValue(30)];
});
});
context (@"With year:1979", ^{
it (@"should be 30", ^{
it (@"should be 30", ^{
NSDate* date = dateWithGivenYear:1979 month:10];
helpMethodWithCount(10);
[[theValue([date lastDay]) should] equal:theValue(30)];
});
});
});helpMethodWithCount(10);
[[theValue([date lastDay]) should] equal:theValue(30)];
});
});
});
});
SPEC_END
^{}で囲まれているところは、そのまんまBlocksなので、その中に値を定義すれば、Blocksから参照できますので、ヘルパーメソッドに限らず定義できます。
SPEC_END
^{}で囲まれているところは、そのまんまBlocksなので、その中に値を定義すれば、Blocksから参照できますので、ヘルパーメソッドに限らず定義できます。
iOSでKiwiでテストする【基本編1】
詳細はこちら。
http://www.kiwi-lib.info/specs.html
RSpecのObjective-C実装といったところで、
やはりRSpecと比べるとかなり機能が少なく最小限のようです。
基本的な書き方は、ほぼRSpecと同じなので、RSpecの本とか読めば参考になりそう。
使い方
テンプレートはこんな感じで、
#import "Kiwi.h"
SPEC_BEGIN(Spec名)
describe {@"テスト対象", ^{
context {@"状態", ^{
describe @"テスト対象メソッド", ^{
context @"与える入力", ^{
it @"期待する出力", ^{
}
}
}
}
ちょっと例が悪かったのでインプットが思いつかなかったのですが、、
http://www.kiwi-lib.info/specs.html
RSpecのObjective-C実装といったところで、
やはりRSpecと比べるとかなり機能が少なく最小限のようです。
基本的な書き方は、ほぼRSpecと同じなので、RSpecの本とか読めば参考になりそう。
使い方
テンプレートはこんな感じで、
#import "Kiwi.h"
SPEC_BEGIN(Spec名)
describe {@"テスト対象", ^{
context {@"状態", ^{
describe @"テスト対象メソッド", ^{
context @"与える入力", ^{
it @"期待する出力", ^{
}
}
}
}
}
SPEC_END
実際に書くと
SPEC_END
実際に書くと
SPEC_BEGIN(NSDateSpec)
describe (@"NSDate", ^{
context (@"When October", ^{
describe (@"NSDate#lastDate", ^{
context (@"With xxx", ^{
it (@"should be 30", ^{
describe (@"NSDate", ^{
context (@"When October", ^{
describe (@"NSDate#lastDate", ^{
context (@"With xxx", ^{
it (@"should be 30", ^{
// ここにテストコードを書く
});
});
});
});
});
});
});
});
});
SPEC_END
SPEC_END
ちょっと例が悪かったのでインプットが思いつかなかったのですが、、
こんな風に書けばよいはずです。
あとはインプットや状態によって以下のようにテストを増やしていけばいいのです。
SPEC_BEGIN(NSDateSpec)
describe (@"NSDate", ^{
context (@"When October", ^{
describe (@"NSDate#lastDate", ^{
context (@"With xxx", ^{
it (@"should be 30", ^{
describe (@"NSDate", ^{
context (@"When October", ^{
describe (@"NSDate#lastDate", ^{
context (@"With xxx", ^{
it (@"should be 30", ^{
// ここにテストコードを書く
});
});
});
});
context (@"With xxxxx", ^{
it (@"should be 31", ^{
// ここにテストコードを書く
});
});
});});
});
describe (@"NSDate#firstDate", ^{
it (@"should be 1", ^{
it (@"should be 1", ^{
// ここにテストコードを書く
});
});
});});
});
context (@"When February", ^{
describe (@"NSDate#lastDate", ^{
context (@"With xxx", ^{
it (@"should be 28", ^{
context (@"With xxx", ^{
it (@"should be 28", ^{
// ここにテストコードを書く
});
});
});
});
});
});
SPEC_END
SPEC_END
なにがよいかというと、テストを実行してみるとわかると思いますが、
出力を見てなんのテストが実行されているのかがわかりやすいのがメリットです。
xUnitでもやろうと思ったらできると思いますが、コピペを繰り返すことになるので、
このように階層構造でわけられるので便利だし、見やすいです。
登録:
投稿 (Atom)
