REST風サービスをJavaEEで構築する方法04(各メソッド編)

前回までは、GETメソッドのみを対象としてきたが、今回はGETメソッド以外(POST、PUT、DELETE)の実装方法を紹介する。
簡潔に実装方法を説明すると、これまで「@GET」を指定していた箇所で、「@POST」、「@PUT」、「@DELETE」を指定することになる。

<前提条件>
下記の記事を読了していること。
REST風サービスをJavaEEで構築する方法01(導入編)
REST風サービスをJavaEEで構築する方法02(雛形プロジェクト編)
REST風サービスをJavaEEで構築する方法03(RESTクライアント編)

<全体像から見た位置づけ>
RESTクライアントとApi層の追加実装を行う。

<手順概要>
1.Api層の追加実装を行う
2.index.htmlファイルの追加実装を行う

<手順詳細>
1.Api層の追加実装を行う
REST風サービスをJavaEEで構築する方法02(雛形プロジェクト編)で作成した「SampleApi」クラスに3つのメソッドを追加する。

package lab.moonmt.SampleRest.api;

import javax.ws.rs.DELETE;
import javax.ws.rs.GET;
import javax.ws.rs.POST;
import javax.ws.rs.PUT;
import javax.ws.rs.Path;

@Path("sampleApi")
public class SampleApi {
    
    @GET              
    @Path("getSample")
    public String getSampleMethod(){
				
        return "Hello REST world(GET)";
    }
    
    @POST                   //...(1)
    @Path("postSample")
    public String postSampleMethod(){
	
        return "Hello REST world(POST)";
    } 
    
    @PUT                   //...(2)
    @Path("putSample")
    public String putSampleMethod(){
                        
        return "Hello REST world(PUT)";
    }
    
    @DELETE                //...(3)
    @Path("deleteSample")
    public String deleteSampleMethod(){
                        
        return "Hello REST world(DELETE)";
    }
}


ソースコード解説

番号 説明
(1) @POSTアノテーションを使用し、POSTメソッドである事を設定する
(2) @PUTアノテーションを使用し、PUTメソッドである事を設定する
(3) @DELETEアノテーションを使用し、DELETEメソッドである事を設定する

2.index.htmlファイルの追加実装を行う
REST風サービスをJavaEEで構築する方法03(RESTクライアント編)で編集した、index.htmlファイルを以下の様に追加編集する。

<!DOCTYPE html>
<html>
    <head>
        <title>TODO supply a title</title>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        
        <!-- jQueryライブラリの読み込み -->
        <script src='js/libs/jquery-1.11.2.min.js'></script>
        
        <!-- RESTクライアントの記述 -->
        <script>
             $(function(){
                 
                $('#btnGet').on('click', function(){    
                     $.ajax({
                       type: "GET",
                       url: "http://localhost:8080/SampleRest/webresources/sampleApi/getSample",
                       success: function(data){ 
                           alert(data);
                       }
                    });
                });
                
                $('#btnPost').on('click', function(){    
                     $.ajax({
                       type: "POST",
                       url: "http://localhost:8080/SampleRest/webresources/sampleApi/postSample",
                       success: function(data){ 
                           alert(data);
                       }
                    });
                });
                
                $('#btnPut').on('click', function(){    
                     $.ajax({
                       type: "PUT",
                       url: "http://localhost:8080/SampleRest/webresources/sampleApi/putSample",
                       success: function(data){ 
                           alert(data);
                       }
                    });
                });
                
                $('#btnDelete').on('click', function(){    
                     $.ajax({
                       type: "DELETE",
                       url: "http://localhost:8080/SampleRest/webresources/sampleApi/deleteSample",
                       success: function(data){ 
                           alert(data);
                       }
                    });
                });
                
             });
        </script>
        
    </head>
    <body>
        <input type="button" value="GETメソッド"    id="btnGet"    /><br>
        <input type="button" value="POSTメソッド"   id="btnPost"   /><br>
        <input type="button" value="PUTメソッド"    id="btnPut"    /><br>
        <input type="button" value="DELETEメソッド" id="btnDelete" />
    </body>
</html>

<動作確認>
プロジェクトを実行し、ブラウザに表示されたボタンを押下すると、それぞれに対応したメッセージが記述された、ダイアログが表示されることを確認する。

