2012年12月27日木曜日

[iOS]iPhone、iPadの画面サイズ、フレームサイズを取得する


iOSの画面サイズは取得にくい、特に特にステータスバーやツールバーの存在がやっかい。

//現在のビューのサイズ、ツールバーやステータスバーのサイズは引かれる
//iPhone4でステータスバー、ナビゲーションバー、ステータスバーがあるとき、heightは480-20-44-44になる
self.view.frame.size.width
self.view.frame.size.height

//現在の端末のスクリーンサイズ
//iPhone4ではheight480、iPhone5ではheight568になる
[[UIScreen mainScreen] bounds].size.width
[[UIScreen mainScreen] bounds].size.height

//現在の端末のスクリーンサイズでステータスバー領域を含む
//iPhone4ではheight460、iPhone5ではheight548になる
[[UIScreen mainScreen] mainScreen].size.width
[[UIScreen mainScreen] mainScreen].size.height

問題になるのはナビゲーションバーを非表示のビューからpushしたビューで
viewDidLoadで
ナビゲーションバーを消しても
self.navigationController.navigationBarHidden = NO;
self.view.frame.size.heightは460になるということ

正確なサイズを知りたい時は
viewDidLoadでナビゲーションバーのON/OFFをして
viewDidAppearで座標を取得すること

2012年12月25日火曜日

[iOS]ld: duplicate symbol

XCode4.5.2のビルドで以下のエラーが発生した。


duplicate symbol _OBJC_CLASS_$_PhotoViewController in:
    /Users/abrain/Library/Developer/Xcode/DerivedData/hogehoge-/Build/Intermediates/hogehoge.build/Debug-iphonesimulator/hogehoge.build/Objects-normal/i386/hogehogeAppDelegate.o
    /Users/abrain/Library/Developer/Xcode/DerivedData/hogehoge/Build/Intermediates/hogehoge.build/Debug-iphonesimulator/hogehoge.build/Objects-normal/i386/RootViewController.o
ld: 88 duplicate symbols for architecture i386
clang: error: linker command failed with exit code 1 (use -v to see invocation)

実際はもっと長いエラーだった。
duplicate symbol(PhotoViewControllerのシンボルが重複しています)
つまりクラス定義を2重にやってるらしいんだが、PhotoViewControllerに悪い場所はない。

いろいろやったところPhotoViewControllerを呼び出しているところが、
#import "PhotoViewController.m"
となっていた、
PhotoViewController.mからヘッダーを呼び出してるので2重定義となっている。
#import "PhotoViewController.h"
と修正してビルド完了。

XCodeうんうんじゃなくてC言語共通のエラーね。
コード補完で間違って.mを選択してしまったようだ。


2012年11月13日火曜日

[iOS]Apple公式iOS日本語ドキュメントの場所

毎度毎度リンクを忘れるのでこちらにリンクしておく
(公式ページからのたどっていくのは難しい)

https://developer.apple.com/jp/devcenter/ios/library/japanese.html

日本語版は最新になっていないことがあるので注意

2012年11月12日月曜日

[AndroidSDK]プリファレンスの使用

データの保存方式の1つ
いつでもどこから呼び出せる上に動作も早いので便利openFileより扱いが楽かも

// プリファレンスに値を保存
// MODE_PRIVATEを変更することで他アプリからも取得できる
SharedPreferences pref = getSharedPreferences("pref", MODE_PRIVATE);
Editor editor = pref.edit();
editor.putInt("fooNumber",fooNumber);
editor.commit();

// プリファレンスから値を取得
SharedPreferences pref = getSharedPreferences("pref", MODE_PRIVATE);
// pref.getIntの2番目の引数は取得できない時のデフォルト値
int fooNumber  = pref.getInt("fooNumber", 0);

保存場所は
/data/data/"packagename"/shared_prefs/"
に保存されるそうだ。

必須データは暗号化した方が良いかも

2012年11月6日火曜日

[AndroidSDK]OverScroll時の表示を消す

ListViewでスクロール限界まで持っていった時にでるあれ
OverScrollと言うのかな?
これの青い部分
(ちょっと見くいけど青い部分が文字にかかってる)


android:overScrollMode="never"
で削除するとことができる

他にも
android:overScrollHeader="@drawable/header"
android:overScrollFooter="@drawable/footer"
でOverScroll時の表示が変わるらしいが
反映されてないようだ、原因不明

2012年11月5日月曜日

[AndroidSDK]アプリ起動中にスリープにしない

スライドショーができるアプリなどでスリープになられると困る時に使用する

//端末のスリープモードをOFFにする
getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);    

//端末のスリープモードをONにする
getWindow().clearFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);

リファレンスによるとFLAG_KEEP_SCREEN_ONは
「ディスプレイの電源が入っており、明るい状態」
らしいんだが、Android端末によって明るくならなかったりする

2012年9月12日水曜日

[AndroidSDK]WidgetでonUpdateやonReceiveがこない

見事にハマった。

原因はWidgetを再配置していないから。

Widget開発中デバイスにWidgetをインストール後は更新した内容が反映されてないことがある
(されていることもある)
面倒臭がらずショートカット>ウィジェットの作成を行おう

はじめにやった時に配置してあるウィジェットがリアリタイムで更新されているからラッキーと思ったんだけどね
こんな事で半日過ごしてしまった
あとアンインストールもやっておくといいかも

2012年9月5日水曜日

[AndroidSDK]アラーム設定を呼び出す

Intent intent = new Intent();
intent.setClassName("com.android.deskclock", "com.android.deskclock.AlarmClock");
startActivity(intent);

com.android.deskclock
com.android.deskclock.AlarmClock
の部分はデバイスによって異なるようです。

2012年8月23日木曜日

[AndroidSDK]文字列からdrawableなどのリソースを取得する

R.drawable.myImageなど毎回ハードコーディングしない方法

ImageView imageView = (ImageView) row.findViewById(R.id.imageView);

String imageName = "imageSampleName.jpg";
//ファイル名と拡張子を分割
String[] stArrayData = imageName.split("\\.");
//リソースの取得
int id = getResources().getIdentifier(stArrayData[0], "drawable", getPackageName());
if (id != 0) {
    //画像をセットする
    imageView.setImageResource(id);
}

2012年8月21日火曜日

[AndroidSDK]at dalvik.system.NativeStart.main(Native Method)

Cursor cursor = null;
String query = "SELECT  text1, text2, text3, FROM entity WHERE number_02 = 1 ORDER BY number_01 ASC";
cursor = db.rawQuery(query, null);
SQLiteのqueryを発行後に以下のエラーが発生した

08-21 10:32:42.262: W/dalvikvm(15823): threadid=1: thread exiting with uncaught exception (group=0x40015590)
08-21 10:32:42.272: I/dalvikvm(15823): DALVIK THREADS:
08-21 10:32:42.272: I/dalvikvm(15823): (mutexes: tll=0 tsl=0 tscl=0 ghl=0 hwl=0 hwll=0)
08-21 10:32:42.272: I/dalvikvm(15823): "main" prio=5 tid=1 RUNNABLE
08-21 10:32:42.272: I/dalvikvm(15823):   | group="main" sCount=0 dsCount=0 obj=0x4001f278 self=0xcf88
08-21 10:32:42.272: I/dalvikvm(15823):   | sysTid=15823 nice=0 sched=0/0 cgrp=default handle=-1345006432
08-21 10:32:42.272: I/dalvikvm(15823):   at dalvik.system.NativeStart.main(Native Method)
08-21 10:32:42.272: I/dalvikvm(15823): "Binder Thread #2" prio=5 tid=8 NATIVE
08-21 10:32:42.272: I/dalvikvm(15823):   | group="main" sCount=0 dsCount=0 obj=0x40517358 self=0x206658
08-21 10:32:42.272: I/dalvikvm(15823):   | sysTid=15830 nice=0 sched=0/0 cgrp=default handle=2127016
08-21 10:32:42.272: I/dalvikvm(15823):   at dalvik.system.NativeStart.run(Native Method)
08-21 10:32:42.272: I/dalvikvm(15823): "Binder Thread #1" prio=5 tid=7 NATIVE
08-21 10:32:42.272: I/dalvikvm(15823):   | group="main" sCount=0 dsCount=0 obj=0x40511ba0 self=0x207108
08-21 10:32:42.272: I/dalvikvm(15823):   | sysTid=15829 nice=0 sched=0/0 cgrp=default handle=1196992
08-21 10:32:42.272: I/dalvikvm(15823):   at dalvik.system.NativeStart.run(Native Method)
08-21 10:32:42.272: I/dalvikvm(15823): "Compiler" daemon prio=5 tid=6 VMWAIT
08-21 10:32:42.272: I/dalvikvm(15823):   | group="system" sCount=0 dsCount=0 obj=0x4050dc80 self=0x1241a0
08-21 10:32:42.272: I/dalvikvm(15823):   | sysTid=15828 nice=0 sched=0/0 cgrp=default handle=1196384
08-21 10:32:42.272: I/dalvikvm(15823):   at dalvik.system.NativeStart.run(Native Method)
08-21 10:32:42.272: I/dalvikvm(15823): "JDWP" daemon prio=5 tid=5 VMWAIT
08-21 10:32:42.272: I/dalvikvm(15823):   | group="system" sCount=0 dsCount=0 obj=0x4050dbd0 self=0x1246a8
08-21 10:32:42.272: I/dalvikvm(15823):   | sysTid=15827 nice=0 sched=0/0 cgrp=default handle=571032
08-21 10:32:42.272: I/dalvikvm(15823):   at dalvik.system.NativeStart.run(Native Method)
08-21 10:32:42.272: I/dalvikvm(15823): "Signal Catcher" daemon prio=5 tid=4 VMWAIT
08-21 10:32:42.272: I/dalvikvm(15823):   | group="system" sCount=0 dsCount=0 obj=0x4050db10 self=0x1244b8
08-21 10:32:42.272: I/dalvikvm(15823):   | sysTid=15826 nice=0 sched=0/0 cgrp=default handle=1512472
08-21 10:32:42.272: I/dalvikvm(15823):   at dalvik.system.NativeStart.run(Native Method)
08-21 10:32:42.272: I/dalvikvm(15823): "GC" daemon prio=5 tid=3 VMWAIT
08-21 10:32:42.272: I/dalvikvm(15823):   | group="system" sCount=0 dsCount=0 obj=0x4050da68 self=0x205920
08-21 10:32:42.272: I/dalvikvm(15823):   | sysTid=15825 nice=0 sched=0/0 cgrp=default handle=1512408
08-21 10:32:42.272: I/dalvikvm(15823):   at dalvik.system.NativeStart.run(Native Method)
08-21 10:32:42.272: I/dalvikvm(15823): "HeapWorker" daemon prio=5 tid=2 VMWAIT
08-21 10:32:42.272: I/dalvikvm(15823):   | group="system" sCount=0 dsCount=0 obj=0x4050d9b0 self=0x8b4d8
08-21 10:32:42.272: I/dalvikvm(15823):   | sysTid=15824 nice=0 sched=0/0 cgrp=default handle=1512344
08-21 10:32:42.272: I/dalvikvm(15823):   at dalvik.system.NativeStart.run(Native Method)

