4

我正在尝试按照Google制作他们的 QuickStart 应用程序的教程来学习如何使用 Swift 进行 API 调用。我完全按照教程完成了这段代码

import GoogleAPIClient
import GTMOAuth2
import UIKit

class ViewController: UIViewController {

    private let kKeychainItemName = "Drive API"
    private let kClientID = "592019061169-nmjle7sfv8i8eahplae3cvto2rsj4gev.apps.googleusercontent.com"

    // If modifying these scopes, delete your previously saved credentials by
    // resetting the iOS simulator or uninstall the app.
    private let scopes = [kGTLAuthScopeDriveMetadataReadonly]

    private let service = GTLServiceDrive()
    let output = UITextView()

    // When the view loads, create necessary subviews
    // and initialize the Drive API service
    override func viewDidLoad() {
        super.viewDidLoad()

        output.frame = view.bounds
        output.editable = false
        output.contentInset = UIEdgeInsets(top: 20, left: 0, bottom: 20, right: 0)
        output.autoresizingMask = [.FlexibleHeight, .FlexibleWidth]

        view.addSubview(output);

        if let auth = GTMOAuth2ViewControllerTouch.authForGoogleFromKeychainForName(
            kKeychainItemName,
            clientID: kClientID,
            clientSecret: nil) {
            service.authorizer = auth
        }

    }

    // When the view appears, ensure that the Drive API service is authorized
    // and perform API calls
    override func viewDidAppear(animated: Bool) {
        if let authorizer = service.authorizer,
            let canAuth = authorizer.canAuthorize, canAuth {
            fetchFiles()
        } else {
            presentViewController(
                createAuthController(),
                animated: true,
                completion: nil
            )
        }
    }

    // Construct a query to get names and IDs of 10 files using the Google Drive API
    func fetchFiles() {
        output.text = "Getting files..."
        let query = GTLQueryDrive.queryForFilesList()
        query.pageSize = 10
        query.fields = "nextPageToken, files(id, name)"
        service.executeQuery(
            query,
            delegate: self,
            didFinishSelector: "displayResultWithTicket:finishedWithObject:error:"
        )
    }

    // Parse results and display
    func displayResultWithTicket(ticket : GTLServiceTicket,
                                 finishedWithObject response : GTLDriveFileList,
                                 error : NSError?) {

        if let error = error {
            showAlert("Error", message: error.localizedDescription)
            return
        }

        var filesString = ""

        if let files = response.files(), !files.isEmpty {
            filesString += "Files:\n"
            for file in files as! [GTLDriveFile] {
                filesString += "\(file.name) (\(file.identifier))\n"
            }
        } else {
            filesString = "No files found."
        }

        output.text = filesString
    }


    // Creates the auth controller for authorizing access to Drive API
    private func createAuthController() -> GTMOAuth2ViewControllerTouch {
        let scopeString = scopes.joinWithSeparator(" ")
        return GTMOAuth2ViewControllerTouch(
            scope: scopeString,
            clientID: kClientID,
            clientSecret: nil,
            keychainItemName: kKeychainItemName,
            delegate: self,
            finishedSelector: "viewController:finishedWithAuth:error:"
        )
    }

    // Handle completion of the authorization process, and update the Drive API
    // with the new credentials.
    func viewController(vc : UIViewController,
                        finishedWithAuth authResult : GTMOAuth2Authentication, error : NSError?) {

        if let error = error {
            service.authorizer = nil
            showAlert("Authentication Error", message: error.localizedDescription)
            return
        }

        service.authorizer = authResult
        dismissViewControllerAnimated(true, completion: nil)
    }

    // Helper for showing an alert
    func showAlert(title : String, message: String) {
        let alert = UIAlertController(
            title: title,
            message: message,
            preferredStyle: UIAlertControllerStyle.Alert
        )
        let ok = UIAlertAction(
            title: "OK",
            style: UIAlertActionStyle.Default,
            handler: nil
        )
        alert.addAction(ok)
        presentViewController(alert, animated: true, completion: nil)
    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }

}

我的问题是

import GoogleAPIClient

我收到错误“没有这样的模块 GoogleAPIClient ”,这对我来说似乎很奇怪,因为 GTMOAuth2 没有收到错误,即使它是我认为的同一个 Pod 的一部分(我是新手,所以我可能正在屠杀术语)。