※【PUTメソッド】ボタンを押下した場合の表示例

Enjoy Programing!!


<関連記事>
REST風サービスをJavaEEで構築する方法01(導入編)
REST風サービスをJavaEEで構築する方法02(雛形プロジェクト編)
REST風サービスをJavaEEで構築する方法03(RESTクライアント編)
・REST風サービスをJavaEEで構築する方法04(各メソッド編)[本記事]
REST風サービスをJavaEEで構築する方法05(パラメータの受け取り編)
REST風サービスをJavaEEで構築する方法06(JSON返却編1)
REST風サービスをJavaEEで構築する方法07(JSON返却編2)
REST風サービスをJavaEEで構築する方法08(Logic層編)
REST風サービスをJavaEEで構築する方法09(DB接続設定編)
REST風サービスをJavaEEで構築する方法10(DAO層編1)
REST風サービスをJavaEEで構築する方法11(DAO層編2)
REST風サービスをJavaEEで構築する方法12(DAO層編3)
REST風サービスをJavaEEで構築する方法13(SQLログ編)


<お勧め書籍>

わかりやすいJavaEEウェブシステム入門
JavaEEに関して基本的なことが分かり易く記述されている。
JavaEEに関する最初の1冊としてお勧めである。
Beginning Java EE 6 GlassFish 3で始めるエンタープライズJava
「金魚本」の愛称を持つJavaEEの教科書的な書籍である。
JavaEEを腰を据えて学びたい人にお勧めする1冊!!

REST風サービスをJavaEEで構築する方法03(RESTクライアント編)

今回はJavaScript(jQuery)を使用して、簡単なRESTクライアントを作成し、前回作成したREST風サービスを実行する方法を紹介する。

<前提条件>
下記の記事を読了していること。
REST風サービスをJavaEEで構築する方法01(導入編)
REST風サービスをJavaEEで構築する方法02(雛形プロジェクト編)

<全体像から見た位置づけ>
RESTクライアントの実装を行う。

<手順概要>
1.jQueryのライブラリをダウンロードする
2.jQueryを使用する準備をする
3.index.htmlファイルを編集する

<手順詳細>
1.jQueryのライブラリをダウンロードする
下記URLよりjQueryのライブラリファイルを取得する。
http://jquery.com

2.jQueryを使用する準備をする
プロジェクトツリーの「Webページ」を右クリックし、[新規]>[フォルダ]を選択する。

表示されたダイアログのフォルダ名に「js」と入力し、【終了(F)】ボタンを押下する。

作成された「js」フォルダを右クリックし、[新規]>[フォルダ]を選択する。

表示されたダイアログのフォルダ名に「libs」と入力し、【終了(F)】ボタンを押下する。

作成した「libs」フォルダに手順1でダウンロードしたjQueryライブラリのファイルをコピー&ペーストする。

3.index.htmlファイルを編集する
【GETメソッド】ボタンを押下すると、前回作成したREST風サービスと通信を行い、サーバからのレスポンスをダイアログに表示するRESTクライアントを作成する。

<!DOCTYPE html>
<html>
    <head>
        <title>TODO supply a title</title>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        
        <!-- jQueryライブラリの読み込み -->
        <script src='js/libs/jquery-1.11.2.min.js'></script>
        
        <!-- RESTクライアントの記述 -->
        <script>
             $(function(){
                 
                 $('#btnGet').on('click', function(){    
                     $.ajax({
                       type: "GET",
                       url: "http://localhost:8080/SampleRest/webresources/sampleApi/getSample",
                       success: function(data){ 
                           alert(data);
                       }
                    });
                 });
             });
        </script>
        
    </head>
    <body>
        <input type="button" value="GETメソッド" id="btnGet" />
    </body>
</html>

<動作確認>
プロジェクトを実行し、【GETメソッド】ボタンを押下すると、「Hello REST world」と記述されたダイアログが表示されることを確認する。

Enjoy Programing!!


