Sr John Oliver Sr John Oliver - 3 years ago 507
iOS Question

Can't run service.executeQuery() for Google Drive REST API due to GTLRServiceCompletionHandler

I've been trying to figure out how to upload a file from iOS to Google Drive via a Swift app that I am programming. I'm very new to Swift and Objective-C but for the purposes of the app that I am working on, it has to be done in Swift. I followed the Google Drive API tutorials to get it setup within my app and I was able to successfully log in and list files from my Google Drive folder(s) as mentioned here in this tutorial.

Since getting that to work, I have been trying upload a file from an iOS to Google Drive. Since there was no Swift code on the Google Drive API documentation showing me how to do this, I tried to closely follow this Objective-C code listed here for Basic Upload.

My current code is as follows:

let fileData: Data? = FileManager.default.contents(atPath: "files/photo.jpg")
let metadata = GTLRDrive_File.init() = "photo.jpg"
let uploadParameters = GTLRUploadParameters(data: fileData!, mimeType: "image/jpeg")
uploadParameters.shouldUploadWithSingleRequest = true
let query = GTLRDriveQuery_FilesCreate.query(withObject: metadata, uploadParameters: uploadParameters)
query.fields = "id"
self.service.executeQuery(query, completionHandler: (GTLRServiceTicket, Any?, Error?) -> Void) {
return {
(ticket: GTLRServiceTicket, object: Any?, error: Error?) -> Void in

I had found another SO post that tried to solve a problem somewhat similar to this by looking at the typealias. When I pull up the type alias for GTLRServiceCompletionHandler, this is what I get:

public typealias GTLRServiceCompletionHandler = (GTLRServiceTicket, Any?, Error?) -> Swift.Void

This is the default function signature for service.executeQuery that shows up:

service.executeQuery(query: GTLRQueryProtocol, completionHandler: GTLRServiceCompletionHandler?)

The current compiler error that I get before being able to run the code says that the argument labels for completionHandler do not match any available overload methods. I've been working on this for so long (and am not that familiar with Swift) that I'm not entirely sure what I can do to get this to work anymore. Any help would be greatly appreciated.

Answer Source

You may be misunderstanding the purpose of completionHandler, or else having trouble with the syntax for this kind of call. You provide a closure that will be executed when the query completes. It takes three arguments of types (GTLRServiceTicket, Any?, Error?) and returns nothing (Void).

You can also use trailing-closure syntax, meaning that you don't need to label the completionHandler argument.

Putting that together you get something like

self.service.executeQuery(query) { (ticket:GTLRServiceTicket, object:Any?, error:Error?) in
    // Put your completion code here
Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download