2013年12月27日金曜日

UIViewのアニメーション

[UIView beginAnimations:nil context:nil];
[UIView setAnimationDuration:0.5];
[UIView setAnimationDelegate:self];
[UIView setAnimationDidStopSelector:@selector(scrollAnimationDidEnd)];

//ここに処理を追加
animeView.frame = CGRectMake(0.0, 10.0, 100, 100)
                            
[UIView commitAnimations];

2013年12月10日火曜日

[iOS]UIImageViewに追加されたUIButtonが反応しない場合の処理

UIImageVIewはタッチイベントに対応してないので、

imageView.userInteractionEnabled = YES;


とするとタッチ可能になる

2013年8月27日火曜日

[Android]Javaで良く使うコードのメモ

//HashMapを格納する可変配列の宣言(コメントアウトのサンプル)
private ArrayList<Map<String, String>> arrayList  = new ArrayList<Map<String, String>>();

//配列をループして取り出し
String data[] = {"a", "b", "c"};

for (String char: data){
     System.out.println(String);
}

//0埋めの桁あわせ
String.format("%1$03d", intNumber)

//String -> byte[]
String data = "test;"
byte[] bytes = data.getBytes();

//byte[] -> String
String byteToString = new String(bytes);

2013年7月18日木曜日

[Android]バックキーを無効にする

以下のコードをActivityに追加。
@Override
public boolean dispatchKeyEvent(KeyEvent event) {
    if (event.getAction() == KeyEvent.ACTION_DOWN) {
        switch (event.getKeyCode()) {
        case KeyEvent.KEYCODE_BACK:
            this.moveTaskToBack(true);
            return true;
        }
    }
    return super.dispatchKeyEvent(event);
}

2013年7月17日水曜日

[iOS]ナビゲーションバーのバックキーを「戻る」に固定する

遷移先のViewControllerでは無く、遷移元のViewControllerに設定すること。

UIBarButtonItem *backButtonItem = [[UIBarButtonItem alloc]
                                   initWithTitle:@"戻る"
                                   style:UIBarButtonItemStyleBordered
                                   target:nil
                                   action:nil];
self.navigationItem.backBarButtonItem = backButtonItem;
[backButtonItem release];

2013年7月3日水曜日

[iOS]NSLogで文字化けする問題

//recvDictをエンコードして表示する
NSString *dictString = [NSString stringWithFormat:@"%@",recvDict];
NSString *encodeString = [NSString stringWithCString:
                                   [dictString cStringUsingEncoding:NSUTF8StringEncoding]
                                    encoding:NSNonLossyASCIIStringEncoding];
NSLog(@"encodeString %@", encodeString);

2013年6月25日火曜日

2013年6月19日水曜日

[iOS]NSURLConnectionの証明書切れを回避する方法

// 証明書切れ回避
- (BOOL) connection:(NSURLConnection *)connection canAuthenticateAgainstProtectionSpace:(NSURLProtectionSpace *)protectionSpace
{
    return [protectionSpace.authenticationMethod isEqualToString:NSURLAuthenticationMethodServerTrust];
}

- (void)connection:(NSURLConnection *)connection didReceiveAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge
{
    if ([challenge.protectionSpace.authenticationMethod isEqualToString:NSURLAuthenticationMethodServerTrust]){
        [challenge.sender useCredential:[NSURLCredential credentialForTrust:challenge.protectionSpace.serverTrust]
             forAuthenticationChallenge:challenge];
    }
    [challenge.sender continueWithoutCredentialForAuthenticationChallenge:challenge];
}

2013年6月12日水曜日

[iOS]UserDefaultsに保存する

FileOpenなどをしなくて良いので便利

// hogeDictを保存
[[NSUserDefaults standardUserDefaults] setObject:hogeDict forKey:@"hoge"];

// hogeDictを読み出し
NSDictionary *hogeDict = [[NSUserDefaults standardUserDefaults] objectForKey:@"hoge"];

2013年6月6日木曜日

[iOS] AVAudioPlayerでサウンドが再生されない