<関連記事>
REST風サービスをJavaEEで構築する方法01(導入編)
REST風サービスをJavaEEで構築する方法02(雛形プロジェクト編)
・REST風サービスをJavaEEで構築する方法03(RESTクライアント編)[本記事]
REST風サービスをJavaEEで構築する方法04(各メソッド編)
REST風サービスをJavaEEで構築する方法05(パラメータの受け取り編)
REST風サービスをJavaEEで構築する方法06(JSON返却編1)
REST風サービスをJavaEEで構築する方法07(JSON返却編2)
REST風サービスをJavaEEで構築する方法08(Logic層編)
REST風サービスをJavaEEで構築する方法09(DB接続設定編)
REST風サービスをJavaEEで構築する方法10(DAO層編1)
REST風サービスをJavaEEで構築する方法11(DAO層編2)
REST風サービスをJavaEEで構築する方法12(DAO層編3)
REST風サービスをJavaEEで構築する方法13(SQLログ編)


<お勧め書籍>

わかりやすいJavaEEウェブシステム入門
JavaEEに関して基本的なことが分かり易く記述されている。
JavaEEに関する最初の1冊としてお勧めである。
Beginning Java EE 6 GlassFish 3で始めるエンタープライズJava
「金魚本」の愛称を持つJavaEEの教科書的な書籍である。
JavaEEを腰を据えて学びたい人にお勧めする1冊!!

REST風サービスをJavaEEで構築する方法02(雛形プロジェクト編)

今回は最低限のREST風サービスを構築する方法を紹介する。

<前提条件>
下記の記事を読了していること。
REST風サービスをJavaEEで構築する方法01(導入編)

<全体像から見た位置づけ>
Api層の実装を行う。

<手順概要>
1.プロジェクトの作成
2.クラスの作成
3.クラスを記述する
4.ApplicationConfigクラスを自動生成する

<手順詳細>
1.プロジェクトの作成
画面上部にある【新規プロジェクト】ボタンを押下する。

表示された「新規プロジェクト」ダイアログで[Java Web]>[Webアプリケーション]を選択し、【次>】ボタンを押下する。

プロジェクト名に「SampleRest」(※)を設定し、【次>】ボタンを押下する。
(※)任意の名前をつけることができる。

特に変更せず、【次>】ボタンを押下する。

何も選択せずに、【終了(F)】ボタンを押下する。

プロジェクトツリーに「SampleRest」という名前のプロジェクトが作成されたことを確認する。

2.クラスの作成
プロジェクトツリー上の「ソース・パッケージ」を右クリックし、[新規]>[Javaクラス]を選択する。

表示されたダイアログのクラス名に「SampleApi」(※)・パッケージ名に「lab.moonmt.SampleRest.api(※)を設定し、【終了(F)】ボタンを押下する。
(※)任意の名前をつけることができる。

クラスが作成された事を確認する

3.クラスを記述する
手順2で作成したクラスを編集し、処理内容を記述する。

package lab.moonmt.SampleRest.api;

import javax.ws.rs.GET;
import javax.ws.rs.Path;

@Path("sampleApi")          //...(1)
public class SampleApi {
    
    @GET                    //...(2)
    @Path("getSample")      //...(3)
    public String getSampleMethod(){
                        
        return "Hello REST world";
    }  
}

ソースコード解説

番号 説明
(1) @Pathアノテーションを使用し、クラスにアクセスするためのパスを設定する
(2) @GETアノテーションを使用し、GETメソッドである事を設定する
(3) @Pathアノテーションを使用し、メソッドにアクセスするためのパスを設定する

4.ApplicationConfigクラスを自動生成する
手順3で記述したクラス名の行番号付近を押下すると幾つかの選択肢が表示される。
その中の「Java EE 6仕様を使用してRESTを構成します」を押下すると、「ApplicationConfig」クラスが自動生成される。

<動作確認>
画面上部の実行ボタンを押下し、プロジェクトを実行する。

WebブラウザのURL欄に下記のURLを入力する
http://localhost:8080/SampleRest/webresources/sampleApi/getSample


URL解説

URL(部分) 説明
webresources 手順4で自動生成された「ApplicationConfig」クラス内の「@javax.ws.rs.ApplicationPath」に指定されている。任意の文字列に変更が可能である。
sampleApi 手順3で記述したクラスの「@Path」に指定している文字列
getSample 手順3で記述したメソッドの「@Path」に指定している文字列

ブラウザ上に「Hello REST world」が表示されることを確認する。

Enjoy Programing!!


