如何访问应用程序特定的文件夹并将其用于备份或某些应用程序特定的数据?迅速

萨兹德·伊卡巴尔

我想创建一个应用程序,其中某些类型的数据将同步到应用程序特定文件夹中的google驱动器,并且进一步可以访问以检索数据并将其填充到应用程序中。如果以某种方式丢失了用户手机,而用户又使用了另一台手机,并且当用户登录相同的Google帐户时,则应获取该数据。

我的问题是我不知道要执行的操作步骤,我可以通过Google驱动器创建应用程序文件夹,并且通过驱动器向最终用户显示 在此处输入图片说明

现在,当我尝试在其中插入数据时出现范围错误。我使用的代码是:

import Foundation
import GoogleAPIClientForREST

enum GDriveError: Error {
    case NoDataAtPath
 }

class ATGoogleDrive {

private let service: GTLRDriveService

init(_ service: GTLRDriveService) {
    self.service = service
}

public func listFilesInFolder(_ folder: String, onCompleted: @escaping (GTLRDrive_FileList?, Error?) -> ()) {
    search(folder) { (folderID, error) in
        guard let ID = folderID else {
            onCompleted(nil, error)
            return
        }
        self.listFiles(ID, onCompleted: onCompleted)
    }
}

private func listFiles(_ folderID: String, onCompleted: @escaping (GTLRDrive_FileList?, Error?) -> ()) {
    let query = GTLRDriveQuery_FilesList.query()
    query.pageSize = 100
    query.q = "'\(folderID)' in parents"

    service.executeQuery(query) { (ticket, result, error) in
        onCompleted(result as? GTLRDrive_FileList, error)
    }
}

public func uploadFile(_ folderName: String, data: Data, MIMEType: String, onCompleted: ((String?, Error?) -> ())?) {

    search("config.json") { (folderID, error) in

        if let ID = folderID {
            self.upload(ID, data: data, MIMEType: MIMEType, onCompleted: onCompleted)
        } else {
            self.createFolder(folderName, onCompleted: { (folderID, error) in
                self.upload("", data: data, MIMEType: MIMEType, onCompleted: onCompleted)
            })
        }
    }
}

private func upload(_ parentID: String, data: Data, MIMEType: String, onCompleted: ((String?, Error?) -> ())?) {

    let metadata: GTLRDrive_File = GTLRDrive_File()
    metadata.name = "config.json"
    metadata.parents = ["appDataFolder"]

    let uploadParameters: GTLRUploadParameters = GTLRUploadParameters(data: data, mimeType: "application/json") 
    uploadParameters.shouldUploadWithSingleRequest = true;
    let query: GTLRDriveQuery_FilesCreate = GTLRDriveQuery_FilesCreate.query(withObject: metadata, uploadParameters: uploadParameters)//[GTLRDriveQuery_FilesCreate queryWithObject:metadata
     query.fields = "id"
     self.service.executeQuery(query) { (ticket, fileN, error) in
        print(ticket)
        print(fileN)
        print(error)
        if let f = fileN as? GTLRDrive_File {
            if (error == nil) {
                print("File ID %@", f.identifier);
            } else {
                print("An error occurred: %@", error);
            }
        } 
      }
    }

public func listFromAppFolder(_ parentID: String, data: Data, MIMEType: String, onCompleted: ((String?, Error?) -> ())?) {
    let file = GTLRDrive_File()
    file.name = "\(Date().timeIntervalSince1970)"
    file.parents = ["appfolder"]

    let uploadParams = GTLRUploadParameters.init(data: data, mimeType: MIMEType)
    uploadParams.shouldUploadWithSingleRequest = true

    let query = GTLRDriveQuery_FilesCreate.query(withObject: file, uploadParameters: uploadParams)
    query.fields = "id"

    self.service.executeQuery(query, completionHandler: { (ticket, file, error) in
        print(ticket)
        print(file)
        print(error)
        onCompleted?((file as? GTLRDrive_File)?.identifier, error)
    })
}

public func download(_ fileID: String, onCompleted: @escaping (Data?, Error?) -> ()) {
    let query = GTLRDriveQuery_FilesGet.queryForMedia(withFileId: fileID)
    service.executeQuery(query) { (ticket, file, error) in
        onCompleted((file as? GTLRDataObject)?.data, error)
    }
}

public func search(_ fileName: String, onCompleted: @escaping (String?, Error?) -> ()) {
    let query = GTLRDriveQuery_FilesList.query()
    query.pageSize = 1
    query.q = "name contains '\(fileName)'"

    service.executeQuery(query) { (ticket, results, error) in
        onCompleted((results as? GTLRDrive_FileList)?.files?.first?.identifier, error)
    }
}

public func createFolder(_ name: String, onCompleted: @escaping (String?, Error?) -> ()) {
    let file: GTLRDrive_File = GTLRDrive_File()
    file.name = "config.json"
    file.parents = ["appfolder"]
    let query = GTLRDriveQuery_FilesCreate.query(withObject: file, uploadParameters: nil)
    query.fields = "id"

    service.executeQuery(query) { (ticket, folder, error) in
        onCompleted((folder as? GTLRDrive_File)?.identifier, error)
    }
}

public func delete(_ fileID: String, onCompleted: ((Error?) -> ())?) {
    let query = GTLRDriveQuery_FilesDelete.query(withFileId: fileID)
    service.executeQuery(query) { (ticket, nilFile, error) in
        onCompleted?(error)
    }
  }
 }