NSString *path = [[NSBundle mainBundle] pathForResource:@"sample" ofType:@"mp3"];
NSString *expandedPath = [path stringByExpandingTildeInPath];
NSURL *url = [NSURL fileURLWithPath:expandedPath];
NSError *error = nil;
AVAudioPlayer *audioPlayer = [[AVAudioPlayer alloc] initWithContentsOfURL:url error:&error];
if (audioPlayer) {
   [audioPlayer prepareToPlay];
   [audioPlayer play];
} else 
   NSLog(@"error %@", error);
}

簡単なコードなのに音声が再生されず、シンボルエラーで落ちるという現象が発生した。
落ちている場所はinitWithContentsOfURLのところ。

pathを変えてみるなどしたが、全く受け付けなかった。

・原因
使用した"sample.mp3"にあったようで、"sample.wav"などにエンコードすると問題なく再生された。
私がエンコードのヘッダーなどは分からないので詳細は不明だが、
エンコーダーやファイルによってはiOSで再生できないものがあるらしい。

そういえばAndroidSDKにもMediaPlayer似た問題があったな。
サウンドがが途切れたり、再生が遅かったり、再生されなかったり、、、

サウンド関係は面倒臭がらずにOpenALを使用したほうが結果的に良いかも

2013/06/19 追記
OpenALでも再生できなかった。
ビルドクリーンをして、本体orシミュレーターからアプリを削除して、
project.xcworkspaceとxcuserdataを削除した後に、
ビルドせずにMACを再起動して、ビルドをしたら問題無く再生された。

2013年6月4日火曜日

[iOS]文字列をLocalizable.stringから取得する

タグ = 表示したい文字列のフォーマット
Localizable.string
"sample" = "サンプル";

コード上で取得する
タグ,コメントでコメントは省略可
NSLocalizedString(@"network_domain", nil)

2013年5月30日木曜日

[iOS]NSURLConnectionを使用してHTTP接続をする。

cookieの保存が必要だったのでメモを残しておく。

- (void)viewDidLoad
{
    [super viewDidLoad];
    
    //リクエストを作成
    NSMutableURLRequest *request = [[NSMutableURLRequest alloc] init];
    [request setHTTPMethod:@"GET"];
    [request setURL:[NSURL URLWithString:@"http://apple.ios.sample.com"]];
    [request setTimeoutInterval:30.0];
    [request setCachePolicy:NSURLRequestReloadIgnoringLocalCacheData];
    
    //Cookieを保持している場合は読み込む
    //TODO Cookieの扱いがおかしい?
    NSHTTPCookie *cookie = nil;
    NSData *cookiesData = [[NSUserDefaults standardUserDefaults] objectForKey:@"cookie"];
    if (cookiesData.length != 0) {
        NSArray *cookies = [NSKeyedUnarchiver unarchiveObjectWithData:cookiesData];
        for (cookie in cookies) {
            [[NSHTTPCookieStorage sharedHTTPCookieStorage] setCookie:cookie];
        }
    } else {
        //TODO Cookieが保持されていない
    }
    NSArray *cookieArray = [NSArray arrayWithObjects: cookie, nil];
    NSDictionary *headers = [NSHTTPCookie requestHeaderFieldsWithCookies:cookieArray];
    [request setAllHTTPHeaderFields:headers];
    
    //ネットワーク接続を開始
    NSURLConnection *connection = [[NSURLConnection alloc]initWithRequest:request delegate:self];
    [connection release];
    [request release];
}

#pragma mark -

//サーバーから認証の要求があった時に呼び出される
-(void)connection:(NSURLConnection *)connection didReceiveAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge
{
    
}

//サーバーからレスポンスがあった時に呼び出される
- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response
{   
    //Cookieを保存
    NSData *cookiesData = [NSKeyedArchiver archivedDataWithRootObject:
                           [[NSHTTPCookieStorage sharedHTTPCookieStorage] cookies]];
    [[NSUserDefaults standardUserDefaults] setObject:cookiesData
                                              forKey:@"cookie"];
    
    //レスポンスコード取得
    statusCode = [((NSHTTPURLResponse *)response) statusCode];
    
    if ([receivedData retainCount]) {
        [receivedData release];
    }
    receivedData = [[NSMutableData alloc] init];
}

//サーバーからデータを受け取ると呼び出される
- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data
{
    [receivedData appendData:data];
}

//サーバーからの通信が終わる直前に呼び出される
- (void)connectionDidFinishLoading:(NSURLConnection *)connection
{
    //TODO receivedDataにbodyが入っている
}

