Help us understand the problem. What is going on with this article?

スプレッドシートとgoogle apps scriptで簡易APIを作ってalamofireからget/postする

More than 5 years have passed since last update.

google apps scriptにはContent Serviceというクラスがあって、GUIを伴うwebアプリケーションを作れたり、REST APIを作れたりします。今回は、GET/POSTができる簡易的なAPIを作って、alamofireとスプレッドシート間でjsonデータのやりとりをしてみたいと思います。

サーバ側がまだ準備できてないとか、サーバ用意するほどのものでもない場合に便利かと思います。

こんな感じ

やりたいこと

  • GET用シートからデータをalamofireで取得
  • POST用シートにデータをalamofire経由で追加

※ 但し、alamofireからのpost時に画像は含められません(ContentServiceがmulti-partに非対応のため)

ソース

[google apps script]
https://github.com/mitolog/GASEasyAPI

[iOS]
https://github.com/mitolog/GASEasyAPI-alamofire-client-sample

手順

スプレッドシートを作成

下記の感じで作成します。

getシート

  • 1行目を項目名にして、2行目からデータを入れます
  • シート名は get にしておきます

Screen Shot 2015-05-02 at 14.14.11.png

postシート

  • 1行目を項目名にしておきます。2行目からはデータが入ってきます
  • シート名は post にしておきます

Screen Shot 2015-05-02 at 16.44.38.png

※ 今回は便宜上postとgetのパラメータを同じにしています。

スクリプトを作成

スプレッドシートのメニューで、ツール > スクリプトエディタ... を選択します。その後、プロジェクト名、ファイル名をそれぞれ適宜設定します。

Get.gs
/**
 * Get API
 * @return json object
 */
function doGet(e) {

  var getSheet = getFirstMatchedFileAndSheet(g_filename, g_getSheetName);
  if(!getSheet) return;

  // First row must be parameter names
  var cells = getSheet.getDataRange().getValues();
  var paramNames = [];
  if(!cells || cells.length <= 1){
    return;
  }

  paramNames = cells[0];
  cells.shift();

  var userLists = [];
  cells.forEach(function(aLine, idx){
    var aDic = {};
    aLine.forEach(function(elem, elemIdx){
      aDic[paramNames[elemIdx]] = elem;
    });
    userLists.push(aDic);
  });

  var result = {};
  result['data'] = userLists;

  return ContentService.createTextOutput(JSON.stringify(result))
    .setMimeType(ContentService.MimeType.JSON);

}
Post.gs
/**
 * Post API
 * @return json object
 */
function doPost(e) {

  if(!e) return;

  var paramStr = e.postData['contents'];
  // debug
//  var paramStr = '{"Users": [{"id": "1", "created": "2015-05-02 07:32:01 +0000", "name": "人造人間1号"},{"id": "2", "created": "2015-05-02 07:32:01 +0000", "name": "人造人間2号"}]}';
  var params = JSON.parse(paramStr);

  var targetSheet = getFirstMatchedFileAndSheet(g_filename, g_postSheetName);
  if(!targetSheet) return;

  // First row must be parameter names
  var dataRng = targetSheet.getDataRange();
  var cells = dataRng.getValues();
  if(!cells || cells.length < 1){
    return;
  }

  // Make data array[][] to plot spreadsheet range
  var paramNames = cells[0];
  var dataAry = [];
  params["Users"].forEach(function(aParamDic, idx){
    var plotLine = [];
    paramNames.forEach(function(paramName, pnIdx){
      var val = aParamDic[paramName];
      plotLine[pnIdx] = (val) ? val : "";
    });
    dataAry.push(plotLine);
  });

  // Append data after last data line
  dataRng.offset(dataRng.getNumRows(),0,dataAry.length).setValues(dataAry);

  var result = {};
  result['data'] = dataAry;

  return ContentService.createTextOutput(JSON.stringify(result))
    .setMimeType(ContentService.MimeType.JSON);

}
Common.gs
var g_filename = 'GASAPIDemo';
var g_getSheetName = 'get';
var g_postSheetName = 'post';
var g_mimeTypeContainStr = 'spreadsheet';

/**
 * Driveの中から最初に見つかった、targetFileNameのスプレッドシートを取得する
 * @return SpreadSheet 
 */
function getFirstMatchedSpreadSheet(targetFileName)
{
  var resFile = null;

  var files = DriveApp.getFilesByName(targetFileName);
  while (files.hasNext()) {
    var file = files.next();
    if(file.getMimeType().indexOf(g_mimeTypeContainStr) != -1){
      resFile = file;
      break;
    }
  }
  return SpreadsheetApp.open(resFile);
}

/**
 * Driveの中から最初に見つかった、filenameファイルのsheetnameシート取得する
 * @return Sheet
 */
function getFirstMatchedFileAndSheet(filename, sheetname)
{
  var targetFile = getFirstMatchedSpreadSheet(filename);
  if(!targetFile){
    return null;
  }

  var targetSheet = targetFile.getSheetByName(sheetname);
  if(!targetSheet){
    return null;
  }
  return targetSheet;
}

アプリの実行権限を得る

Google Apps Scriptからスプレッドシートを利用するには、オーソライズが必要なので、まずは、下記のように実行して権限を取得します。

Screen Shot 2015-05-02 at 15.56.31.png

Screen Shot 2015-05-02 at 15.56.44.png

Screen Shot 2015-05-02 at 15.57.06.png

APIを公開する

下記の手順で公開します。とりあえずスクショをぺたぺた貼っていきます。

新しい版(APIのversionになります)を登録

Screen Shot 2015-05-02 at 17.43.47.png
Screen Shot 2015-05-02 at 17.44.05.png

ウェブアプリとして導入

Screen Shot 2015-05-02 at 17.44.22.png

Screen Shot 2015-05-02 at 17.44.34.png

公開したいバージョンを選択、アプリケーションの実行ユーザは Meにしておいて、アクセスできるユーザーは、全員(匿名ユーザーを含む)にしておきます。

Screen Shot 2015-05-02 at 17.44.50.png

最後に出てきた画面のURLをコピーして置きます。

iOSアプリ側

ソースを落とす

$ git clone git@github.com:mitolog/GASEasyAPI-alamofire-client-sample.git GASEasyAPIAlamoSmaple
$ cd GASEasyAPIAlamoSmaple
$ pod install

さっきコピーしておいた、urlをコピペ

下記の部分になります。

ViewController.swift
struct AppConsts {

    struct HttpGetUrl {
        static let UserList = ""
    }

    struct HttpPostUrl {
        static let RegUser = ""
    }
}

以上!

感想 & 注意点

  • multipartのpostもできたら尚良いな
  • APIの公開urlはredirectされているので、AFNetworkingとかAlamofire以外で独自でやる際はredirect処理を忘れずに
  • iOS側でエラーがかえってくる場合、jsonのパースで落ちる場合は、スプレッドシートの処理がおかしい可能性があるので、function doPost(e)のeにダミーの値をいれてためすといいです。
  • eの内部構造が公式ドキュメントで解説されていない?ので、困った...(Event Objectのページにも無いし...)
  • realmとかcoredataとかのモデル部分もXcodeのプロジェクトに入れてアプリのテンプレートとして持っとくと使い回しできて良いのかも
mito_log
ベトナム・ハノイ拠点の個人デベロッパ。東南アジア向けに素敵なサービスと文化を作るべく模索中。ベトナムで1年半農業。newbie skateboarder、ハノイITもくもく会毎週土曜朝9時頃 → https://bit.ly/2Oe9Ehk
http://mitolab.hatenablog.com/
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした