鯛’s PG blog

プログラミングに関するあれこれを書きます

【Swift4】Alamofire を使ってAPIを呼び出してみた

SwiftのHTTPネットワークライブラリ「Alamofire」を使うと
API叩いたりするのが簡単!とのことなので、使ってみた。

環境:
Xcode 9.2
Swift 4
iOS 11.2 (テスト端末のOS)
CocoaPods (Alamofire インストールに使用)

Xcode を起動し、新規プロジェクトを作成

1. Create a new Xcode project を選択
2. Single View App を選択
3. Product Name に適当に名前を入力(例:AlamofireSampleApp)
4. Alamofire インストールのため、いったんXcodeを閉じる

Alamofire のインストール

ここでは、CocoaPods を使ってインストールする。

CocoaPods 自体のインストール方法は以下のリンク先がわかりやすかった。
"CocoaPodsの環境構築" という部分を参照
qiita.com

ターミナルを起動し、cd コマンドでプロジェクトディレクトリの直下に移動

cd {workspaceのディレクトリ} /{プロジェクト名のディレクトリ}
ex. cd Desktop/workspace/AlamofireSampleApp

ディレクトリ移動できたら、以下コマンドで PodFile を作成

pod init

作成されたPodfile の中身を編集。以下を追記する。

pod 'Alamofire'


f:id:taiyaki_dos:20171216113324p:plain

上記図に記載されている '~> 4.5' というのは、
Alamofire のGitHubページ内、"Installation" 部分に記載されていたので、マネしてみた。

github.com


PodFileの編集が終わったら、以下コマンドを実行

pod install
Swift のコードを書いて動かしてみる

{プロジェクト名}.xworkspace からプロジェクトを開く

f:id:taiyaki_dos:20171216114033p:plain


とりあえずボタンを1つ用意する

f:id:taiyaki_dos:20171216114554p:plain


ボタンをコードに接続する

@IBAction func getWeather(_ sender: UIButton) {
}


今回使うAPIはこれ
weather.livedoor.com


東京のID "130010" で問い合わせしてみる
http://weather.livedoor.com/forecast/webservice/json/v1?city=400040

URLの宛先がhttpなので、明示的に許可してやらないとエラーになる
やり方は以下リンク先がわかりやすかった

qiita.com


コード内で、Alamofire を使って通信する処理を記述する
※エラーハンドリングは省略

import Alamofire

〜中略〜

    @IBAction func getWeather(_ sender: UIButton) {
        // 天気情報APIにアクセスする
        Alamofire.request("http://weather.livedoor.com/forecast/webservice/json/v1?city=130010").responseJSON {response in
            print("Request: \(String(describing: response.request))")
            print("Response: \(String(describing: response.response))")
            print("Result: \(String(describing: response.result))")
            
            if let json = response.result.value {
                print("JSON: \(json)")  // serialized json response
            }
            
            if let data = response.data, let utf8Text = String(data: data, encoding: .utf8) {
                print("Data: \(utf8Text)")  // original server data as UTF8 String
            }
        }
    }


Alamofireを使わなくてもHTTP通信は可能だが、使ったら楽になるよ、という話。

LINEのチャットボットを作ってみた 〜Google Apps Script のコード〜

別記事「LINEのチャットボットを作ってみた 〜導入〜」
taiyaki-dos.hatenablog.com

で省略した、Google Apps Script(以降GAS) のコードを載せていこうと思う。

 

GAS側で行いたい処理は以下

1. 受け取ったメッセージを元にGoogle スプレッドシート内を検索
2. 該当の「名前」「住所」「Google MapのURL+住所」を取得
3. 結果を返す


事前作業として、以下を済ませておくこと。

  • LINE Developers の Channel基本設定 で 「アクセストークン」を発行
  • 住所が記載されているスプレッドシートのファイルキーを取得


ファイルキーはスプレッドシートを開いたときのURLのうち△の部分
例)https://docs.google.com/spreadsheets/d/△△△/edit#gid=0

var CHANNEL_ACCESS_TOKEN = 'xxxxxx';
var ADDRESS_FILE_KEY = 'ooooooo';

function doPost(e) {
  var reply_token= JSON.parse(e.postData.contents).events[0].replyToken;
  if (typeof reply_token === 'undefined') {
    return;
  }
  // レスポンスメッセージの設定
  var response_message = setResponseMessage(e);

  // メッセージ送信のための設定
  var url = 'https://api.line.me/v2/bot/message/reply';
  UrlFetchApp.fetch(url, {
    'headers': {
      'Content-Type': 'application/json; charset=UTF-8',
      'Authorization': 'Bearer ' + CHANNEL_ACCESS_TOKEN,
    },
    'method': 'post',
    'payload': JSON.stringify({
      'replyToken': reply_token,
      'messages': [{ 
        'type': 'text',
        'text': response_message,
      }],
    }),
  });
  return ContentService.createTextOutput(JSON.stringify({'content': 'post ok'})).setMimeType(ContentService.MimeType.JSON);
}

 
事前作業で取得しておいた「アクセストークン」「ファイルキー」を上記ソース内の"CHANNEL_ACCESS_TOKEN"、"ADDRESS_FILE_KEY"に設定する。

