技術の犬小屋

Webプログラミングを餌に生きる犬のメモ帳

Posts in the スマートフォン category

フィーチャーフォンアプリやスマートフォンアプリにて顧客の情報を管理する必要があるようなサービスを作りたい場合、データベース側との照合において、顧客の使用する携帯端末を一意として識別する方法を用意する必要がある。
 
何故このような識別方法を取るのかと言うと、顧客の端末にあらかじめ紐付いている情報を利用することでログイン情報を入力させる手間を省くことができるからである。
 
 

UUIDを利用する

大人気iPhone用アプリ「パズドラ」が利用していると思われる認証方法。
アプリの初回起動時にUUIDを生成し、アプリ内に保持することによって、次回起動以降、そのUUIDを参照して個人の端末を識別する。
 
・メリット
IMEIやIMSIを利用することで発生するデメリットをある程度回避することが可能。
 
・デメリット
アプリが1度でも削除されるとUUIDも消えてしまい、照合できなくなる。(何らかの方法でアプリのバックアップが取れる機構が用意されている場合は回避可能)
 

IMEIを利用する

携帯端末に紐付けるられている固有番号を利用する認証方法。
 
・メリット
アプリを削除してしまっても再インストールすれば再度認証が可能。
 
・デメリット
携帯端末の乗り換え(変更)を行うと照合ができなくなる。
 

IMSIを利用する

SIMカードに紐付けられている固有番号を利用する認証方法。
 
・メリット
アプリを削除してしまっても再インストールすれば再度認証が可能。
携帯端末を乗り換えても、同じSIMカードさえ手元にあれば認証が可能。
 
・デメリット
SIMカードスロットが搭載されていない端末では利用不可。
通信事業者との契約を解約する際にSIMカードは通信事業者に返却しなければいけない。
 
 
以上
 
 
参考
独自の調査・研究

仕事でAndroidによる開発を行ったので、その際に用いたデバッグ方法のメモ。
  
 

方法

Androidには専用のデバッグツールがあり、その名もLogCatという。
 
EclipseにAndroidSDKをインストールした際にはLogCatがデフォルトで付属する。
 
LogCatには専用の命令が用意されており、以下のような記述で強制的にログに自分でコメントを出力することができる。
 
 

Log.d("○○のデバッグ", "ここを通過したよ!");

 
第1引数がタグ、第2引数がテキストという分類でログに出力される。
 
 
 

例外処理を合わせて使う

Androidアプリの開発ではJavaを使うので、この場合の例外処理はtry catch文を使う。
 
以下のようにエラーが発生しそうなコードをtryブロックで囲み、catchブロックにLog.d();を書いておく。
 

try{
    //エラーが発生しそうなコード


} catch (Exception e) {
    Log.d("例外処理でのデバッグ", "上記のコードでエラー発生です。");
}

 

今回はインスタンス生成周りについてまとめる。インスタンス生成以外にもメソッド内の実装で重要なことを書いておく。
 

クラスのインスタンスを生成する方法

インスタンスはallocキーワードで生成することができる。
 
インスタンス生成の書式
変数 = [クラスの型 alloc];
 
記述例としては以下のようになる。

MyClass *myClass = [MyClass alloc];

 

インスタンス生成後にコンストラクタを実行する

以下のコードではインスタンス生成後にコンストラクタを実行している。二重カッコで囲むと複数の処理を行うことが可能になる。
 
書式は以下のようになる。
変数 = [[クラスの型 処理1] 処理2];
 
記述例としては以下のようになる。

MyClass *myClass = [[MyClass alloc] init];

 
また、次のような書き方もできる。 

[[MyClass alloc] initWithNibName:@"HelloWorld" bundle:[NSBundle mainBundle]];

 
上記では、MyClassのインスタンスを生成した後にinitWithNibNameメソッドを呼び出し、引数を2つ渡している。引数として@”HelloWorld”とbundleを渡している。bundleにはmainBundleメソッドの戻り値が格納されている。
 
