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]])
}
-
DriveApp.getFileById("xxxxx")
でGoogle Drive内にある対象ファイルのIDを取得します。※1 -
SpreadsheetApp.open(targetFileID)
で対象ファイルを取得します。 -
targetFile.getSheetByName("シート1")
で対象ファイル内の対象シートを取得します。 -
targetSheet.getLastRow() + 1
で現在入力済みの最終行を取得し1を足すことで次の空白行の行数を取得します。 -
targetSheet.getRange(targetRow, 1, 1, 4).setValues([["次郎", 28, 30, 1]])
で対象シート内の対象となる行(ここでは4行目)1列目のセルを起点に、1行分4列目までに次郎", 28, 30, 1
の値を書き込みます - デバッグするにはメニューバーにある
▷実行
を押します。- スプレッドシートの内容にアクセスする場合、初回はアクセス権限に関する表示が出るので対処します。
※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つ下の行)の取得までは
Writeする
と同じです。 -
JSON.parse(e.postData["contents"])
でPOSTされたデータそのものを取得します。 -
users
キーのバリューとしてuser
を格納した配列があり、ここではその1つ目を取得します。 -
setValues()
でPOSTされたuserデータの書き込みを行います。 -
デプロイ
を行い、WebAPIを発行します。
- こちらの手順を参考にして下さい。
すると、このような形でWebAPIが取得できます。
ここではusersには1つしかデータがありませんが、
当然一度に複数人のデータを送り全部書き込ませることも可能です。
内容の修正を行った際は忘れずにWebAPIの処理内容も更新してください。
iOSの実装
ここではiOSからGASのWebAPIへのアクセスを容易にするためにAlamofireとSwiftyJSONを用います。
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)
}
}
}
}
-
doPost(e)
で記載した各データと同じキーを用いて辞書型オブジェクトを作成し、配列に格納します。 -
AF.request(_, method: .post)
で上で取得したWebAPIにPOSTで通信を行います。また、パラメータを辞書型で渡し、エンコードをJSON形式にします。 - 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)
}