2013年5月14日火曜日

[iOS]Interface BuilderでUIScrollViewのContentSizeを設定することはできない。


Interface BuilderでUIScrollViewのContentSizeを設定使用と思ったが、
それを行うUIが無いことに気づいた。

http://stackoverflow.com/questions/1135163/how-do-i-use-uiscrollview-in-interface-builder
によると、ContentSizeはコード状態のみ設定可能のようだ、IBでやるのは諦めよう。
ただしiOS6のAuto Layoutを使用すれば可能になる。

With Autolayout (iOS6+), you can avoid setting contentSize. Set the following constraints instead:
Pin the top of the scrollview to the top of its top-most child.
And pin the bottom to the bottom of its bottom-most child.

2013年4月27日土曜日

[AndroidSDK]ServiceのbindService()でfalseが帰る

Intent intent = new Intent(this, MyService.class);
boolean result = bindService(intent, mConnection, Context.BIND_AUTO_CREATE);.

でfalseが返ってくる

StackOverflowによると

Android Context.bindService always returns false and ServiceConnection object is never triggered
(bindServiceでfalseが返ってきてServiceConnectionが動かねえよ)


getApplicationContext().bindService()でいけるぜ、
この回答で動いた人がおおいみたいだが、今回はどうも違うようだ。

結論
Manifest.xmlで
<service android:name=".MyService" />
となっていたが、パッケージが間違っていた
<service android:name="Utility.MyService" />

2013年4月26日金曜日

[AndroidSDK]Google PlayにおけるAndroid端末のシェア率を見る

公式が出している。

Dashboards
http://developer.android.com/intl/ja/about/dashboards/index.html#Platform

14日前のデータとのこと。
これを見てどのバージョンに合わせるか考えると良い

iOSもこの表があると良いな、不定期にしか出してくれないからな

2013年4月24日水曜日

[AndroidSDK]AsyncTaskを使用してバックグランド処理を行う。

ネットワーク処理をさせている間にProgressDialogを表示させたい時など
public class MainActivity extends Activity {
    ProgressDialog progressDialog;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        //setContentView(R.layout.activity_main);

        progressDialog = new ProgressDialog(this);

        MyAsyncTask task = new MyAsyncTask();
        //バックグランド処理を実行
        task.execute(getApplicationContext());
        //このログが実行されているときに、MyAsyncTaskが終わっているとは限らなので
        //MyAsyncTask後に処理させたいときはonPostExecute()を使用すること
        Log.i("tag", "mes");
    }

    public class MyAsyncTask extends AsyncTask {
        @Override
        //doInBackgroundが実行されてる前に呼ばれる
        protected void onPreExecute() {
            //ProgressDialogなどはここで実装すると良い
            progressDialog.setMessage("データを取得しています。");
            progressDialog.setProgressStyle(ProgressDialog.STYLE_SPINNER);
            progressDialog.setCancelable(false);
            progressDialog.show();
        }

        //バックグランド処理はここに追加
        @Override
        protected Integer doInBackground(Context... context) {
            //何かの処理

            return 1;
        }

        //doInBackgroundが実行された後に呼ばれる
        @Override
        protected void onPostExecute(Integer result) {
            progressDialog.dismiss();
        }
    }
}

2013年4月23日火曜日

[AndroidSDK]DefaultHttpClientを使ってPOSTをする

public void httpConnect() {
 DefaultHttpClient client = new DefaultHttpClient();
 StringBuilder uri = new StringBuilder("hostname.com");
 HttpPost http = new HttpPost(uri.toString());

 http.setHeader("Content-type", "text/plain; charset=utf-8");
 //bodyの作成
 try {
  http.setEntity(new StringEntity("body", "UTF-8"));
 } catch (UnsupportedEncodingException e) {
  e.printStackTrace();
 }

 HttpResponse httpResponse = null;
 try {
  // HTTPリクエストを送信
  httpResponse = client.execute(http);
 } catch (Exception e) {
  e.printStackTrace();
 }

 // HTTPレスポンスを取得
 int status = httpResponse.getStatusLine().getStatusCode();
 if (HttpStatus.SC_OK == status) {
  //ヘッダーの表示
  Header[] headerArray = http.getAllHeaders();
  for (Header header : headerArray) {
   Log.d(getLocalClassName(), "header[" + header.getName() + "] [" + header.getValue() + "]");
  }
  // Bodyの取得
  HttpEntity httpEntity = httpResponse.getEntity();
  String body = null;
  try {
   body = EntityUtils.toString(httpEntity);
  } catch (ParseException e) {
   e.printStackTrace();
  } catch (IOException e) {
   e.printStackTrace();
  }
  Log.d(getLocalClassName(), "body " + body);
 } else {
  //TODO エラー処理
 }
}

