3
Help us understand the problem. What are the problem?

posted at

updated at

iOSアプリからスプレッドシートにデータを書き込む

iOSアプリからスプレッドシートにデータを書き込みたい時が人生にはあります。その方法です。

大まかな流れ

iOSからスプレッドシートのデータを書くためには、スプレッドシート側にGAS(Google Apps Script)を実装する必要があります。GASでスプレッドシートをWriteするPOSTを実装し、iOSからそこ目掛けて通信する実装をすれば完成です。

GASの実装

スプレッドシートの「シート1」シートに下記のようなデータがあるものとします。

スプレッドシートメニューのツール>スクリプトエディタを選択します。

するとApps Scriptエディタが開きます。

ここに処理を実装していきます。

Writeする

スプレッドシートにデータを書き込む方法は以下の通りです。

function myFunction(){
    var targetFileID = DriveApp.getFileById("xxxxx")
    var targetFile = SpreadsheetApp.open(targetFileID)
    var targetSheet = targetFile.getSheetByName("シート1")

    var targetRow = targetSheet.getLastRow() + 1
    targetSheet.getRange(targetRow, 1, 1, 4).setValues([["次郎", 28, 30, 1]])
}
  1. DriveApp.getFileById("xxxxx")でGoogle Drive内にある対象ファイルのIDを取得します。※1
  2. SpreadsheetApp.open(targetFileID)で対象ファイルを取得します。
  3. targetFile.getSheetByName("シート1")で対象ファイル内の対象シートを取得します。
  4. targetSheet.getLastRow() + 1で現在入力済みの最終行を取得し1を足すことで次の空白行の行数を取得します。
  5. targetSheet.getRange(targetRow, 1, 1, 4).setValues([["次郎", 28, 30, 1]])で対象シート内の対象となる行(ここでは4行目)1列目のセルを起点に、1行分4列目までに次郎", 28, 30, 1の値を書き込みます
  6. デバッグするにはメニューバーにある▷実行を押します。

※1:ファイルIDはURLの https://docs.google.com/spreadsheets/d/xxxxx/edit#gid=0 のxxxxxにあたる部分です

実行後、スプレッドシート側に書き込みが行われていることが確認できます。

POSTを実装する

GASでWebAPIを実装できます。GASの中でPOSTならdoPost(e)を定義し実装します。これをウェブアプリとして公開するとWebAPIが発行され外部からアクセスできるようになります。

doPost(e)

スプレッドシートにWebAPI経由で書き込む方法は以下の通りです。

//POSTされるデータ形式
postData: {
    'contents' : '{"users": [{"name": "次郎", "age": "28", "count": "30", "error": "1"}]}'
}

前提として、GASのdoPost(e)で送られたデータは、e.postData["contents"]に格納されることになっています。これを踏まえ、doPost内の処理を実装していきます。

function doPost(e){
    var targetFileID = DriveApp.getFileById("xxxxx")
    var targetFile = SpreadsheetApp.open(targetFileID)
    var targetSheet = targetFile.getSheetByName("シート1")
    var targetRow = targetSheet.getLastRow() + 1

    var json = JSON.parse(e.postData["contents"])
    var user = json["users"][0]

    targetSheet.getRange(targetRow, 1, 1, 4).setValues([[user.name, user.age, user.count, user.error]])
}
  1. 書き込む行(データ最下行の1つ下の行)の取得まではWriteすると同じです。
  2. JSON.parse(e.postData["contents"])でPOSTされたデータそのものを取得します。
  3. usersキーのバリューとしてuserを格納した配列があり、ここではその1つ目を取得します。
  4. setValues()でPOSTされたuserデータの書き込みを行います。
  5. デプロイを行い、WebAPIを発行します。

すると、このような形でWebAPIが取得できます。

ここではusersには1つしかデータがありませんが、
当然一度に複数人のデータを送り全部書き込ませることも可能です。

内容の修正を行った際は忘れずにWebAPIの処理内容も更新してください。

iOSの実装

ここではiOSからGASのWebAPIへのアクセスを容易にするためにAlamofireSwiftyJSONを用います。

import UIKit
import Alamofire
import SwiftyJSON

class ViewController: UIViewController {

    let url = "https://script.google.com/macros/s/xxx/exec" //上記で取得したWebAPI

    @IBOutlet weak var name: UITextField! 
    @IBOutlet weak var age: UITextField!
    var count: Int!
    var error: Int!

    override func viewDidLoad() {
        //何かしら下記2つの値を取得する処理など
        count = 45
        error = 3
    }

    @IBAction func onTap(_ sender: Any) {

        //POSTするデータの生成
        var user: Dictionary<String, Any> = [:]
        user["name"] = name.text //香織
        user["age"] = age.text //24
        user["count"] = self.count
        user["error"] = self.error

        var users: Array<Dictionary<String, Any>> = []
        users.append(user)

        //POST処理
        AF.request(url,
                   method: .post,
                   parameters: ["users": users],
                   encoding: JSONEncoding.default,
                   headers: nil
        ).responseJSON{ (response) in
            switch response.result {
                case .success(let elm):
                    print("success")

                case .failure(let error):
                    print("error", error)
            }
        }
    }
}
  1. doPost(e)で記載した各データと同じキーを用いて辞書型オブジェクトを作成し、配列に格納します。
  2. AF.request(_, method: .post)で上で取得したWebAPIにPOSTで通信を行います。また、パラメータを辞書型で渡し、エンコードをJSON形式にします。
  3. POSTを行うと、GAS側からのレスポンスが来るので受け口を用意します。
    • .success(let elm)のelmにはGAS側のdoPostに実装したreturnの値が入ります。必要に応じて実装してください。
    • .failure(let error)はPOSTに失敗した場合に実行されます。

これをシュミレータで実行し、ボタンを押すとこうなります。

まとめ

iOSアプリからスプレッドシートにデータを書き込む方法をまとめました。スプレッドシートのデータを読み込む方法もまとめましたので、よろしければこちらもご覧ください。

おまけ

doPost(e)を実装する際、POSTデータを修正する度にGASとiOSを直しiOSシミュレータからアクセスするのは面倒です。
GAS側で下記のように実装し実行する関数をdebugDoPostにすることで、擬似的に外部からのPOSTを実装できるので効率的です。

function debugDoPost(){
  const e = {
    postData: {
      'contents' : '{"users": [{"name": "次郎", "age": "28", "count": "30", "error": "1"}]}'
    }
  }
  doPost(e)
}
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
Sign upLogin
3
Help us understand the problem. What are the problem?