通过研究这个问题,我发现应该用 GoogleAPIClientForREST 代替 GoogleAPIClient。GitHub 上的这个文档说只在代码中使用 GoogleAPIClientForREST 而不是 GoogleAPIClient,但我也遇到了同样的错误。

然后我想也许我可以通过对 Google 的教程进行一些更改来重新安装 Pod。在教程中,它说要在终端中执行此代码

$ cat << EOF > Podfile &&
> platform :ios, '7.0'
> use_frameworks!
> target 'QuickstartApp' do
>     pod 'GoogleAPIClient/Drive', '~> 1.0.2'
>     pod 'GTMOAuth2', '~> 1.1.0'
> end
> EOF
> pod install &&
> open QuickstartApp.xcworkspace

所以我想也许我可以在终端代码中将 GoogleAPIClient 替换为 GoogleAPIClientForREST ,但这让我遇到了同样的错误

在此处输入图像描述

正如您在屏幕截图中看到的,框架在左侧,但我仍然收到“没有这样的模块”错误。

嵌入式二进制文件和链接框架

在此处输入图像描述

搜索路径

在此处输入图像描述

在此处输入图像描述

我也在这里找到了一些我试图遵循的建议,但我并没有完全理解解释。尽管如此,我还是尝试了,并且这样做了(如果我做错了,请告诉我): 在此处输入图像描述

所以我试图让 GoogleAPIClient 或 GoogleAPIClientForREST 工作。谢谢您的帮助

4

4 回答 4

1

将此用于您的 Podfile:

platform :ios, '7.0'
use_frameworks!
target 'QuickstartApp' do
    pod 'GoogleAPIClientForREST/Drive', '~> 1.1.1'
    pod 'GTMOAuth2', '~> 1.1.0'
end

将您的导入更改为

import GoogleAPIClientForREST

然后按照此处的说明迁移项目: 从 GoogleAPIClient 迁移到 GoogleAPIClientForREST

这主要涉及通过一些单词交换将 GTL 调用更改为 GTLR 调用。例如,GTLServiceDrive变成GTLRDriveService

关于框架搜索路径,此图像显示了您可能需要更改的部分(注意它适用于我使用默认值):

在此处输入图像描述

搜索路径也可以是每个目标。这是显示应用程序目标和框架搜索路径的图像:

在此处输入图像描述

于 2017-01-09T08:10:00.343 回答
0

尽管我向您指出的解决方案可能适用于其他库,但它肯定会对您有所帮助。https://stackoverflow.com/a/25874524/5032645。如果我应该为您简化更多,请尝试让我知道。

于 2017-01-10T04:58:09.323 回答
0

因此,我也完全按照快速入门教程进行操作,并且能够使其正常工作。我在 GTMOAuth2 上方的框架搜索路径中移动了 GoogleAPIClientForRest:

截屏

成功包含模块后,我在代码中遇到了一个错误,我不得不更改这一行以使其构建和运行: if (result.files!.countif (result.files!.count > 0).

当然,现在谷歌已经弃用了 GTMOAuth2 并用 GTMAppAuth 取而代之,这使得这个应用程序毫无用处。

于 2017-03-22T21:49:14.273 回答
0

首先,查看 Quickstart 项目的 Frameworks 组中的 Pods_QuickstartApp.framework。如果它仍然是红色的,就像在你的屏幕截图上一样,那么 Xcode 没有构建它。如果 Xcode 没有构建框架,Xcode 无法为您导入它。

Cocoapods 构建了一个工作区,包括您的应用程序项目,以及将您的各个 pod 框架组装成一个更大框架的另一个项目。

似乎 cocoapods 构建了您的工作区,并且您确实打开了工作区而不是项目。那挺好的。

检查名为“Podfile”的文件的内容。它应该匹配:

platform :ios, '7.0'
use_frameworks!
target 'QuickstartApp' do
    pod 'GoogleAPIClient/Drive', '~> 1.0.2'
    pod 'GTMOAuth2', '~> 1.1.0'
end

如果没有,修复它,退出 Xcode,删除 .xcodeworkspace 文件,然后运行

pod install

从控制台。这可能会修复您的依赖关系,以便 Xcode 构建框架。

如果你确实让它编译,你的问题才刚刚开始。Google 已弃用嵌入式用户代理的 OAAuth 授权。

来自嵌入式用户代理的 OAAuth 授权已弃用

于 2017-01-12T01:59:32.797 回答