如何在Swift版Xcode项目中接入Google Fit API并实现用户认证
在Swift(Xcode)项目中接入Google Fit API的自动认证与Token获取步骤
一、前置配置(Google Cloud与项目)
- 打开Google Cloud控制台,选中目标项目,搜索并启用Google Fit API
- 进入「API和服务」→「凭据」,创建「OAuth客户端ID」,选择iOS类型,填入项目的Bundle ID,完成后下载
GoogleService-Info.plist文件 - 将
GoogleService-Info.plist拖入Xcode项目,确保勾选对应的项目目标(Target)
二、集成Google Sign-In SDK
方式1:CocoaPods
在Podfile中添加依赖:
pod 'GoogleSignIn'
执行pod install后,打开项目的.xcworkspace文件
方式2:Swift Package Manager
在Xcode中选择「File」→「Add Packages」,搜索官方GoogleSignIn包并添加到项目依赖
配置Info.plist
右键Info.plist→「Open As」→「Source Code」,添加以下配置($(REVERSED_CLIENT_ID)会自动从GoogleService-Info.plist读取对应值):
<key>CFBundleURLTypes</key> <array> <dict> <key>CFBundleURLSchemes</key> <array> <string>$(REVERSED_CLIENT_ID)</string> </array> </dict> </array> <key>LSApplicationQueriesSchemes</key> <array> <string>googlechrome</string> <string>googlechromes</string> </array>
三、实现登录与AccessToken自动获取
1. 初始化Google Sign-In
在AppDelegate的启动方法中完成初始化:
import GoogleSignIn func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool { guard let clientID = Bundle.main.object(forInfoDictionaryKey: "CLIENT_ID") as? String else { fatalError("GoogleService-Info.plist中缺少CLIENT_ID配置") } GIDConfiguration.shared.clientID = clientID return true }
如果使用SceneDelegate,需添加URL回调处理:
func scene(_ scene: UIScene, openURLContexts URLContexts: Set<UIOpenURLContext>) { guard let url = URLContexts.first?.url else { return } GIDSignIn.sharedInstance.handle(url) }
2. 发起带Fit权限的登录请求
在登录按钮的点击事件中触发登录,请求对应的数据权限:
// 根据需求调整权限范围,比如心率读取、活动数据读取 let fitScopes = [ "https://www.googleapis.com/auth/fitness.heart_rate.read", "https://www.googleapis.com/auth/fitness.activity.read" ] GIDSignIn.sharedInstance.signIn(with: GIDConfiguration.shared, presenting: self) { user, error in if let error = error { print("登录失败:\(error.localizedDescription)") return } guard let user = user, let accessToken = user.accessToken?.tokenString else { print("未获取到用户或AccessToken") return } // 存储Token,用于后续API请求 UserDefaults.standard.set(accessToken, forKey: "GoogleFitAccessToken") // 调用你的Google Fit API请求逻辑 self.callFitAPI(with: accessToken) }
3. 处理Token过期自动刷新
Google Sign-In SDK支持自动刷新Token,可在API请求返回401(未授权)时触发:
// 在API请求错误回调中处理401 if let httpResponse = response as? HTTPURLResponse, httpResponse.statusCode == 401 { GIDSignIn.sharedInstance.currentUser?.refreshTokensIfNeeded { refreshedUser, refreshError in if let newToken = refreshedUser?.accessToken?.tokenString { UserDefaults.standard.set(newToken, forKey: "GoogleFitAccessToken") self.callFitAPI(with: newToken) } } }
四、替换原有API请求的Token配置
将你已有的API请求代码中的硬编码Token替换为自动获取的Token:
func callFitAPI(with token: String) { let url = URL(string: "https://fitness.googleapis.com/fitness/v1/users/me/dataSources/derived:com.google.heart_rate.bpm:com.google.android.gms:merge_heart_rate_bpm/datasets/1681711200000000000-1681887600000000000") guard let requestUrl = url else { fatalError() } var request = URLRequest(url: requestUrl) request.httpMethod = "GET" request.setValue("application/json", forHTTPHeaderField: "Content-Type") // 替换为自动获取的AccessToken request.setValue("Bearer \(token)", forHTTPHeaderField: "Authorization") let task = URLSession.shared.dataTask(with: request) { (data, response, error) in if let error = error { print("请求错误:\(error)") // 处理Token过期逻辑 if let httpResponse = response as? HTTPURLResponse, httpResponse.statusCode == 401 { GIDSignIn.sharedInstance.currentUser?.refreshTokensIfNeeded { user, refreshError in if let newToken = user?.accessToken?.tokenString { self.callFitAPI(with: newToken) } } } return } if let response = response as? HTTPURLResponse { print("响应状态码:\(response.statusCode)") } if let data = data, let dataString = String(data: data, encoding: .utf8) { print("响应数据:\n \(dataString)") } } task.resume() }
关键注意事项
- 权限范围需与业务需求匹配:不同的Fit数据类型对应不同的scope,需确保请求的权限已在Google Cloud控制台的OAuth consent screen中声明
- 测试阶段需使用已添加到Google Cloud测试账号列表的邮箱,避免OAuth授权被拦截
- 确保
GoogleService-Info.plist中的CLIENT_ID、REVERSED_CLIENT_ID与控制台配置完全一致
内容的提问来源于stack exchange,提问作者DanLand
相关产品推荐
相关产品推荐