理由は String query = "SELECT text1, text2, text3(","が不必要) FROM entity WHERE number_02 = 1 ORDER BY number_01 ASC";
なんつうエラーを出すんだよ

2012年8月17日金曜日

[AndroidSDK]android.database.sqlite.SQLiteDiskIOException: disk I/O error


SQLiteOpenHelper.getReadableDatabaseで以下のエラーが発生した。


Caused by: android.database.sqlite.SQLiteDiskIOException: disk I/O error

at android.database.sqlite.SQLiteDatabase.dbopen(Native Method)
at android.database.sqlite.SQLiteDatabase.<init>(SQLiteDatabase.java:1849)
at android.database.sqlite.SQLiteDatabase.openDatabase(SQLiteDatabase.java:820)
at android.database.sqlite.SQLiteOpenHelper.getReadableDatabase(SQLiteOpenHelper.java:197)
at com.myapp.util.PackageDBHelper.createDataBase(PackageDBHelper.java:51)


解決方法
DBのの保存先を変更する

data/data/YOUR_PACKAGE/databases/”;

Environment.getDataDirectory() + “/data/YOUR_PACKAGE/databases/”;

参考URL

2012年8月15日水曜日

[AndroidSDK]"Conversion to Dalvik format failed with error 1" の解決策


原因不明、いろいろ試してみた

・プロジェクトのクリーン
Eclipseの-clean
プロジェクトのAndroidツール⇒「プロジェクト・プロパティを修正」
Build Pathの順序変更、エクスポートのチェック見直し

・Androidのバージョン変更
プロジェクトのプロパティからアンドロイドのバージョンを変更、クリーン、ビルド、元のバージョンに戻す

・binとgen削除
各プロジェクトリのbinとgenディレクトリ内のファイルをすべて削除
むしろbin genごと削除

・.classpathを削除

・proguardの更新

・インポートのやり直し
なぜかこれで直った

2012年7月10日火曜日

[iOS]簡単なタイマー処理

- (void)startTimer
{
    //タイマーの開始
    ctimer = [NSTimer scheduledTimerWithTimeInterval:0.25
                                              target:self
                                            selector:@selector(timerDidEnd)
                                            userInfo:@"userInfoString";
                                             repeats:YES];
}

- (void)timerDidEnd
{
    //タイマーが1回終了した

    //userInfoで値を取得できる
    NSString *string = [timerDidEnd userInfo];
}

- (void)stopTimer
{
    //タイマーの停止
    if (ctimer) {
        if ([ctimer isValid]) {
            [ctimer invalidate];
            //停止時にはnilにすること
            ctimer = nil;
        }
        
    }
}

- (void)dealloc
{
    [super dealloc];
    //タイマーの停止
    if (ctimer) {
        if ([ctimer isValid]) {
            [ctimer invalidate];
            //停止時にはnilにすること
            ctimer = nil;
        }
    }
}

2012年7月9日月曜日

[Xcode]XCode4 例外発生時のブレークポイントの貼り方


XCode3では、強制終了や例外が発生した時に、ソースコード上の例外が発生したポイントが見えたが
XCode4のデフォルト設定では例外発生時にmain.mにProgram received singlal:"SIGBRT"で止まるようになってしまった。

XCode上で例外発生時にブレークさせる方法は

XCode4の左上のタブバーでブレークポイントのマークをタップ
右下の"+"をクリックして"Add Exception BreakPoint"でブレークポイントが作成できる


2012年5月17日木曜日

2012年4月23日月曜日

[iOS]directory not found for option

directory not found for optionのエラーが発生した時

プロジェクト>ターゲット>Build Settingを開く
検索メニューdirectory not found for optionあとの表示されるライブラリを選択
ライブラリパスを削除

参考
‘ld: warning: directory not found for option’ while building iPhone app with Xcode 4

2012年4月18日水曜日

[iOS]UISearchBarキーボードボタンの"search"を"done"にする


stackoverflow.comから引用

//cSearchBarの持っているサブビューを取得
for (UIView *searchBarSubview in [cSearchBar subviews]) {
  //protocolがUITextInputTraits=キー入力関係のオブジェクトを判定
  if ([searchBarSubview conformsToProtocol:@protocol(UITextInputTraits)]) {
    @try {
      //UITextInputTraitsのオブジェクト、ここでは「検索」ボタンになるので
      //UIReturnKeyDone=完了に変更
      [(UITextField *)searchBarSubview setReturnKeyType:UIReturnKeyDone];
    }
    @catch (NSException * e) {       
      //例外処理
    }
  }
}

ただコレだとUISearchBarのキーボードに「検索」ボタン以外がある時も「完了」ボタンに変わってしまうはず。
他言語キーボードでの不具合とかありそうだな。

2012年4月17日火曜日

[AndroidSDK]Unable to resolve superclass of MyClass

Android ADT17(2012/03/21Update)にアップデート後に以下のエラーが発生した。

Unable to resolve superclass of MyClass

MyClassはxxx.jarの中に入っているんだけど見えないというエラー。

解決方法は
プロジェクト直下(gen、binと同じフォルダ)にlibsフォルダを作成
libsフォルダにxxx.jarを配置後に再度パスを貼り直し

ADT17からlibsフォルダは必須のようだ

2012年4月13日金曜日

[iOS]executeFetchRequestを使用した検索方法

    NSString *foo = @"hoge";
    NSString *bar = @"huga";
    
    //Coredate検索
    NSFetchRequest *request = [[NSFetchRequestalloc] init];
    //検索先entityを設定
    NSEntityDescription *entity = [NSEntityDescriptionentityForName:@"Card"
                                              inManagedObjectContext:managedObjectContext_];
    [request setEntity: entity];
    //検索条件を設定
    NSString *predicateCommand = [NSStringstringWithFormat:@"foo MATCHES '%@' and bar CONTAINS '%@' and isHoge == YES", foo, bar];
    NSPredicate *predicate = [NSPredicatepredicateWithFormat:predicateCommand];
    [request setPredicate: predicate];
    //fetch開始
    NSArray *fetchedObjects = [[selfmanagedObjectContext] executeFetchRequest:request
                                                                         error:nil];
    
    if ([fetchedObjects count]) {
        NSManagedObject *managedObject;
        for (managedObject in fetchedObjects) {
            //managedObjectを削除
            NSString *data = [managedObject valueForKey:@"data"];
        }
        
    } else {
        //No result
    }

2012年4月7日土曜日

[iOS] NSFetchedResultsControllerに検索結果があるか取得する

わざわざコード書いているけどNSFetchedResultsControllerに検索結果取得メソッドぐらいあるはず、、、なので苦肉の策