2013年4月22日月曜日

[Android SDK]Activity、アプリを終了させる。


finish()
でactivityを1つずつ終わらせるのがベスト
ただしスタックされたn個のActivityを終わらせるには、見た目上うまく表示する必要がある。

this.moveTaskToBack(true);
でアプリがバックグランドに入るので見た目上はこっちの方が良い

System.exit(int) 
は問題があるので使わない方がいい

2013年4月18日木曜日

[AndroidSDK]Thread時のUI更新

・AndroidアプリはUI更新は1タスクで回っている
・ThreadからUI更新をしても、更新先が無い
・Handlerで割り込みをして、UI更新のタスクに委任する

public class SampleActivity extends Activity {
 private static Handler mHandler;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        
  mHandler = new Handler(); //Handlerを作成
  
  //Threadを開始
  new Thread(new Runnable() {
                public void run() {
                
                if (true) { 
                 TextView textView = (TextView) findViewById(R.id.TextView);
                 textView.setText("Handlerを使わないとここで落ちる");
                }
                
    mHandler.post(new Runnable() {
     public void run() {
      TextView textView = (TextView) findViewById(R.id.TextView);
                  textView.setText("Handlerを使って更新するので落ちるない");
     }
    });
   }
  }).start();
 }
}

参考サイト
TechBooster
http://techbooster.org/android/application/6191/

throw Life
http://www.adamrocker.com/blog/261/

2013年4月15日月曜日

[Android SDK]デバックモードの判別


[Android SDK]デバックモードの判別

Debug.isDebuggerConnected()

で判定できる。

manifest.xmlで
android:debuggable="true"
とすると。
Avoid hardcoding the debug mode; leaving it out allows debug and release builds to automatically assign one
とワーニングが出るが、debuggableは自動的に判別するのでmanifest.xmlで設定をする必要がない、
eclipseからの起動でdebug=trueとなり、apkを書きだす時にdebug=falseになる。

2013年3月15日金曜日

[iOS]iOSシミュレーターの格納場所

フォルダパスは
/Users/[User Name]/Library/Application Support/iPhone Simulator/6.1
または
/Library/Application Support/iPhone Simulator/6.1
iOSのバージョンごとにフォルダ分けされている。

Applicationsフォルダ内の
HOGE1234-HO77-HO77-HO77-HOGE123456789
などのフォルダがアプリ格納の場所。

ファイルのアウトプットはDocuments内に格納される。

2013年3月8日金曜日

[iOS]Enumeration values * not handled in switch


Enumeration values * not handled in switch

列挙子*はswitchで処理されていません。
つまりswitchで列挙子をすべて網羅する必要がある。

2013年3月4日月曜日

[iOS]iOS4.3~5.1~6.1に回転対応をする

あらかじめ[appname].plistSupported interface orientationsを設定する必要がある。

- (void)viewDidLoad
{
    [super viewDidLoad];
    
    //iOS 4.3~5.1 回転時の呼び出しメソッドを設定
    
    [[UIDevice currentDevice] beginGeneratingDeviceOrientationNotifications];
    [[NSNotificationCenter defaultCenter] addObserver:self
                                             selector:@selector(orientationChanged:)
                                                 name:UIDeviceOrientationDidChangeNotification
                                               object:nil];
}

- (void)viewDidDisappear:(BOOL)animated
{
    [super viewDidDisappear:animated];
    //iOS 4.3~5.1 回転の停止
    //他のViewControllerで使用したくないときはここでキャンセルする
    [[NSNotificationCenter defaultCenter] removeObserver:self
                                                    name:UIDeviceOrientationDidChangeNotification
                                                  object:nil];
}

//iOS 6.0~ 回転をサポートするか
- (BOOL)shouldAutorotate
{
    return YES;
}