送り返すメッセージを生成しているのは、

  // レスポンスメッセージの設定
  var response_message = setResponseMessage(e);


で、setResponseMessage() の中で受け取ったメッセージを元に住所検索を行う。

/*
 * レスポンスメッセージ設定処理
 */
function setResponseMessage(req) {
  var res = '';

  // ユーザーの入力文字列を取得
  var user_message = JSON.parse(req.postData.contents).events[0].message.text;

  // 入力文字列から住所を検索
  var address_str = getAddress(user_message);

  // 〜中略〜

  var count = address_str.length;

  if (count < 3) {
    for (var i=0; i<count; i++) {
      // 住所をURIエンコード
      e_url = encodeURIComponent(address_str[i][1]);
      res = res + address_str[i][0] + '\n' + address_str[i][1] + '\n' + google_map_url + e_url + '\n';
    }
  } else {
    for (var i=0; i<count; i++) {
      // 社寺名だけをレスポンスメッセージにセット
      res = res + address_str[i][0] + '\n';
      if (i >= 19) {
        res = res + '他多数...';
        break;
      }
    }
  }
  // メッセージの返却  
  return res;
}

/*
 * スプレッドシート内の検索
 */
function getAddress(str) {
  // スプレッドシートの取得
  var spreadsheet = SpreadsheetApp.openById(ADDRESS_FILE_KEY);
  // 取得したシートのデータを二次元配列に格納
  var dat = spreadsheet.getDataRange().getValues();
  // 返却用配列
  var result = [];
  
  // 検索
  for (var i=1,len=dat.length; i<len; i++) {
    if (dat[i][0].indexOf(str) !== -1) {
    //  return dat[i][1];
      result.push([dat[i][0], dat[i][1]]);
    }
  }
  return result;
}


スプレッドシート内の検索を行っているのは getAddress() 内。
直接スプレッドシートを参照、検索しても良いのだが、一度配列に入れてからループで回したほうが処理速度が早いらしいのでこんなことをしている。

  // 取得したシートのデータを二次元配列に格納
  var dat = spreadsheet.getDataRange().getValues();

LINEのチャットボットを作ってみた 〜導入〜

LINEのボットが無料で作れるとのことで、興味本位でチャットボットを作ってみた。

使用したのは、

・LINE ビジネスアカウント

・LINE Messaging API

Google Apps Script (通称GAS)

Google スプレッドシート

 

それぞれ簡単にコメント

 

・LINE ビジネスアカウント 

 LINE Messaging API を使うために登録が必要。

 "一般アカウント" であれば個人でも登録可能で、「フリープラン」なら無料

at.line.me

 

・LINE Messaging API

 LINEと自分のサービス(GASのプログラム)間でメッセージのやり取りをする

 のに使用。

https://developers.line.me/ja/services/messaging-api

 

Google Apps Script

 Google のアカウントを持っていれば使用可能なサービス。

 スクリプトの言語はJavaScript をベースにしている。

qiita.com

 

Google スプレッドシート

 GAS同様、Googleのアカウントを持っていれば使用可能なサービス。

 GASに比べれば、こちらのほうが使ったことがある方も多いだろう。

 Excel みたいなやつ、といえば大体通じる。

 

で、どんなのを作ったのかというと。

 

「京都の神社やお寺の住所を答えてくれるチャットボット」

 

百聞は一見にしかず。まずは下の写真をご覧あれ。

f:id:taiyaki_dos:20171130155243p:plain

 

伏見稲荷」とメッセージを送ると、Bot が以下の情報を返す。

  • 名前
  • 住所
  • google map で住所検索するURL

 

●仕組み 

1. LINEでBotに対してメッセージを送る

2. LINE Messaging API を利用し、GASがメッセージを受信

3. GAS側で、受け取ったメッセージを元にGoogle スプレッドシート内を検索

(※Google スプレッドシートはデータベースの代わりとして使用)

4. 該当の「名前」「住所」「Google MapのURL+住所」を取得

5. 結果を返す 

 

●もう少し詳しく  

"Google スプレッドシートはデータベースの代わりとして使用" と記載したが、

実際に見てもらうとこんな感じ。

f:id:taiyaki_dos:20171130161507p:plain

 

Google Apps Script の実際のコードを載せると長くなるので別記事を参照

taiyaki-dos.hatenablog.com

 

GAS側では、受け取ったメッセージで スプレッドシートの"name" 列 をLIKE 検索(文字列が含まれていればヒット扱い)して、ヒットした行の "name" と "address" を取得する、といったつくりになっている。

 

なお、複数行ヒットしたら複数行返すようにはしたが、例えば 神社の "神" なんて送られてきた日には100件超ヒットしてしまい、レスポンスがエラいことになるので

少し制御を入れてある。

 

以下のQRコード、もしくはボタンから友達追加すると、実際に触ってもらえるので、興味があればどうぞ。

無料プランなので 友達は 50人まで という制限がある。万が一追加できなかったら申し訳ない。。。

友だち追加

こいつが追加されるはず。

f:id:taiyaki_dos:20171130165733p:plain