<関連記事>
REST風サービスをJavaEEで構築する方法01(導入編)
・REST風サービスをJavaEEで構築する方法02(雛形プロジェクト編)[本記事]
REST風サービスをJavaEEで構築する方法03(RESTクライアント編)
REST風サービスをJavaEEで構築する方法04(各メソッド編)
REST風サービスをJavaEEで構築する方法05(パラメータの受け取り編)
REST風サービスをJavaEEで構築する方法06(JSON返却編1)
REST風サービスをJavaEEで構築する方法07(JSON返却編2)
REST風サービスをJavaEEで構築する方法08(Logic層編)
REST風サービスをJavaEEで構築する方法09(DB接続設定編)
REST風サービスをJavaEEで構築する方法10(DAO層編1)
REST風サービスをJavaEEで構築する方法11(DAO層編2)
REST風サービスをJavaEEで構築する方法12(DAO層編3)
REST風サービスをJavaEEで構築する方法13(SQLログ編)


<お勧め書籍>

わかりやすいJavaEEウェブシステム入門
JavaEEに関して基本的なことが分かり易く記述されている。
JavaEEに関する最初の1冊としてお勧めである。
Beginning Java EE 6 GlassFish 3で始めるエンタープライズJava
「金魚本」の愛称を持つJavaEEの教科書的な書籍である。
JavaEEを腰を据えて学びたい人にお勧めする1冊!!

REST風サービスをJavaEEで構築する方法01(導入編)

これから何回かにわたりJavaEEを用いて、REST風サービスを構築する方法を紹介する。

RESTと記述している理由
ここでは厳密にRESTfulと呼べるものを追い求めるのでは無く、業務としてのシステム構築を見据えて、各手法を紹介したいためである。
(厳密なRESTfulが業務に使えないと言いたい訳では無く、RESTfulの定義に縛られたく無いという思いで記述している)


<開発環境>
開発環境は下記のものを利用している

項目名 プロダクト名
OS Mac OS X(10.9.4)
JDK Java SE 7u51
統合開発環境 NetBeans 8.0.2 Java EE
データベース MySQL 5.6.23

Java統合開発環境といえば、「Eclipse」が有名だが、JavaEEを使用する場合は「NetBeans」の方が便利なので、「NetBeans」を使用する事にする。


<アーキテクチャの全体像>

項目名 説明
Api RESTクライアントからのリクエストを受け取り、リクエストに適切なLogic層の処理を呼び出す。Logic層からの結果を受け取り、リクエスト元に結果を返却する。
Logic層 Api層からの呼び出しで処理を開始する。データの処理を行う。また、DB操作が必要な場合は、Dao層を呼び出し処理を委譲する。
Dao層 Logic層からの呼び出しで処理を開始する。DB操作を行う。
DTO 複数のデータをまとめて管理するためのクラス
Entity DBのレコードに対応した、複数のデータをまとめて管理するためのクラス
RESTクライアント RESTサービスを使用するクライアント。PCのWebブラウザ、スマートフォンのWebブラウザ、スマートフォンのアプリ等がある。

次回から具体的に動くシステムの構築方法を紹介していく。

Enjoy Programing!!


<関連記事>
・REST風サービスをJavaEEで構築する方法01(導入編)[本記事]
REST風サービスをJavaEEで構築する方法02(雛形プロジェクト編)
REST風サービスをJavaEEで構築する方法03(RESTクライアント編)
REST風サービスをJavaEEで構築する方法04(各メソッド編)
REST風サービスをJavaEEで構築する方法05(パラメータの受け取り編)
REST風サービスをJavaEEで構築する方法06(JSON返却編1)
REST風サービスをJavaEEで構築する方法07(JSON返却編2)
REST風サービスをJavaEEで構築する方法08(Logic層編)
REST風サービスをJavaEEで構築する方法09(DB接続設定編)
REST風サービスをJavaEEで構築する方法10(DAO層編1)
REST風サービスをJavaEEで構築する方法11(DAO層編2)
REST風サービスをJavaEEで構築する方法12(DAO層編3)
REST風サービスをJavaEEで構築する方法13(SQLログ編)


<お勧め書籍>

わかりやすいJavaEEウェブシステム入門
JavaEEに関して基本的なことが分かり易く記述されている。
JavaEEに関する最初の1冊としてお勧めである。
Beginning Java EE 6 GlassFish 3で始めるエンタープライズJava
「金魚本」の愛称を持つJavaEEの教科書的な書籍である。
JavaEEを腰を据えて学びたい人にお勧めする1冊!!

