2016年3月17日木曜日

[iOS開発][CoreData]The fetched object at index ….. has an out of order section name

The fetched object at index …..  has an out of order section name

今日はCoreDataをいじっていたら表題のエラーに出くわしたので、それを投稿したい。

対処としては簡単なのだが、なんかイマイチな仕様だなぁ・・・とモヤッたので書きたいのである。

さっそく、どんなコードを書いていたのかというと。

  NSFetchRequest *request = [[NSFetchRequest alloc] init];
        NSEntityDescription *entity = [NSEntityDescription entityForName:@“clothes”
                                                  inManagedObjectContext:context];
        [request setEntity:entity];
        
        
  
        NSSortDescriptor *sd2 = [[NSSortDescriptor alloc] initWithKey:@“color” ascending:YES];
        NSSortDescriptor *sd3 = [[NSSortDescriptor alloc] initWithKey:@“size” ascending:YES];
        
        request.sortDescriptors = [NSArray arrayWithObjects:sd2,sd3, nil];
        
        NSDictionary *entityProperties = [entity propertiesByName];
        
        NSMutableArray *properties = [NSMutableArray arrayWithObject:
[entityProperties objectForKey:@“sex”]];
        [properties addObject:[entityProperties objectForKey:@"color"]];
        [properties addObject:[entityProperties objectForKey:@"size"]];
        [request setPropertiesToFetch:properties];
        
        [request setResultType:NSDictionaryResultType];
        
        NSFetchedResultsController *controller =
        [[NSFetchedResultsController alloc] initWithFetchRequest:request managedObjectContext:context sectionNameKeyPath:@“sex” cacheName:nil]; 
        
        controller.delegate = self;
        [controller performFetch:nil];


こんな感じなのである。performFetchをしたところで、エラーを出力してフェッチできないという状態。

まあ、メッセージにある通り、セクション指定をしてあるにもかかわらず、そのデータで区切れないデータだったのでエラーとしたようである。


