Artem Kirillov
Artem Kirillov

Reputation: 1398

How can I make basic writing via Google Sheets API?

On my way of learning Google Sheets API with Swift I wanted to write a single range to a spreadsheet.

Looking into Quickstart iOS Guide and Basic Writing examples I came with this code:

func constructAndSendAQuery() {
    let baseUrl = "https://sheets.googleapis.com/v4/spreadsheets"
    let spreadsheetId = "1FhbBdEvpcyHsdfgsdft65eDGHre2fLVki5ZolMmZaRs"
    let range = "Sales!A31:C31"
    let url = baseUrl + "/" + spreadsheetId + "/values/" + range
    let params = ["valueInputOption": "RAW"]
    let fullUrl = GTLUtilities.URLWithString(url, queryParameters: params)

    let body = GTLObject()
    body.JSON = ["majorDimension":"ROWS",
                 "values": ["One", "Two", "Three"]]

    service.fetchObjectByInsertingObject(body, 
                                         forURL: fullUrl,
                                         delegate: self, 
                                         didFinishSelector: #selector(ViewController.processTheResponse(_:finishedWithObject:error:)))
}

Don't know what I did wrong but I got the error message: "The requested URL wasn't found on this server".

Upvotes: 1

Views: 1949

Answers (3)

Sergey Neskoromny
Sergey Neskoromny

Reputation: 1208

If someone needs, I answered here on the similar question. You can use the GTLRSheets_ValueRange() object and GTLRSheetsQuery_SpreadsheetsValuesUpdate.query(withObject: to create or update any cell through Google Sheets API.

let service = GTLRSheetsService()
service.authorizer = GIDSignIn.sharedInstance().currentUser.authentication.fetcherAuthorizer()
service.apiKey = Constants.GOOGLE_SPEADSHEET_API_KEY
let rowIndex:Int = job.rowIndex
let range = "Employee List!C\(rowIndex):C\(rowIndex)"
let valueRange = GTLRSheets_ValueRange()
valueRange.range = "Employee List!C\(rowIndex):C\(rowIndex)"
valueRange.values = [[job.jobTitle!]]
valueRange.majorDimension = "COLUMNS"

let query = GTLRSheetsQuery_SpreadsheetsValuesUpdate.query(withObject: valueRange, spreadsheetId:  Constants.SPREAD_SHEET_ID, range: range)
query.valueInputOption = "USER_ENTERED"

service.executeQuery(query) { (ticket, response, error) in
    print(response)

}

Upvotes: 0

Artem Kirillov
Artem Kirillov

Reputation: 1398

As @sam-berlin mentioned I should have used fetchObjectByUpdatingObject instead of fetchObjectByInsertUpdating.

But there was one more little mistake/typo. In constructing JSON I lost a pair of square brackets and got an error about invalid value.

The working code looks like this:

func constructAndSendARequest() {

    let baseUrl = "https://sheets.googleapis.com/v4/spreadsheets"
    let spreadsheetId = "1FhbBdEvpsfgzb3Akn1opmru0iresdfglbki5ZMmZaRs"
    let range = "Sales!A3:D3"
    let url = baseUrl + "/" + spreadsheetId + "/values/" + range
    let params = ["valueInputOption": "RAW"]
    let fullUrl = GTLUtilities.URLWithString(url, queryParameters: params)


    let body = GTLObject()
    body.JSON = ["range": range,
                 "majorDimension": "ROWS",
                 "values": [["One", "Two", "Three"]]]

    service.fetchObjectByUpdatingObject(body, forURL: fullUrl, delegate: self, didFinishSelector: #selector(ViewController.processTheResponse(_:finishedWithObject:error:)))   
}

It's also possible to use service.fetchObjectByUpdatingObject(body, forURL: fullUrl, completionHandler: nil) and not process the response.

Upvotes: 1

Sam Berlin
Sam Berlin

Reputation: 3773

According to the GTLService code, fetchObjectByInsertUpdating does a POST, whereas this request requires a PUT. It seems that fetchObjectByUpdatingObject should do a PUT, so try that instead.

Upvotes: 0

Related Questions