I'm currently working on an iOS app that needs to write to a google sheet owned by the user who is signed in.
To sign in the user I'm using the GoogleSignIn
pod and for appending to the google sheet I'm using the GoogleAPIClientForREST/Sheets
pod.
I can get the user to sign in ok, but for the life of me I can't seem to write to a sheet due to authentication errors. Every example I've found on SO ( like Updating specific row in iOS Swift using Google SpreadSheet API) and the like states to use an fetcherAuthorizer()
method of the current user and assign it to the service.authorizer
, however this won't even compile with the following error value of type 'GIDAuthentication?' has no member 'fetcherAuthorizer'
So for my podfile I have:
pod 'GoogleSignIn'
pod 'GoogleAPIClientForREST/Sheets'
My AppDelegate didFinishLaunchingWithOptions
has the following:
GIDSignIn.sharedInstance().clientID = "clientIdHere"
GIDSignIn.sharedInstance()?.scopes.append(kGTLRAuthScopeSheetsSpreadsheets)
GIDSignIn.sharedInstance()?.scopes.append(kGTLRAuthScopeSheetsDrive)
GIDSignIn.sharedInstance()?.delegate = self
And when I try to write to the sheet I use:
let service = GTLRSheetsService()
// following line errors with authorizer not being a property of the service
//variable and fetchAuthorizer() not being a method on authentication
service.authorizer = GIDSignIn.sharedInstance().currentUser.authentication.fetcherAuthorizer()
let spreadsheetId = "id"
let range = "Sheet1"
let valueRange = GTLRSheets_ValueRange.init();
valueRange.values = [
["Hello", "World"]
]
let query = GTLRSheetsQuery_SpreadsheetsValuesAppend
.query(withObject: valueRange, spreadsheetId:spreadsheetId, range:range)
query.valueInputOption = "USER_ENTERED"
service.executeQuery(query) { (ticket, any, error) in
if let error = error {
print(error)
}
print(any)
print(ticket)
}
I've tried using a standard URLSession with an authorization
header such as
let data = ["range":"Sheet1!A1:D1", "majorDimension":"ROWS", "values": ["123","123","123","123"]] as [String : Any]
urlRequest.addValue("application/json", forHTTPHeaderField: "content-type")
urlRequest.addValue(GIDSignIn.sharedInstance()!.currentUser.authentication.accessToken, forHTTPHeaderField: "authorization")
urlRequest.httpBody = try! JSONSerialization.data(withJSONObject: data, options: .sortedKeys)
let session = URLSession.shared.dataTask(with: urlRequest) { (data, response, error) in
if let error = error {
print(error)
} else {
print(String(data: data!, encoding: .utf8))
}
}.resume()
but this also fails telling me I need to pass an access token along. Can anyone advise how this should work? I just seem to be going round in circles with the docs and all the other examples I can find seem to use methods/properties that don't seem to exist!
These are the current pod versions I'm using
Using GTMOAuth2 (1.1.6)
Using GTMSessionFetcher (1.2.0)
Using GoogleAPIClientForREST (1.3.6)
Using GoogleSignIn (4.2.0)
Using GoogleToolboxForMac (2.1.4)
And I only ever call the method to write to the sheet when I know I have a user.
Thanks
For anyone else facing similar issues, I managed to get this working with the GoogleAPIClient.
The issue is to do with Swift silently dropping imports for forward declarations.
So you need a bridging header as follows
#import <GTMSessionFetcher/GTMSessionFetcher.h>
#import <GTMSessionFetcher/GTMSessionFetcherService.h>
and this needs to be imported before the APIClient framework in whatever class you use this in.
e.g
import GTMSessionFetcher
import GoogleAPIClientForREST
import GoogleSignIn
you should then be able to access the authorizer
property and fetcherAuthorizer()
method!
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With