//iOS 6.0~ 推奨される向き
- (UIInterfaceOrientation)preferredInterfaceOrientationForPresentation
{
    return UIInterfaceOrientationLandscapeLeft;
}

//iOS 6.0~ サポートする向き
- (NSUInteger)supportedInterfaceOrientations
{
    return UIInterfaceOrientationMaskAll;
}

//iOS 4.3~5.1 回転をサポートするか?
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
    return YES;
}

//回転時の動作
- (void)orientationChanged:(NSNotification *)notification
{

}

//回転時のアニメーションを定義
- (void)willAnimateRotationToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation duration:(NSTimeInterval)duration
{

}

//回転前に呼び出される
- (void)willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration
{

}

2013年2月19日火曜日

[iOS]This bundle is invalid.

This bundle is invalid. The key CFBundleVersion in the info.plist file must contain a higher version than that of the previously uploaded version.

iTunesConnectに審査提出中にOrganaizerで上記のエラーが発生した。

CFBundleVersionが前のバージョンより新しくしてください、
ってことなんだけど、1.1.0から1.1.1でもちろん新しくなってる。

原因は
plistからBundle versionが抜けていた。

Target>SummaryのVersionって修正してもplistに反映されないのね。

2013年2月18日月曜日

[iOS]NSPersistentStoreCoordinatorでエラー


Coredataを使用中に
persistentStoreCoordinator_ = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:[self managedObjectModel]];
でエラーを吐いた。
persistentStoreCoordinator_
を生成できないらしい。

現象は
http://stackoverflow.com/questions/4199466/core-data-crash-in-initwithmanagedobjectmodel
と同じで、appname.xcdatamodeldのファイルがおかしいらしい

appname.xcdatamodeldがxCode上から開けない状態だったので、
一度xCode上から削除して再度インポートするとエラーは消えた。

他にもxcdatamodeldが前のバージョンと違ってもこのエラーらしいね。

2013年2月8日金曜日

[iOS]iPadのサイズとか

iPhoneサイズ
320x480
640x960
640x1136

ステータスバーを省いたサイズ
320x460
640x620
640x1096

iPad、iPadMiniサイズ
Portrait 768 x 1024
Landscape 1024 x 768

ステータスバーを省いたサイズ
Portrait 768 x 1004
Landscape 1024 x 748


iPad(Retina)サイズ
Portrait 1536 x 2048
Landscape 2048 x 1536

ステータスバーを省いたサイズ
Portrait 1536 x 2008
Landscape 2048 x 1496


2013年1月23日水曜日

[AndroidSDK]MapViewが表示されない

AndroidSDKにてMapViewことGoogle Map APIが動作しない事態になった。
MapView自体は表示されているが、地形データ等のダウンローができない状態。

エラーログには

IOException processing: 26
java.io.IOException: Server returned: 3

と表示された。

・ソース上のミスをチェック、、無し
・Google MAP API Keyは正しいか、、、正しい

少し考えこんで署名が無いことに気づいた。
Google MAP API Keyはアプリ署名に紐付けられているので、
署名付きアプリとしてAPKを書き出したところ表示された。


2013年1月21日月曜日

[iOS]iPhoneでゲームを作る方法

ゲームを作ることになったので、iPhoneでゲームを作る方法を考えてみる。
現在4通りほど考えられる。


CoreAnimetion
UIViewとCGContextRefなどを使う方法
ゲームのために作られてるわけじゃないから複雑なことを実装するとコケる可能性がある

OpenGL1.1/2.0
パフォーマンスが良い3D/2Dエンジン、本格的に作るならこっちだろう
習得に時間がかかりそうだ、1週間やそこらで十分に扱うのは難しいだろう

強火で進め
http://d.hatena.ne.jp/nakamura001/20080918/1221738923

OpenGL1.1リファレンス
http://www.khronos.org/opengles/sdk/1.1/docs/man/

cocos2d
iOS向き2Dゲームワークフレーム
実績が無数にある、修得も簡単
中身はOpenGLES1.1

http://www.cocos2d-iphone.org/

corona
モバイル向きワークフレーム
重力エンジンなどがある、修得も比較的簡単

http://jp.anscamobile.com/corona/

salad
コード不要でGUIベースで簡単なゲームを作成する

http://gamesalad.com/