iOSアプリ間でデータを共有する方法(Custom Paste Board)

今回は、iOSアプリ間で、データを共有する方法を紹介する。

通常、iOSアプリはアプリ毎に独立した領域にデータを格納するため、別アプリのデータを利用することは出来ない仕組みになっている。
セキュリティ面を考えると、この仕組みは非常に有用であるが、利便性で問題が生じる可能性がある。
今回紹介する「Custom Paste Board」を使用すれば、アプリ間でデータを共有することが可能となる。

iOSの「Paste Board」はWindowsの「クリップボード」の様なものであり、アプリ間で共有したデータ領域を使用することが出来る。
「Paste Board」は「General Paste Board」と「Custom Paste Board」がある。
「General Paste Board」は全アプリで共通の領域を使用するもので、全てのアプリに読み書き可能である。
一方「Custom Paste Board」は領域に「名前」をつけて使用するもので、その「名前」を知っているアプリのみが読み書き可能である。
どちらを使用するべきかは、共有するデータの性質によるが、特別な理由が無い限り、セキュリティ的に優れている「Custom Paste Board」を使用することをお勧めする。

UIPasteboard *pb = [UIPasteboard pasteboardWithName:@"lab.moonmt.CPSample" create:YES];
[pb setPersistent:YES];
[pb setValue:@"abcdefg" forPasteboardType:@"public.text"];

<解説>
1行目:
「lab.moonmt.CPSample」(第1引数)という「名前」の領域にアクセスするためのUIPasteboardを初期化している。
「名前」は任意の文字列を使用することができる。ただ、他のアプリと重複しない様な「名前」をつけないと、意図しない動きをする事があるので、注意が必要である。
第2引数は指定した「名前」の領域が存在しない場合の動きを指定する。今回は存在しない場合は、領域を作成して欲しいので「YES」を指定している。

2行目:
領域を永続的に保持するため「YES」を指定している。

3行目:
種別に文字列を指定して(第2引数)を指定して、「abcdefg」(第1引数)を値として設定している。


UIPasteboard *pb = [UIPasteboard pasteboardWithName:@"lab.moonmt.CPSample" create:YES];
[pb setPersistent:YES];
NSString *strVal = pb.string;

<解説>
1行目:
書き込み時と同様

2行目:
書き込み時と同様

3行目:
種別が文字列として設定された値を取得している。

Enjoy Programing!!

<お勧め書籍>

詳解 Objective-C 2.0 第3版
iOSアプリ開発技術者として仕事をするのであれば、必ず読んでおくべき書籍である。
筆者も何度も繰り返し精読している。

iOSアプリ開発でNSErrorの情報を出力する拡張NSLogを定義する方法

今回はNSLogを拡張して、NSErrorの情報を出力する識別子の定義方法を紹介する。

わざわざ新しい識別子を定義しなくても、NSErrorの情報をログに出力することは可能であるが、記述が少々長くなってしまう。
今回紹介する方法を用いれば、NSErrorの変数を直接引数に指定することができ、簡潔に記述することが出来る様になる。

<方法概要>
PCHファイル(<プロジェクト名-Prefix.pch>)に拡張したログを定義する。

(注意)
PCHファイルはXcode6から自動で生成されなくなった。
手動で作成する方法は「Xcode6でPCHファイルを追加する方法」を参照のこと。


<方法詳細>
PCHファイルに下記の定義を追加する。

#define ErrLog(error) NSLog(@"\n--- error detail ---\ndomain:%@\ncode:%ld\n%@\n", [error domain],(long)[error code],[[error userInfo] description])

解説:
「ErrLog」という識別子をNSLogを拡張して定義している。
先頭に「--- error detail ---」という文言を出力し、その後、「ドメイン」「コード」「ユーザ情報」を改行(\n)を挟みながら順に出力している。


<使用方法>
NSErrorの情報をログ出力する際は「ErrLog」を使用して行う。
サンプルコードを下記に示す。

//↓↓↓ 「ErrLog」の動作を確認するため「NSError」を手動で初期化している ↓↓↓

NSMutableDictionary *dic = [[NSMutableDictionary alloc] init];
[dic setObject:@"abcde" forKey:@"key1"];
[dic setObject:@"fghij" forKey:@"key2"];
    