bool isNoResult = false;
int count = [[self.fetchedResultsController sectionscount];

if (count == 1) {
   id <NSFetchedResultsSectionInfo> sectionInfo = [[self.fetchedResultsController sectionslastObject];
    TRACE("sectionInfo %d", [sectionInfo numberOfObjects])
    if ([sectionInfo numberOfObjects] == 0) {
         //取得が0である
         isNoResult = true;
    }
}

2012年3月9日金曜日

[iOS]日付時刻関係のメソッドメモ

NSCalendar、NSDate、NSDateComponentsをうまく使用すること

無題ノート
//指定した日付でNSDateを作成
NSString *dateString = [[NSStringalloc] initWithFormat:@"2030/01/01 %02d:%02d:00", [cmphour], [cmpminute]];
NSDateFormatter *dateFormatter = [[NSDateFormatteralloc] init];
[dateFormatter setDateFormat:@"yyyy/MM/dd HH:mm:ss"];
NSDate *date = [dateFormatter dateFromString:dateString];
[dateString relese];
[dateFormatter relese];

//現在時刻を取得
NSDate *date = [NSDate date];

//時間を追加する
NSDate *date = [NSDate date];
NSDate *newDate = [date dateByAddingTimeInterval:7*24*60*60];

//翌日に日付を取得
NSDateComponents *cmp = [[NSDateComponentsalloc] init];
[cmp setDay:1];
NSDate *date = [[NSCalendar currentCalendar] dateByAddingComponents:cmp toDate:[NSDate date] options:0];
[cmp release];

2012年2月29日水曜日

[iPhoneSDK]UIViewController Managing the View (ビュー管理)関係の関数

毎度忘れるのでメモをとっておく

– (void)loadView
ビューがロードされる時に呼び出される。

- (void)viewDidLoad
ビューがロードされた後に呼び出される。

- (void)viewWillAppear:(BOOL)animated
ビューが描画される前やアニメーションが始まる前にこの処理が呼ばれる。

- (void)viewWillDisappear:(BOOL)animated
ビューが非表示にされる前や解放される前にこの処理が呼ばれる。


呼びさされた後にsuperで元の呼び出しを行うこと
- (void)loadView {
    [super loadView];
}

2012年2月27日月曜日

[iOS]XCode4が重い

「iOS5でバグが出て修正が必要なのにXcode4が重くてイライラしする現象」を修正してみた。

どうやらmacのキャッシュを消せば軽くなるらしい。
キャッシュを消したところ、
旧mac miniで常時30%のcpu使用率が一桁まで減った。
オートコンプリート機能でクラッシュするのも直った。

ただしキャッシュを消すと何が起こるか分からないのでくれぐれも自己責任で

(ユーザーネーム)>ライブラリ> Caches
Macintosh HD>ライブラリ>Caches

のキャッシュを消してmac再起動

危険だけど、どのファイルがxcodeのキャッシュなのか分からないのでとりあえず全部消してみたが
mac miniをハンマーで叩き割るよりはスマートだと思う

追記
キャッシュを消したところテキストツールなどで文字化けするようになったが、再起動でなおった。
さすがにすべてのキャッシュ削除は乱暴すぎるかも。

project.xcworkspaceを削除するという方法もあった。
Yomo

2012年2月11日土曜日

[iOS]writeToFileでfalseが返る

NSDictionaryでwriteToFileでfalseが返る

NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *path = [paths objectAtIndex:0];
path = [path stringByAppendingPathComponent:@"config.plist"];
NSMutableDictionary *configDict = [NSMutableDictionary dictionaryWithContentsOfFile:path];
[configDict setObject:newDict forKey:@"newDict"];
if ([configDict writeToFile:path2 atomically:YES]) {
     TRACE("OK");
} else {
     TRACE("NG");
}

writeToFileでエラーが"NG"が返るのでずっと悩んでたんだが
理由はこれ
This method recursively validates that all the contained objects are property list objects (instances of NSDataNSDateNSNumberNSString,NSArray, or NSDictionary) before writing out the file, and returns NO if all the objects are not property list objects, since the resultant file would not be a valid property list.

このメソッドの再帰的に含まれているすべてのオブジェクトは、ファイルを書き出す前に、プロパティリストオブジェクト(NSDataの、NSDate、NSNumber、NSString、NSArray、またはNSDictionaryのインスタンス)であることを検証しておらず、すべてのオブジェクトがプロパティリストオブジェクトでない場合はNOを返すので結果ファイルが有効なプロパティのリストではありません。

objectがおかしいよってことで
[configDict setObject:newDict forKey:@"newDict"];
のnewDictにNSDictionaryっぽくないデータが入っていた
plistはこんな感じなる
key = value

newDictの中身はこうなっていた
"key" = value
JSONからの変換時に""が付与されてwriteToFileができなかったというというオチ