如何使用Swift在iOS应用中实现Google Sheets读写更新
接入可行性结论
Swift 完全可以接入 Google Sheets API 实现数据读取、写入、更新全能力,官方文档未提供Swift专属实现示例不影响接入,落地有两种可选路径:一是集成Google官方为Apple平台推出的SDK(适配iOS、macOS等全Apple生态),二是拿到授权凭证后直接调用Sheets API的REST接口。
前置准备
- 进入Google Cloud控制台创建项目,在API库中搜索并启用Google Sheets API
- 创建对应类型的OAuth 2.0授权凭证:面向普通用户的端侧应用选择iOS应用类型,填写项目的Bundle ID;纯后端/脚本类Swift程序选择服务账号类型,下载生成的JSON密钥文件妥善保存
- 根据业务需求配置授权范围:需要读写改全能力选全量权限,仅需要读取数据就选只读权限,最小化授权粒度提升安全性
- 若选择SDK集成方式(推荐端侧应用使用),通过CocoaPods添加依赖即可:在Podfile中引入
GoogleAPIClientForREST/Sheets和GoogleSignIn两个依赖,执行pod install完成集成。
SDK方式核心操作实现
初始化服务与授权
首先完成Google账号登录授权流程,授权成功后将凭证注入Sheets服务实例,基础初始化代码如下:
import GoogleAPIClientForREST_Sheets import GoogleSignIn // 全局维护Sheets服务实例 private let sheetsService = GTLRSheetsService() // 在Google登录回调中完成授权注入,示例: // func signIn(_ signIn: GIDSignIn, didSignInFor user: GIDGoogleUser?, withError error: Error?) { // guard let user = user, error == nil else { return } // sheetsService.authorizer = user.authentication.fetcherAuthorizer() // }
读取表格数据
调用values.get接口读取指定范围的单元格内容,示例代码:
// 替换为目标表格的ID(从表格URL中可以获取) let spreadsheetId = "你的目标表格ID" // 替换为要读取的范围,格式为「工作表名称!起始单元格:结束单元格」,例:"销售表!A1:F20" let readRange = "工作表名!A1:D10" let query = GTLRSheetsQuery_SpreadsheetsValuesGet.query(withSpreadsheetId: spreadsheetId, range: readRange) sheetsService.executeQuery(query) { _, result, error in if let error = error { print("数据读取失败:\(error.localizedDescription)") return } guard let valueRange = result as? GTLRSheets_ValueRange, let rows = valueRange.values as? [[Any]] else { print("指定范围无有效数据") return } // rows为二维数组结构,第一层对应行,第二层对应每行的列数据 print("读取成功,数据:\(rows)") }
追加写入数据
需要在表格现有内容后新增行时,调用values.append接口,不会覆盖原有内容,示例代码:
let spreadsheetId = "你的目标表格ID" // 一般指定到对应工作表的首列即可,接口会自动定位到现有内容的最后一行之后 let appendRange = "工作表名!A:A" // 要写入的二维数组数据,每个子数组对应一行的列内容 let writeData = [ ["2024-05-01", "商品A", "12", "239"], ["2024-05-01", "商品B", "3", "599"] ] let valueBody = GTLRSheets_ValueRange() valueBody.values = writeData let query = GTLRSheetsQuery_SpreadsheetsValuesAppend.query( withObject: valueBody, spreadsheetId: spreadsheetId, range: appendRange ) // 配置写入规则:自动插入新行,不覆盖原有数据 query.insertDataOption = kGTLRSheets_InsertDataOption_InsertRows // 配置值解析规则:和用户手动在表格输入效果一致,自动识别公式、日期、数字格式 query.valueInputOption = kGTLRSheets_ValueInputOption_UserEntered sheetsService.executeQuery(query) { _, _, error in if let error = error { print("追加写入失败:\(error.localizedDescription)") return } print("数据追加成功") }
更新指定单元格数据
需要修改已有单元格内容时,调用values.update接口覆盖指定范围内容,示例代码:
let spreadsheetId = "你的目标表格ID" // 要更新的范围,需要和传入数据的行列数完全匹配,例:2行2列数据对应A2:B3范围 let updateRange = "工作表名!A2:B3" let updateData = [ ["修改后的A2内容", "修改后的B2内容"], ["修改后的A3内容", "修改后的B3内容"] ] let valueBody = GTLRSheets_ValueRange() valueBody.values = updateData let query = GTLRSheetsQuery_SpreadsheetsValuesUpdate.query( withObject: valueBody, spreadsheetId: spreadsheetId, range: updateRange ) query.valueInputOption = kGTLRSheets_ValueInputOption_UserEntered sheetsService.executeQuery(query) { _, _, error in if let error = error { print("数据更新失败:\(error.localizedDescription)") return } print("数据更新成功") }
无SDK的REST调用方式
如果不想引入SDK依赖,也可以在拿到有效OAuth 2.0的access_token后,直接构造原生HTTP请求调用接口:
- 读取数据:构造GET请求到Sheets API的values端点,路径中拼接表格ID和读取范围,请求头携带
Authorization: Bearer 你的有效access_token - 追加数据:构造POST请求到对应values路径,请求体传入JSON格式的二维数组数据,URL参数携带
valueInputOption=USER_ENTERED&insertDataOption=INSERT_ROWS - 更新数据:构造PUT请求到对应范围的values路径,请求体传入要更新的JSON数据,URL参数携带
valueInputOption=USER_ENTERED
注意事项:如果使用服务账号模式授权,必须将服务账号的邮箱地址添加到目标表格的共享列表中,授予对应查看/编辑权限,否则会返回403无权限错误。端侧SDK会自动处理access_token过期刷新逻辑,手动调用REST接口需要自行实现token刷新逻辑。
内容的提问来源于stack exchange,提问作者Abdelrahman Hafrag
相关产品推荐
相关产品推荐