NSError *error = [NSError errorWithDomain:@"ドメイン" code:-100 userInfo:dic];

//↑↑↑ 「ErrLog」の動作を確認するため「NSError」を手動で初期化している ↑↑↑
    
ErrLog(error);   //←ポイント


<実行結果>

2014-12-08 19:04:17.721 ErrLogSample[13022:80656] 
--- error detail ---
domain:ドメイン
code:-100
{
    key1 = abcde;
    key2 = fghij;
}

Enjoy Programing!!

<関連記事>
iOSアプリ開発でログにクラス名とメソッド名を出力する方法
iOSアプリ開発でログにログレベルを導入する方法
iOSアプリ開発でNSErrorの情報を出力する拡張NSLogを定義する方法(本記事)

<お勧め書籍>

詳解 Objective-C 2.0 第3版
iOSアプリ開発技術者として仕事をするのであれば、必ず読んでおくべき書籍である。
筆者も何度も繰り返し精読している。

iOSアプリ開発でログにログレベルを導入する方法

iOSアプリ開発でログを出力する場合「NSLog」を使用するが、Javaでログ出力に用いられるLog4Jのログレベルの様な考え方は存在しない。
今回はiOSアプリ開発でログにログレベルを導入する方法を紹介する。

<捕捉>
Log4Jのログレベルは、設定値によって出力するログを制御する方式である。
例えば、エラーより深刻なログを出力する設定にした場合、デバッグのために出力するログは出力されない仕組みである。
ログレベルの設定は、設定ファイルで簡単に変更することができ、単体テスト時は全てのログを出力し、結合テストの時は警告以上のログを出力し、サービスイン後はエラー以上のログを出力するといった制御が行える。

<方法概要>
1.PCHファイルにログレベルを定義する
2.PCHファイルに採用するログレベル定義する
3.PCHファイルにログレベル毎のログ出力を定義する

(注意)
PCHファイルはXcode6から自動で生成されなくなった。
手動で作成する方法は「Xcode6でPCHファイルを追加する方法」を参照のこと。

説明を簡単にするため、今回設定するログレベルは、下記の3レベルとする。


ログレベル説明
ログ無しログを出力しない
エラーエラー情報を出力する
デバッグデバッグ情報を出力する

<方法詳細>
1.PCHファイルにログレベルを定義する

<プロジェクト名>-Prefix.pchファイルにログレベルを定義する。
数値に意味は無く、他のログレベルと異なるのであれば、任意で良い。

//ログレベル定義
#define VAL_LOG_NONE    0       //ログ無し
#define VAL_LOG_ERROR   1       //エラー
#define VAL_LOG_DEBUG   2       //デバッグ


2.PCHファイルに採用するログレベル定義する

<プロジェクト名>-Prefix.pchファイルに採用するログレベル定義する。
「DEF_LOG_LEVEL」の右に手順1で定義したログレベルを記述することで、アプリが動作する時に採用するログレベルを定義する。
(下記の例はログレベル「エラー」を設定している)

//ログレベル設定
#define DEF_LOG_LEVEL VAL_LOG_ERROR


3.PCHファイルにログレベル毎のログ出力を定義する

<プロジェクト名>-Prefix.pchファイルにログレベル毎のログ出力を定義する。
マクロのif文で、手順2で設定した採用ログレベルにより、ログ出力の有無を定義する。
デバッグレベルで出力したいログ出力のために識別子「LogD」を定義し、エラーレベルで出力したいログ出力のために識別子「LogE」を定義する。

#if DEF_LOG_LEVEL == VAL_LOG_DEBUG      //↓↓↓ ログレベルが「デバッグ」の場合の定義

    #define LogD(format, ...) NSLog((@"<D>: "format), ##__VA_ARGS__)    //※1
    #define LogE(format, ...) NSLog((@"<E>: "format), ##__VA_ARGS__)    //※2

#elif DEF_LOG_LEVEL == VAL_LOG_ERROR   //↓↓↓ ログレベルが「エラー」の場合の定義

    #define LogD(format, ...)                                           //※3
    #define LogE(format, ...) NSLog((@"<E>: "format), ##__VA_ARGS__)    //※4