并用于登录并在下面的类中使用

import UIKit
import GoogleSignIn
import GoogleAPIClientForREST

class ViewController: UIViewController {

@IBOutlet weak var resultsLabel: UILabel!

fileprivate let service = GTLRDriveService()
private var drive: ATGoogleDrive?

override func viewDidLoad() {
    super.viewDidLoad()

    setupGoogleSignIn()

    drive = ATGoogleDrive(service)

    view.addSubview(GIDSignInButton())
}

private func setupGoogleSignIn() {
    GIDSignIn.sharedInstance().delegate = self
    GIDSignIn.sharedInstance().uiDelegate = self
    GIDSignIn.sharedInstance().scopes = [kGTLRAuthScopeDriveFile]
    GIDSignIn.sharedInstance().signInSilently()
}


@IBAction func uploadAction(_ sender: Any) {
    if let documentsDir = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).last {
        let dataImg: Data = UIImageJPEGRepresentation(UIImage(named: "logo.png")!, 1.0)!
        drive?.uploadFile("config.json", data: dataImg, MIMEType: "image/png") { (fileID, error) in
            print("Upload file ID: \(fileID); Error: \(error?.localizedDescription)")
        }
       }
     }

    @IBAction func listAction(_ sender: Any) {
    drive?.listFilesInFolder("config.json") { (files, error) in
        guard let fileList = files else {
            print("Error listing files: \(error?.localizedDescription)")
            return
        }

        self.resultsLabel.text = fileList.files?.description
        print(fileList)
        for nFile in fileList.files! {
            if nFile.mimeType == "image/jpeg" {
                self.drive?.download(nFile.identifier!, onCompleted: { (data, error) in
                    print(data)
                    print(error)
                })
              }
            }
          }
        }
      }

     // MARK: - GIDSignInDelegate
     extension ViewController: GIDSignInDelegate {
     func sign(_ signIn: GIDSignIn!, didSignInFor user: GIDGoogleUser!, withError error: Error!) {
    if let _ = error {
        service.authorizer = nil
    } else {
        service.authorizer = user.authentication.fetcherAuthorizer()
        service.shouldFetchNextPages = true
    }
  } 
 }

    // MARK: - GIDSignInUIDelegate
    extension ViewController: GIDSignInUIDelegate {}

每当我尝试上传任何文件时,都会出现错误:

Error Domain=com.google.GTLRErrorObjectDomain Code=403 "The granted scopes do not allow use of the Application Data folder." UserInfo={GTLRStructuredError=GTLRErrorObject 0x281515d10: {message:"The granted scopes do not allow use of the Application Data folder." errors:[1] code:403}, NSLocalizedDescription=The granted scopes do not allow use of the Application Data folder.}
Mohd Zakir |

您需要为Google驱动器配置设置范围,

GIDSignIn.sharedInstance().scopes = [kGTLRAuthScopeDriveAppData]

参考 驱动器范围

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章

Eclipse RCP:特定于应用程序的文件夹

限制 Azure 应用程序对 OneDrive 中特定文件夹的访问

是否可以通过媒体存储访问特定于应用程序的外部存储文件夹?

如何将图片保存在特定文件夹中仅用于我的应用程序(正确)?

如何使用c#从外部应用程序访问特定文件夹中的Outlook 2013联系人?

我想使用Powershell将Web应用程序的特定文件和文件夹备份到Blob存储中

android:从资产的文件夹(sqllite db)中导出数据,并将其导入应用程序的数据库中

如何在Android应用程序中将文件创建到特定文件夹?

创建文件并将其存储在Java Web应用程序文件夹中

应用扩展程序如何访问包含应用程序文档/文件夹中的文件

使用文件夹重定向时访问“应用程序数据”文件夹

如何配置Behat从应用程序特定文件夹自动加载类

如何在特定文件夹中启动 Windows 10 Mail 应用程序?

如何打开具有特定专辑或文件夹的默认图库应用程序?

如何在Android Gallery中创建应用程序特定的文件夹?

phonegap从URL下载图像并将其保存到应用程序安装文件夹

WatchKit:Swift-如何获取数据并将其放入iPhone应用程序文档文件夹中的sqlite数据库中

拒绝访问Cloudfoundry应用程序的子文件夹

请求从UWP应用程序永久访问文件夹

如何在UWP应用程序中的应用程序文件夹之外访问文件(如SQLite数据库)?

使用特定的wifi阻止对某些应用程序的Internet访问

将文件包放入iOS应用程序中的特定文件夹位置

Microsoft Graph应用程序权限-限制对特定文件/文件夹的读取/写入

从静态文件夹获取图像文件并将其显示在客户端应用程序中

在应用程序中创建CSV或TXT文件并将其保存到“下载”文件夹-Android

如何将对文件夹的访问限制为Asp.Net WebForms应用程序中的特定活动目录组?

如何在Codeigniter应用程序的文件夹中访问CSS文件?

如何在移动设备上访问uwp应用程序的文件和文件夹

如何从应用程序访问“我的用户”文件夹中的文件?