Swift集成Google Drive后首次登录成功后出现限额超标错误排查
解决Google Drive集成后后续请求触发未授权日限额错误的问题
看起来你遇到的问题核心是后续请求没有携带有效的授权信息,导致请求被判定为未认证请求,触发了Google Drive的未认证请求日限额。结合你的代码,我帮你梳理几个关键的遗漏点和修复方案:
1. 每个VC单独创建GTLRDriveService实例导致授权丢失
你在GDriveFileListingVC里新建了一个独立的GTLRDriveService实例,但这个实例并没有继承你在登录成功后设置的authorizer——只有DocumentUploadVC里的service有授权信息,后续页面的请求完全是未认证状态,自然会触发未授权配额限制。
修复方案:统一管理Drive服务实例
创建一个单例类来全局管理你的Drive服务,确保所有页面都使用同一个带授权的实例:
class DriveServiceManager { static let shared = DriveServiceManager() let service = GTLRDriveService() private init() {} // 保证单例唯一 }
然后在登录成功的回调里,把授权信息绑定到这个全局service:
func sign(_ signIn: GIDSignIn!, didSignInFor user: GIDGoogleUser!, withError error: Error!) { if let error = error { self.showAlert("Error", message: error.localizedDescription) DriveServiceManager.shared.service.authorizer = nil } else { // 将授权信息赋值给全局service DriveServiceManager.shared.service.authorizer = user.authentication.fetcherAuthorizer() listFiles() } }
最后在GDriveFileListingVC里使用这个全局service发起请求:
func showGoogleDriveData() { let query = GTLRDriveQuery_FilesList.query() query.pageSize = 10 // 使用全局共享的service实例 DriveServiceManager.shared.service.executeQuery(query, delegate: self, didFinish: #selector(displayResultWithTicket(ticket:finishedWithObject:error:)) ) }
2. 缺少登录状态的持久化与静默登录逻辑
你的代码没有处理App重启后的登录状态恢复,导致每次启动App都需要重新登录;如果用户直接进入文件列表页面,此时service没有授权,同样会触发未认证请求。
修复方案:添加静默登录逻辑
在AppDelegate的didFinishLaunchingWithOptions里,添加恢复之前登录状态的代码:
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool { // Initialize google sign-in var configureError: NSError? GGLContext.sharedInstance().configureWithError(&configureError) assert(configureError == nil, "Error configuring Google services: \(String(describing: configureError))") // 尝试静默恢复之前的登录状态 GIDSignIn.sharedInstance().restorePreviousSignIn { user, error in if let user = user { // 把授权信息恢复到全局service DriveServiceManager.shared.service.authorizer = user.authentication.fetcherAuthorizer() // 可选:如果需要,直接跳转到文件列表页面 } else { // 没有历史登录状态,需要用户手动触发登录 } } return true }
同时,在登录页面(比如DocumentUploadVC)的初始化阶段,记得设置需要的权限范围:
override func viewDidLoad() { super.viewDidLoad() GIDSignIn.sharedInstance().delegate = self GIDSignIn.sharedInstance().uiDelegate = self // 明确设置需要的Drive权限范围 GIDSignIn.sharedInstance().scopes = [kGTLRAuthScopeDriveReadonly] }
3. 额外的控制台配置检查
除了代码问题,也可以确认下开发者控制台的配置是否正确:
- 确保Google Drive API已经在Google Cloud Console中启用
- 确认创建的OAuth 2.0客户端ID是iOS类型,且Bundle ID和你的项目完全匹配
- 检查
GoogleService-Info.plist是否正确添加到项目中,包含正确的CLIENT_ID和REVERSED_CLIENT_ID
4. 可选:添加授权状态检查
为了避免无授权的请求,你可以在发起Drive请求前先检查授权状态:
func showGoogleDriveData() { guard DriveServiceManager.shared.service.authorizer != nil else { self.showAlert("未授权", message: "请先登录Google账号") // 跳转到登录页面 return } let query = GTLRDriveQuery_FilesList.query() query.pageSize = 10 DriveServiceManager.shared.service.executeQuery(query, delegate: self, didFinish: #selector(displayResultWithTicket(ticket:finishedWithObject:error:)) ) }
内容的提问来源于stack exchange,提问作者Krutika Sonawala
相关产品推荐
相关产品推荐

