Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

GoogleSignIn ios append to google sheets

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

like image 562
TommyBs Avatar asked Jan 02 '23 18:01

TommyBs


1 Answers

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!

like image 93
TommyBs Avatar answered Jan 05 '23 16:01

TommyBs