上記のbundleはラベルと呼ばれる。Objective-Cには「オーバーロード」が存在しないので、ラベルはメソッドの定義において、同一名のメソッドが複数定義されている場合に、メソッドを呼び分ける際に使用する。
 
 
以上
 
 
参考
visible true: Java脳でもわかるObjective-C入門

今回はアクセサについて説明する。
 

アクセサについて

Objective-Cにはアクセサを自動的に生成してくれる機能が存在する。
 
アクセサの宣言は@propertyで行う。
 
書式は以下のようになる。以下はヘッダファイル(.h)に記述する。

@interface Class : SuperClass {
変数型1 *変数名1;
変数型2 変数名2;
}
@property (属性) 変数型1 *変数名1;
@property (属性) 変数型2 変数名2;
@end

 
ヘッダファイル(.h)の記述例としては以下のようになる。

@interface SampleObj : NSObject {
    NSString *foo;
    int bar;
}
@property (nonatomic , strong) NSString *foo;
@property (nonatomic , assign) int bar;
@end

 
アクセサの実装は@synthesizeで行う。以下はメインファイル(.m)に記述する。

@implementation クラス名
@synthesize 変数名1;
@synthesize 変数名2;
@end

 
メインファイル(.m)の記述例としては以下のようになる。

@implementation SampleObj
@synthesize foo;
@synthesize bar;
foo = 5;        //アクセサで変数を操作する
bar = 10;      //アクセサで変数を操作する
@end

 
属性には以下のものが存在する。
 

assign


setterで単純代入を使用することを指定します。これはデフォルトで適用されます。このキーワードを使う場合、アプリケーションはガーベジコレクション(GC)を使っていないと、単純代入は適切な振る舞いではなくなるためコンパイラ警告が発生します。GCでないアプリケーションの場合は、オブジェクトへの警告を避けるために、格納方法の属性の1つを明示的に指定する必要があります。GCを使わないアプリケーションで変数がNSCopyingプロトコルを採用していると、その状況でのassignの使用は通常は適切でないため、この属性に対して警告が発生します。

 

retain


代入時にオブジェクトに対してretainを呼び出す必要があることを指定します。この属性はObjective-Cオブジェクトに対してのみ有効です(Core Foundationオブジェクトに対してはretainは指定できません。詳しくはCore Foundationを参照してください)。

※これから使用するので勝手にメモリから解放してはいけないとObjective-Cに伝える。
 

copy


代入にオブジェクトのコピーを使用することを指定します。コピーは、copyメソッドを呼び出すことによって作成されます。この属性はオブジェクト型に対してのみ有効であり、その場合はNSCopyingプロトコルを実装する必要があります。

 

nonatomic

合成されるアクセサが非アトミックになるように指定します。
 

readwrite


プロパティを読み取り/書き込み可能として扱うべきであることを示します。これはデフォルトで適用されます。@implementationではgetterとsetterの両方のメソッドが必須であり、@synthesizeを使う場合はgetterメソッドとsetterメソッドが合成されます。

 

readonly


プロパティが読み取り専用であることを示します。デフォルトは、読み取り/書き込みが可能です。ドット構文を使って値を代入しようとすると、コンパイラエラーが発生します。@implementationではgetterメソッドだけが必須であり、@synthesizeを使う場合は、getterメソッドだけが合成されます。

 

unsafe_unretained


assignと同じ。(ARCという新しいメモリ管理方式に対応。詳しくはARCの概要を参照。)
 
 

strong


強い参照と認識されるようになる。retainと同じ。(ARCという新しいメモリ管理方式に対応)

※デフォルトは強い参照となるので、通常は指定する必要はない。
 

weak


弱い参照と認識されるようになる。(ARCという新しいメモリ管理方式に対応)

 
 
以上
 
 
参考
Objective-C ARCによるメモリ管理 | YOHEI’s BLOG
ダイナミックObjective-C (104) プロパティ(4) – プロパティの属性 | マイナビニュース

前回は変数宣言についてまとめたので、今回はメソッドの宣言、実装、呼び出しについてまとめる。
 

メソッドの宣言

メソッドを宣言する際の書式は以下のようになる。以下はヘッダファイル(.h)に記述する。
 
- (戻り値の型) メソッド名 : (引数の型) 引数名;
 
宣言の頭に-を付けるとインスタンスメソッドを指す。逆は+で、これはクラスメソッド(静的メソッド)を指す。
 
引数を複数指定する場合は以下のような書式になる。
 
- (戻り値の型) メソッド名 : (第1引数の型) 第1引数名 : (第2引数の型) 第2引数名;
 
ラベル名を指定すると、同一名のメソッドが複数存在する場合にメソッドの呼び分けを行うことができるようになる。Objective-Cには「オーバーロード」が存在しないので、同一名のメソッドを複数定義する際には、第二引数以降に名前を付ける必要がある。
 
- (戻り値の型) メソッド名 : (第1引数の型) 第1引数名 第2引数のラベル名: (第2引数の型) 第2引数名 第3引数のラベル名: (第3引数の型) 第3引数名;
 
記述例としては以下のようになる。以下はヘッダファイル(.h)に記述している。
 

@interface SampleClass: Object {
    //変数の宣言
    int val;
}
//メソッドの宣言
//インスタンスメソッドの場合は頭に"-"を付ける。
- (id)sample1 : (NSString*)file:(int)ch;

//クラスメソッドの場合は頭に"+"を付ける。
+ (id)sample2 : (NSString*)file:(int)ch;

//引数がNSStringなどの参照型の場合は引数の型宣言にアスタリスク(*)を付ける。
- (id)sample3 : (NSString*)file:(int)ch;

//引数がintなどのプリミティブ型の場合は引数の型宣言にアスタリスクは不要。
- (id)sample4 : (int)num;

//引数を複数受け取る場合はコロン(:)で区切る。
- (id)sample5 : (int)num:(int)loop;

//戻り値が無い場合はvoidと記述する。
- (void)sample6 : (int)foo;

//戻り値の記述を省くこともできる。この場合はvoidの扱いになる。
- sample7 : (int) v;

//プロトコルで型への適合をチェックすることもできる。
- (id)sample8 : (NSView <Moge> *) y;

@end

 

メソッドの実装

メソッドを実装する際の書式は以下のようになる。以下はメインファイル(.m)に記述する。
 
- (戻り値の型)メソッド名:(引数の型)引数名 {
//…何らかの実装
}

 
ちなみにObjective-Cでは戻り値を複数指定することはできないので、複数戻り値を指定したいときは配列で代用する。
 

メソッドの呼び出し

Objective-Cではメッセージ式というメソッドの呼び出し方法を使用してメソッドを呼び出す。今回はメッセージ式にはあまり深く踏み込まず、簡潔な呼び出し方法だけを説明する。
 
書式は以下のようになる。以下はメインファイル(.m)に記述する。
 
[クラス名 メソッド名];
 
記述例としては以下のようになる。
 

[myClass doMethod];

 
引数を付ける場合の書式は以下のようになる。
 
[クラス名 メソッド名:引数];
 
記述例としては以下のようになる。
 

[myClass doMethod:@"hoge1"];

 
コロン(:)で区切ることで引数をメソッドに渡すことができる。
 
以下のようにコロン(:)区切りで記述することで複数の引数をメソッドに渡すことができる。
 

[myClass doMethod:@"hoge1":@"hoge2"];

 

[myClass doMethod:@"hoge1":@"hoge2":@"hoge3"];

 
 
以上
 
 
参考
visible true: Java脳でもわかるObjective-C入門
こたつつきみかん なぜ Objective-C は気持ち悪いのか 見た目編
iPhoneアプリケーション開発: Objective-Cのメソッドについて