在给定的ViewController上应用脚本API错误

在给定的ViewController上应用脚本API错误

问题描述:

有没有人经历过这个API并想出了它? 这是我第三次尝试按照本指南进行工作在给定的ViewController上应用脚本API错误

我正在使用本指南的swift版本。

Google Apps Script Guide

,它总是给我同样的错误。

import UIKit 

class ViewController: UIViewController { 

    private let kKeychainItemName = "Google Apps Script Execution API" 
    private let kClientID = "493692471278-3mf6bo212flgjopl06hrjfeepphe70h4.apps.googleusercontent.com" 
    private let kScriptId = "Mj0RNm2ZtohFurieBLPwnxYAb4Jnnku4P" 
    // If modifying these scopes, delete your previously saved credentials by 
    // resetting the iOS simulator or uninstall the app. 
    private let scopes = ["https://www.googleapis.com/auth/drive"] 

    private let service = GTLService() // error Use of unresolved identifier 'GTLService' 


    let output = UITextView() 

    // When the view loads, create necessary subviews 
    // and initialize the Google Apps Script Execution 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 = UIViewAutoresizing.FlexibleHeight | 
      UIViewAutoresizing.FlexibleWidth 
     // error*** Binary operator '|' cannot be applied to two 'UIViewAutoresizing'  operands 


     view.addSubview(output); 
     // Error**Use of unresolved identifier 'GTMOAuth2ViewControllerTouch' 
     if let auth = GTMOAuth2ViewControllerTouch.authForGoogleFromKeychainForName(
      kKeychainItemName, 
      clientID: kClientID, 
      clientSecret: nil) { 
       service.authorizer = auth 
     } 

    } 

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

    // Calls an Apps Script function to list the folders in the user's 
    // root Drive folder. 
    func callAppsScript() { 
     output.text = "Getting folders..." 
     let baseUrl = "https://script.googleapis.com/v1/scripts/\(kScriptId):run" 
     let url = GTLUtilities.URLWithString(baseUrl, queryParameters: nil) 
     // error ** Use of unresolved identifier 'GTLUtilities' 
     // Create an execution request object. 
     var request = GTLObject() 
     // Error** Use of unresolved identifier 'GTLObject' 

     request.setJSONValue("getFoldersUnderRoot", forKey: "function") 

     // Make the API request. 
     service.fetchObjectByInsertingObject(request, 
      forURL: url, 
      delegate: self, 
      didFinishSelector: "displayResultWithTicket:finishedWithObject:error:") 
    } 

    // Displays the retrieved folders returned by the Apps Script function. 
    func displayResultWithTicket(ticket: GTLServiceTicket, 
     finishedWithObject object : GTLObject, 
     error : NSError?) { 
      if let error = error { 
       // The API encountered a problem before the script 
       // started executing. 
       showAlert("The API returned the error: ", 
        message: error.localizedDescription) 
       return 
      } 

      if let apiError = object.JSON["error"] as? [String: AnyObject] { 
       // The API executed, but the script returned an error. 

       // Extract the first (and only) set of error details and cast as 
       // a Dictionary. The values of this Dictionary are the script's 
       // 'errorMessage' and 'errorType', and an array of stack trace 
       // elements (which also need to be cast as Dictionaries). 
       let details = apiError["details"] as! [[String: AnyObject]] 
       var errMessage = String(
        format:"Script error message: %@\n", 
        details[0]["errorMessage"] as! String) 

       if let stacktrace = 
        details[0]["scriptStackTraceElements"] as? [[String: AnyObject]] { 
         // There may not be a stacktrace if the script didn't start 
         // executing. 
         for trace in stacktrace { 
          let f = trace["function"] as? String ?? "Unknown" 
          let num = trace["lineNumber"] as? Int ?? -1 
          errMessage += "\t\(f): \(num)\n" 
         } 
       } 

       // Set the output as the compiled error message. 
       output.text = errMessage 
      } else { 
       // The result provided by the API needs to be cast into the 
       // correct type, based upon what types the Apps Script function 
       // returns. Here, the function returns an Apps Script Object with 
       // String keys and values, so must be cast into a Dictionary 
       // (folderSet). 
       let response = object.JSON["response"] as! [String: AnyObject] 
       let folderSet = response["result"] as! [String: AnyObject] 
       if folderSet.count == 0 { 
        output.text = "No folders returned!\n" 
       } else { 
        var folderString = "Folders under your root folder:\n" 
        for (id, folder) in folderSet { 
         folderString += "\t\(folder) (\(id))\n" 
        } 
        output.text = folderString 
       } 
      } 
    } 

    // Creates the auth controller for authorizing access to Google Apps Script Execution API 
    private func createAuthController() -> GTMOAuth2ViewControllerTouch { 
    // Error** Use of undeclared type 'GTLServiceTicket'  let scopeString = " ".join(scopes) // Error* 'join' is unavailable: call the 'joinWithSeparator()' method on the sequence of elements 
     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 Google Apps Script Execution API 
    // with the new credentials. 
    func viewController(vc : UIViewController, 
     finishedWithAuth authResult : GTMOAuth2Authentication, error : NSError?) 
    // Error** Use of undeclared type 'GTMOAuth2Authentication' { 

      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 = UIAlertView(
      title: title, 
      message: message, 
      delegate: nil, 
      cancelButtonTitle: "OK" 
     ) 
     alert.show() 
    } 

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

} 

我觉得很难相信谷歌会作出指导,并使其不适用于当前版本的xcode。它甚至在他们的指南底部说,它已于2016年2月更新。

希望看看过去是否有人按照本指南运气。

是否有另一个这个谷歌API的快速指南?

预先感谢您。

+0

什么错误?你提供的信息越多,你就越容易得到答案? – user3069232

+0

好吧,它告诉我复制和粘贴视图控制器,它给了我错误。假设我在此之前执行了这些步骤,是否将由于从objective-c转换为swift而成为问题? –

1)看起来你没有得到头文件。你需要一个Bridging-Header.h。该步骤在快速入门中省略;请参阅Google云端硬盘快速入门以了解您需要采取的步骤。 2)你可以注释掉下面这行,似乎没有必要。

output.autoresizingMask = UIViewAutoresizing.FlexibleHeight | 
    UIViewAutoresizing.FlexibleWidth 

3)这些更改将解决编译问题。我发现在解决编译问题后,它不会链接并在手机上运行。 快速入门指南使用Xcode的“链接二进制库”链接GTL.framework与您的应用程序。我改为使用Cocoapods(https://cocoapods.org/pods/Google-API-Client)安装它,然后能够运行我的应用程序。