Swift3 使用Google Drive REST API避免Swift 3完成处理程序中的降级

Swift3 使用Google Drive REST API避免Swift 3完成处理程序中的降级,swift3,google-drive-api,downcast,completionhandler,Swift3,Google Drive Api,Downcast,Completionhandler,我正在Swift 3应用程序中使用Google Drive REST API。使用GTLRDriveService的executeQuery方法执行查询。此方法接受类型为GTLRServiceCompletionHandler?的完成块,该完成块依次声明为 public typealias GTLRServiceCompletionHandler = (GTLRServiceTicket, Any?, Error?) -> Swift.Void 由于此声明,第二个参数必须向下转换为块内的

我正在Swift 3应用程序中使用Google Drive REST API。使用
GTLRDriveService
executeQuery
方法执行查询。此方法接受类型为
GTLRServiceCompletionHandler?
的完成块,该完成块依次声明为

public typealias GTLRServiceCompletionHandler = (GTLRServiceTicket, Any?, Error?) -> Swift.Void
由于此声明,第二个参数必须向下转换为块内的适当类型。例如:

let createPermissionQuery = GTLRDriveQuery_PermissionsCreate.query(
    withObject: permission, fileId: toShare.id)

...

driveService.executeQuery(createPermissionQuery) { (ticket, result, error) in
    if (error == nil) {
        // need to downcast result to GTLRDrive_Permission
        let permission = result as! GTLRDrive_Permission
        ...
    }
}
第二个参数始终为特定类型,完全由传递给
executeQuery
的特定查询决定。例如,如果传递的是
gtldrivequery\u PermissionsCreate
的实例,则第二个参数(如果查询成功)的类型始终为
gtldrive\u Permission
。但是,如果我试图将
result
声明为
any?
以外的任何类型,则代码将无法编译

在目标C中,可以使用特定于查询的类型指定完成块。例如(改编自):


有没有办法避免这种沮丧情绪?(我这样问是出于无知;我对斯威夫特有点陌生。)如果我写自己的库,我会以不同的方式设计方法签名,但这是谷歌的库,我有点拘泥于它们提供的东西。可能是Google代码之上的某种扩展或层?

您可以指定一个扩展,该扩展包装Google execute方法,接受泛型并强制转换到块中的泛型类型。这基本上只是对您正在做的事情的一个相当抽象的描述,但是对于所有类型,您的扩展都将被设计为覆盖。

您可以指定一个扩展来包装Google execute方法,接受泛型并在块中强制转换为您的泛型类型。这基本上只是对您正在做的事情的一个相当抽象的描述,但是对于所有类型,您的扩展都将被设计为涵盖。

不是答案,但是如果库遇到了阻碍,那么可能值得考虑直接调用http REST API并解析生成的JSON。到目前为止,我对谷歌库的经验(我承认,我没有尝试过Swift)是,它们对硬的东西(例如节流、重试、分页、可恢复的上传)没有多大帮助,所以你需要自己编写代码。这不是答案,但如果库碍事,可能值得考虑直接调用HTTPRESTAPI并解析生成的JSON。到目前为止,我对谷歌库的经验(我承认,我还没有尝试过Swift)是,它们对硬的东西(例如节流、重试、分页、可恢复的上传)没有多大帮助,所以你无论如何都需要自己编写代码。
GTLRDriveQuery_PermissionsCreate *createPermissionQuery =
    [GTLRDriveQuery_PermissionsCreate queryWithObject:permission
                                               fileId:fileId];
...

[driveService executeQuery:createPermissionQuery
         completionHandler:^((GTLRServiceTicket *ticket,
                              GTLRDrive_Permission *permission,
                              NSError *error) {
    if (error == nil) {
        // work directly with permission
        ...
    }
}];