【Swift5】Googleスプレッドシート(GAS)でセルの情報を取得する/POST通信で更新する【Xcode12】
前回の記事はこちらです。
Googleスプレッドシートのデータを取得する
static func getShareSheetData(){
let mainAPIHost: String = "https://script.google.com/macros/s/---/exec" // デプロイしたURLを設定してください。
var request = URLRequest(url: URL(string: mainAPIHost)!)
request.httpMethod = "GET"
let task = URLSession.shared.dataTask(with: request) { data, response, error in
guard let jsonData = data else { return }
struct Result: Codable {
var deckRecipes: [deckRecipe]
}
do {
let deckRecipes = try JSONDecoder().decode(Result.self, from: jsonData)
DataManager.shared.convertShareDeckModel(list: deckRecipes.deckRecipes)
print(deckRecipes)
} catch {
print(error.localizedDescription)
}
}
task.resume()
}
struct deckRecipe: Codable {
var id: String
var decktitle: String
var deckrecipeid: String
var createdate: String
var memo: String
var isfav: String
}
ちなみにGoogleスプレッドシートはこのようになっています。
列名(カラム名)がカスタムモデルと対応していますね。
ちなみにGoogleスプレッドシートのスクリプトでは以下のようにGetを書いております。
function doGet(e){
var result = JSON.stringify({'deckRecipes': getVitalDatas()});
return ContentService.createTextOutput(result).setMimeType(ContentService.MimeType.JSON);
}
多分'deckRecipes'がSwift側と一致する必要がありそうです。(エラー起こりまくりでした)
Googleスプレッドシートのデータを更新(追加する)
まずGoogleスプレッドシート側のスクリプトを追加します。
function doPost(e) {
var jsonString = e.postData.getDataAsString();
var data = JSON.parse(jsonString);
var id = data.id;
var decktitle = data.decktitle;
var deckrecipeid = data.deckrecipeid;
var createdate = data.createdate;
var memo = data.memo;
var isfav = data.isfav;
// シート取得
var ss = SpreadsheetApp.openById(SpreadsheetApp.getActiveSpreadsheet().getId());
var sheet = ss.getSheetByName("sheets1");
// データ入力
sheet.appendRow([id, decktitle, deckrecipeid, createdate, memo, isfav]);
}
ちなみに今回は1個でのデータ登録・追加の挙動しかないので、1件ずつの登録・追加を想定しています。(Swiftの送信側で配列で送っているので、多分2件以上の一括登録も行けます)
Swiftでの書き方はこちらです。
func requestAsyncJson(model : DeckModel,
success: @escaping (Dictionary<String, Any>) -> (), // 通信成功時のクロージャ
failure: @escaping (Error) -> ()){ // 通信失敗時のクロージャ
// URLはデプロイしたURLを使ってください。
guard let url = URL(string: "https://script.google.com/macros/s/---/exec") else {
return failure(NetworkError.invalidURL)
}
var request = URLRequest(url: url) //Requestを生成
request.httpMethod = "POST" // 何も設定しないとGETリクエストになるがコードのサンプルのため、明示的に書いている。
request.addValue("application/json", forHTTPHeaderField: "Content-Type")
let params:[String:Any] = [
"id": model.duckRecipeId,
"decktitle": model.deckTitle,
"deckrecipeid": model.duckRecipeId,
"createdate": model.createDate,
"memo": model.memo,
"isfav": "OK",
]
request.httpBody = try! JSONSerialization.data(withJSONObject: params, options: .prettyPrinted)
URLSession.shared.dataTask(with: request, completionHandler: {data , response, error in
if let error = error {
print(error.localizedDescription)
failure(error)
return
}
guard let data = data,
let response = response as? HTTPURLResponse else {
print("データもしくはレスポンスがnilの状態です")
failure(NetworkError.unknown)
return
}
if response.statusCode == 200 {
do {
// 本当は値を取り出して成否など見るのですが、WebAPI側で返却していないので空のDictを返却しています。
// 詳細は後述の記事見てください。
let dict: Dictionary<String, Any> = ["isSuccess": "isSuccess"]
// コールバックを行う
success(dict)
} catch let error {
failure(error)
}
} else {
print("statusCode:\(response.statusCode)")
failure(NetworkError.unknown)
}
}).resume()
}
呼び出し側の処理はこうです。
APIRequest().requestAsyncJson(model: self.deckModel! , success: {(dictionary) in
// 通信成功時のクロージャ
print(dictionary)
self.showAlertView(message: "通信に成功しました。")
}) { (error) in
// 通信失敗時のクロージャ
print(error)
self.showAlertView(message: "通信に失敗しました。")
}
以前書いた記事はこちらです。