#elif DEF_LOG_LEVEL == VAL_LOG_NONE   //↓↓↓ ログレベルが「ログ無し」の場合の定義

    #define LogD(format, ...)                                           //※5
    #define LogE(format, ...)                                           //※6

#endif

※1:「LogD」という識別子を通常の「NSLog」出力に「」を付加して出力する
※2:「LogE」という識別子を通常の「NSLog」出力に「」を付加して出力する
※3:「LogD」という識別子は無視する
※4:「LogE」という識別子を通常の「NSLog」出力に「」を付加して出力する
※5:「LogD」という識別子は無視する
※6:「LogE」という識別子は無視する


自動生成されたPCHファイルか否かで、冒頭部分が異なる。
例は手動で生成したPCHファイルである。

#ifndef LogSample_LogSample_Prefix_pch
#define LogSample_LogSample_Prefix_pch

//ログレベル定義
#define VAL_LOG_NONE    0       //ログ無し
#define VAL_LOG_ERROR   1       //エラー
#define VAL_LOG_DEBUG   2       //デバッグ

//ログレベル設定
#define DEF_LOG_LEVEL VAL_LOG_ERROR

#if DEF_LOG_LEVEL == VAL_LOG_DEBUG      //↓↓↓ ログレベルが「デバッグ」の場合の定義

    #define LogD(format, ...) NSLog((@"<D>: "format), ##__VA_ARGS__)    //※1
    #define LogE(format, ...) NSLog((@"<E>: "format), ##__VA_ARGS__)    //※2

#elif DEF_LOG_LEVEL == VAL_LOG_ERROR   //↓↓↓ ログレベルが「エラー」の場合の定義

    #define LogD(format, ...)                                           //※3
    #define LogE(format, ...) NSLog((@"<E>: "format), ##__VA_ARGS__)    //※4

#elif DEF_LOG_LEVEL == VAL_LOG_NONE   //↓↓↓ ログレベルが「ログ無し」の場合の定義

    #define LogD(format, ...)                                           //※5
    #define LogE(format, ...)                                           //※6

#endif
#endif

<使用方法>
ログを出力する際は、「NSLog」ではなく、「LogD」および「LogE」を使用する。
サンプルコードを下記に示す。

- (void)viewDidLoad {
    [super viewDidLoad];
    
    LogD(@"デバッグレベルのログ");
    
    LogE(@"エラーレベルのログ");
    
    NSLog(@"NSLogによる出力");
}

<出力結果>
「#define DEF_LOG_LEVEL VAL_LOG_DEBUG」と設定した場合

2014-12-01 20:48:28.543 LogSample[4775:32404] <D>: デバッグレベルのログ
2014-12-01 20:48:28.544 LogSample[4775:32404] <E>: エラーレベルのログ
2014-12-01 20:48:28.545 LogSample[4775:32404] NSLogによる出力

「#define DEF_LOG_LEVEL VAL_LOG_ERROR」と設定した場合

2014-12-01 20:49:35.280 LogSample[4861:32974] <E>: エラーレベルのログ
2014-12-01 20:49:35.281 LogSample[4861:32974] NSLogによる出力

ソースコードを変更せずに、PCHファイルの変更で、デバッグレベルのログが出力されなくなった。

「#define DEF_LOG_LEVEL VAL_LOG_NONE」と設定した場合

2014-12-01 20:51:42.142 LogSample[4991:33935] NSLogによる出力

ソースコードを変更せずに、PCHファイルの変更で、デバッグレベル・エラーレベルのログが出力されなくなった。

<考察>
実用レベルのiOSアプリを作成する場合、ログ出力のためのコードが大量になることが少なくない。
リリース時に全てログ出力用のコードを削除しても良いが、アプリにトラブルが発生した時に原因調査に再びログ出力用コードを記述することになる。
今回紹介した方法を使用すれば、簡単にログ出力量を制御することができる。

Enjoy Programing!!

<関連記事>
iOSアプリ開発でログにクラス名とメソッド名を出力する方法
iOSアプリ開発でログにログレベルを導入する方法(本記事)
iOSアプリ開発でNSErrorの情報を出力する拡張NSLogを定義する方法

<お勧め書籍>

詳解 Objective-C 2.0 第3版
iOSアプリ開発技術者として仕事をするのであれば、必ず読んでおくべき書籍である。
筆者も何度も繰り返し精読している。