Error al conectarse a la API de Google Drive (Swift 5)
Quiero conectarme a la API de Google Drive en mi aplicación para mostrar una lista de archivos de usuario y poder descargarlos en el dispositivo. Estoy siguiendo este ejemplo Integrar Google Drive en la aplicación iOS
Conecté el SDK de Google y autoricé correctamente al usuario. Sin embargo, no puedo obtener la lista de sus archivos de ninguna manera. Sigo recibiendo el siguiente error:
"Se superó el límite diario de uso no autenticado. El uso continuo requiere registrarse".
Revisé mi aplicación y configuración en Google Console muchas veces, hice todo paso a paso, pero aún así no pude resolver este problema. Alguien ha experimentado el mismo problema?
Mi código y capturas de pantalla:
//class AppDelegate...
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
GIDSignIn.sharedInstance().clientID = "Me client ID"
return true
}
//class myVC: GIDSignInDelegate...
override func viewDidLoad() {
super.viewDidLoad()
GIDSignIn.sharedInstance().presentingViewController = self
GIDSignIn.sharedInstance().delegate = self
GIDSignIn.sharedInstance().scopes = [kGTLRAuthScopeDrive]
GIDSignIn.sharedInstance().restorePreviousSignIn()
}
func sign(_ signIn: GIDSignIn!, didSignInFor user: GIDGoogleUser!,
withError error: Error!) {
if let error = error {
print("Google autorization error: \(error.localizedDescription)")
return
}
guard let token = user.authentication.accessToken else { return }
SourceAuthorizationStateManager.shared.addAuthorizedSource(.googleDrive)
let fullName = user.profile.name
print("Google authorization successful. User name: \(fullName ?? "Error: no user name")\nUser token: \(token)")
}
//class GoogleDriveFileListSource...
private var fileListTicket: GTLRServiceTicket?
var files: [FileModelProtocol] {
guard let files = fileList?.files else { return [] }
return files.map { GoogleDriveFileModel($0) }
}
lazy var driveService: GTLRDriveService = {
let service = GTLRDriveService()
service.shouldFetchNextPages = true
service.isRetryEnabled = true
return service
}()
func fetchFileList(path: String?, _ completion: @escaping () -> Void) {
let query = GTLRDriveQuery_FilesList.query()
query.fields = "kind,nextPageToken,files(mimeType,id,kind,name,webViewLink,thumbnailLink,trashed)"
fileListTicket = driveService.executeQuery(query,
completionHandler: { [weak self] (_, resultObject, error) in
if let error = error {
debugPrint("driveService.executeQuery error: \(error.localizedDescription)")
return
}
guard let self = self,
let fileList = resultObject as? GTLRDrive_FileList else { return }
self.fileList = fileList
self.fileListTicket = nil
completion()
})
}
Respuestas
"Se superó el límite diario de uso no autenticado.
Significa que no estás autorizado. Las llamadas a las API de Google que exponen datos privados del usuario deben incluir un token de portador de encabezado de autorización que contenga un token de acceso.
Parece que estás enviando algo llamado token de usuario que no creo que sea lo mismo que configurar el encabezado de autorización.
intento de depuración
Tenga en cuenta que nunca he tenido un dispositivo Apple. No soy un desarrollador de Ios o rápido. He trabajado con las API y la biblioteca de Google durante años.
Por lo que puedo ver, estás llamando
fileListTicket = driveService.executeQuery(query,
Mientras el tutorial está siguiendo las llamadas
self.service.executeQuery(query)
No cambiaste la delicada configuración
GIDSignIn.sharedInstance().delegate = self
GIDSignIn.sharedInstance().uiDelegate = self
¿Porque lo cambiaste?
Resuelto. Gracias a todos los que ayudaron. Todo lo que tenía que hacer era transferir el estado de autenticación del usuario a driveService e importar GTMSessionFetcher a mis archivos.
var googleUser: GIDGoogleUser?
class myVC: GIDSignInDelegate {
...
func sign(_ signIn: GIDSignIn!, didSignInFor user: GIDGoogleUser!,
withError error: Error!) {
if let error = error {
print("Google autorization error: \(error.localizedDescription)")
return
}
guard let token = user.authentication.accessToken else { return }
SourceAuthorizationStateManager.shared.addAuthorizedSource(.googleDrive)
googleUser = user //Here I have saved the current user
let fullName = user.profile.name
print("Google authorization successful. User name: \(fullName ?? "Error: no user name")\nUser token: \(token)")
}
}
class GoogleDriveFileListSource {
...
lazy var driveService: GTLRDriveService = {
let service = GTLRDriveService()
if let user = googleUser {
service.authorizer = user.authentication.fetcherAuthorizer() //Here I passed the status
}
service.shouldFetchNextPages = true
service.isRetryEnabled = true
return service
}()
}
Ahora que el código no se ve muy bien, pensaré en cómo mejorarlo. Pero esto ya funciona, obtengo la lista de archivos del usuario.