・・・略・・・・

        NSSortDescriptor *sd2 = [[NSSortDescriptor allocinitWithKey:@“color” ascending:YES];
        NSSortDescriptor *sd3 = [[NSSortDescriptor allocinitWithKey:@“size” ascending:YES];
        
        request.sortDescriptors = [NSArray arrayWithObjects:sd2,sd3, nil];

・・・中略・・・・

        [[NSFetchedResultsController allocinitWithFetchRequest:request managedObjectContext:context sectionNameKeyPath:@“sex” cacheName:nil]; 



なので、ソート条件に追加してやる


・・・略・・・・
        NSSortDescriptor *sd1 = [[NSSortDescriptor allocinitWithKey:@“sex ascending:YES];
        NSSortDescriptor *sd2 = [[NSSortDescriptor allocinitWithKey:@“color” ascending:YES];
        NSSortDescriptor *sd3 = [[NSSortDescriptor allocinitWithKey:@“size” ascending:YES];
        
        request.sortDescriptors = [NSArray arrayWithObjects:sd1,sd2,sd3, nil];

・・・中略・・・・

        [[NSFetchedResultsController allocinitWithFetchRequest:request managedObjectContext:context sectionNameKeyPath:@“sex” cacheName:nil]; 



うまく動作!
何がモヤっとしたかというと、セクション区切りに使う場合には、その項目はプログラムの挙動的にはソートされていないと実現できないだろうという確信があったんですが、あえて、それはソート条件に入れてなかったんですよ。

だって、セクションに指定してますよ、ってメソッドに入ってますからね。

        [[NSFetchedResultsController allocinitWithFetchRequest:request managedObjectContext:context sectionNameKeyPath:@“sex” cacheName:nil]; 


で、コンパイラエラーになりもしなけりゃ、実行時エラーにもならない。
お!動くじゃん。賢いね!と思ってたら、突然動かない。で、調べたら表題のエラー。

このエラー、データがたまたまセクション区切りできるように綺麗にデータベースに入ってると発生しないんですよ。ひどい仕様だと思いません?


ということでいつまでもボヤいていても仕方ないので、今日はこの辺で。

ではでは。










2016年3月7日月曜日

[iOS開発] _handleNonLaunchSpecificActions in iOS9

よくわからんエラーが出た

デバッガーからのメッセージはこんな感じ。

 -[UIApplication_handleNonLaunchSpecificActions:
      forScene:
      withTransitionContext:
      completion:] unhandled action -> 
      <FBSSceneSnapshotAction: 0x150b2aef0> 
       {
            handler          = remote;
            info = <BSSettings: 0x15333f650> 
            {
                (1) = 5;
            };
        }

:iOS 9.2.1 実機、 xcode7.2 で発生


stack overflow によると、iOS9 にて発生する事象(バグ?)のようである。

ようである、というのは このメッセージ、 _handleNon... と アンダースコアで始まるからだ。
このルール、apple の公式ドキュメントによると 内部メソッドという決まりがある。

ということで基本的にプログラムのロジックエラーではないというのが stack overflow のメンツのご意見。
まあ、私も彼らの意見を読んでみて、それが妥当であるように思う。

かならず発生するわけではなく、特定のビルドでもないからだ。
強いて言うと、画面操作を行っている場合に、メッセージログにこれが出る感じ。

ちなみに、iOS9 betaでも発生していたという情報もあるので、この事象はまだ治っていないということになる。


ではでは。


2016年3月2日水曜日

[iOS開発] APPNAME was compiled with optimization - stepping may behave oddly; variables may not be available.

久しぶりにアプリを改造していたら、表題のエラーが発生。


 検索してみるが、いまいち、的を得た内容がない。 完全な解決に至っていないので、まだ調査中ということになりますが、後世?のために何をしたかを記載しときます。


エラーメッセージ 


XXXアプリ was compiled with optimization - stepping may behave oddly; variables may not be available. 

発生する条件:
  1. 任意の場所、つまりどこでもいいからBreakPointを設定して実行すると、メッセージが表示される。 
  2. どんな操作をしても、データに関わらず発生するように見える。
  3. X-codeのスキームは複数設定してあるが、リリース用設定をしているスキーマでデバッグを実行させると発生する。 

条件3が限定的で怪しい。
いくつかスキーマの条件をいじってみると、どうもRun 設定で Releaseになっているとこのメッセージが表示されるようである。 新しいスキームをつくってみても、エラーが出ていないスキームでも、このオプションを設定するとエラーが発生する。

 このままにしておくわけにはいかない。何しろ、アプリをリリースするときは最適化した状態だし、最適化オプション無しなら動くということはたまたま動いているにすぎないからだ。  

 ググってみると、プログラム全体がおかしいという情報がちらほら。 作り直しは避けたいので、様々なバージョンから同じ条件で実行すると、エラーが発生しないバージョンが存在した。そこから頑張って作成すれば、エラーは出ないと思われるが、かなり古い状態なのでそこから作り直すのは避けたい。
悪あがきに、とりあえず x-code のプロジェクトファイルでも差分をとってみようかとチェックすることにした。






X-code付属のFileMergeを使って見る




 すると、 UserInterfaceState.xcuserstateで差分が大量に発生している。UserInterfaceState.xcuserstateとは何だろうか?エラーが発生していないバージョンにそのプロジェクトファイルをコピーしてみる。


・・・ エラーが発生した! これが原因のようだ。


 一説によると workspace や project layout に関する情報を個々のアカウントに紐付けている情報のようである。アカウントを複数使って何かしている場合には何か有用なのかもしれないが、アプリのロジック自体には影響しない。(gitにも登録不要)


 というわけで、どうもプロジェクトファイルが何らかの操作でおかしな状態になっていたようである。古いプロジェクトファイルをコピーして、そのバージョンから追加したファイルなど、再度紐付けてコンパイルする。


 ・・・問題ない。





差分が大量にあった問題のファイル




 ちなみに、このファイルはx-codeをちょっとでも触れば更新が入るようで、大量の差分が発生するのも納得である。この UserInterfaceState.xcuserstate がどうして、こんなエラーを吐くことにつながったのかは不明だ。

だが、現実問題として、このファイル以外に差分はなく、プロジェクトファイルのコピーで対処できてしまったのである。
 
 もやもやした結果だが、このままで開発を続けてみることにする。

どなたか、何かご存知でしたら情報ください。