Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

WebDavFileProvider example #32

Closed
CPiersigilli opened this issue Apr 1, 2017 · 46 comments
Closed

WebDavFileProvider example #32

CPiersigilli opened this issue Apr 1, 2017 · 46 comments
Labels

Comments

@CPiersigilli
Copy link

This is my example code for os x:

import Cocoa
import FileProvider

class ViewController: NSViewController {
    
    @IBOutlet weak var writeText: NSTextField!
    @IBOutlet weak var textSavedFromFile: NSTextField!
    @IBOutlet weak var folderList: NSTextField!
    
    var webdavFile: WebDAVFileProvider?
    var operation: OperationHandle?
    
    @IBAction func saveText(_ sender: NSButton) {
        let user = "xxx@xxxxx.xx"
        let password = "xxxx"
        
        let credential = URLCredential(user: user, password: password, persistence: .forSession)
        let myUrlWebdav = URL(string: "https://webdav.pcloud.com")
        let webdavFile = WebDAVFileProvider(baseURL: myUrlWebdav!, credential: credential)
        let path = "newFile1.txt"
        let nameFolder = "Text"
        let atFolder = "/"
        let atFile = atFolder + nameFolder + atFolder + path
        
        print(atFile)

        if writeText.stringValue != "" {
            let data = writeText.stringValue.data(using: .utf8)
            print("Data is: \(data)")
            
            webdavFile?.create(folder: nameFolder, at: atFolder, completionHandler: { error in
                if error == nil {
                print("La cartella è stata creata con successo.")
                }
                else
                {
                print("La cartella non è stata creata con il seguente errore: \(error)")
                }
                webdavFile?.writeContents(path: atFile, contents: data, atomically: false, overwrite: false, completionHandler: { error in
                    if error == nil {
                        print("Il file è stato creato con successo.")
                    }
                    else
                    {
                        print("Il file non è stato creato con il seguente errore: \(error)")
                    }
                })
            
            })
        }
        
    }

    @IBAction func readText(_ sender: NSButton) {
        
    }
    
    @IBAction func folderList(_ sender: NSButton) {
        
    }
    

    override func viewDidLoad() {
        super.viewDidLoad()
        
        // Do any additional setup after loading the view.
        webdavFile?.delegate = (self as! FileProviderDelegate)
    }

    override var representedObject: Any? {
        didSet {
        // Update the view, if already loaded.
        }
    }

    func fileproviderSucceed(_ fileProvider: FileProviderOperations, operation: FileOperationType) {
        switch operation {
        case .copy(source: let source, destination: let dest):
            print("\(source) copied to \(dest).")
        case .remove(path: let path):
            print("\(path) has been deleted.")
        default:
            print("\(operation.actionDescription) from \(operation.source!) to \(operation.destination) succeed")
        }
    }
    
    func fileproviderFailed(_ fileProvider: FileProviderOperations, operation: FileOperationType) {
        switch operation {
        case .create(path: let pathFile):
            print("create file: \(pathFile) failed.")
        case .modify(path: let pathFile):
            print("modify file: \(pathFile) failed.")
        case .copy(source: let source, destination: let dest):
            print("copy of \(source) failed.")
        case .remove:
            print("file can't be deleted.")
        default:
            print("\(operation.actionDescription) from \(operation.source!) to \(operation.destination) failed")
        }
    }
    
    func fileproviderProgress(_ fileProvider: FileProviderOperations, operation: FileOperationType, progress: Float) {
        switch operation {
        case .copy(source: let source, destination: let dest):
            print("Copy\(source) to \(dest): \(progress * 100) completed.")
        case .create(path: let pathFile):
            print("Create file or folder to \(pathFile): \(progress * 100) completed.")
        default:
            break
        }
    }
}

My problems are:

  1. If I do not use "create folder" and the folder does not exist the file is not created without any error.
  2. If the directory exists the file is created, but without any information.
  3. It does not work the delegate method.

Can anyone change the code so that it works?
Thank you
Cesare Piersigilli

@amosavian
Copy link
Owner

Please check latest version (0.15.0), I think this bug would be fixed already

@CPiersigilli
Copy link
Author

I tried to test the code with version (0.15.0) but I have not noticed any changes. Delegate does not work and is not communicated anything when the file was created.

@amosavian
Copy link
Owner

I can't understand how creating a folder can have a progress. It will either fail or succeed.

@amosavian
Copy link
Owner

@CPiersigilli please check 0.15.2

@CPiersigilli
Copy link
Author

I check 0.15.2.

  • operation = webdavFile?.create works fine with a message that the folder was created.
  • operation = webdavFile?.writeContents works but I do not receive any message that the file was created.
  • operation = webdavFile?.contents not works.
  • webdavFile?.contentsOfDirectory works fine, but when I put the result in self.folderList.stringValue works but with this error CoreAnimation: warning, deleted thread with uncommitted CATransaction; set CA_DEBUG_TRANSACTIONS=1 in environment to log backtraces.
  • Still will not work func fileproviderSucceed(_, func fileproviderFailed( and func fileproviderProgress(.

I modified the code to create and read the "/Text/newFile2.txt" file, but still does not work as I would like. Can you help me? Sorry for my English.

import Cocoa
import FileProvider

class ViewController: NSViewController {
    
    @IBOutlet weak var writeText: NSTextField!
    @IBOutlet weak var textSavedFromFile: NSTextField!
    @IBOutlet weak var folderList: NSTextField!
    
    var webdavFile: WebDAVFileProvider?
    var operation: OperationHandle?
    
    @IBAction func saveText(_ sender: NSButton) {
        let user = "xxx@xxxxx.it"
        let password = "xxxxx"
        
        let credential = URLCredential(user: user, password: password, persistence: .forSession)
        let myUrlWebdav = URL(string: "https://webdav.pcloud.com")
        let webdavFile = WebDAVFileProvider(baseURL: myUrlWebdav!, credential: credential)
        
        let path = "newFile2.txt"
        let nameFolder = "Text"
        let atFolder = "/"
        let atFile = atFolder + nameFolder + atFolder + path

        if writeText.stringValue != "" {
            let data = writeText.stringValue.data(using: .utf8)
            
            operation = webdavFile?.create(folder: nameFolder, at: atFolder, completionHandler: { error in
                if error == nil {
                print("The folder was created successfully.")
                }
                else
                {
                print("The folder was not created for the following error: \(error)")
                }
            })
            operation = webdavFile?.writeContents(path: atFile, contents: data, atomically: false, overwrite: true, completionHandler: { error in
                if error == nil {
                    print("The file was created with: \(self.operation).")
                }
                else
                {
                    print("The file was not created for the following error: \(error)")
                }
            })
        }
    }

    @IBAction func readText(_ sender: NSButton) {
        let user = "xxx@xxxx.it"
        let password = "xxx"
        
        let credential = URLCredential(user: user, password: password, persistence: .permanent)
        let myUrlWebdav = URL(string: "https://webdav.pcloud.com")
        webdavFile = WebDAVFileProvider(baseURL: myUrlWebdav!, credential: credential)
        let path = "/Text/newFile2.txt"
        
        operation = webdavFile?.contents(path: path, completionHandler: {
            contents, error in
            if error == nil {
            if let contents = contents {
                print("The file contains: \(String(data: contents, encoding: .utf8))")
                self.textSavedFromFile.stringValue = String(data: contents, encoding: .utf8)!
                }
            }
            else
            {
                print("Error: \(error)")
            }
        })
    }
    
    @IBAction func folderList(_ sender: NSButton) {
        let user = "xxx@xxxx.it"
        let password = "xxx"
        
        let credential = URLCredential(user: user, password: password, persistence: .forSession)
        let myUrlWebdav = URL(string: "https://webdav.pcloud.com")
        webdavFile = WebDAVFileProvider(baseURL: myUrlWebdav!, credential: credential)
        let atFolder = "/"
        
        webdavFile?.contentsOfDirectory(path: atFolder, completionHandler: {
            contents, error in
            if error == nil {
                var localFolderList = "Name Size Creation Date Modification Date"+"\n"
                for file in contents {
                    localFolderList += "\(file.name) \(file.size) \(file.creationDate!) \(file.modifiedDate!) \n"
                }
                print(localFolderList)
                self.folderList.stringValue = localFolderList
            }
            else
            {
             print("Error: \(error)")
            }
        })
    }
    

    override func viewDidLoad() {
        super.viewDidLoad()
        
        // Do any additional setup after loading the view.
        webdavFile?.delegate = self as? FileProviderDelegate
    }

    override var representedObject: Any? {
        didSet {
        // Update the view, if already loaded.
        }
    }

    func fileproviderSucceed(_ fileProvider: FileProviderOperations, operation: FileOperationType) {
        switch operation {
        case .fetch(path: let pathFile):
            print("fetch file from: \(pathFile).")
        case .modify(path: let pathFile):
            print("modify file: \(pathFile).")
        case .copy(source: let source, destination: let dest):
            print("\(source) copied to \(dest).")
        case .remove(path: let path):
            print("\(path) has been deleted.")
        case .create(path: let pathFile):
            print("created file: \(pathFile).")
        case .move(source: let source, destination: let dest):
            print("\(source) moved to \(dest).")
        default:
            print("\(operation.actionDescription) from \(operation.source!) to \(operation.destination) succeed")
        }
    }
    
    func fileproviderFailed(_ fileProvider: FileProviderOperations, operation: FileOperationType) {
        switch operation {
        case .create(path: let pathFile):
            print("create file: \(pathFile) failed.")
        case .modify(path: let pathFile):
            print("modify file: \(pathFile) failed.")
        case .copy(source: let source, destination: let dest):
            print("copy of \(source) to \(dest) failed.")
        case .remove:
            print("file can't be deleted.")
        default:
            print("\(operation.actionDescription) from \(operation.source!) to \(operation.destination) failed")
        }
    }
    
    func fileproviderProgress(_ fileProvider: FileProviderOperations, operation: FileOperationType, progress: Float) {
        switch operation {
        case .copy(source: let source, destination: let dest):
            print("Copy\(source) to \(dest): \(progress * 100) completed.")
        case .create(path: let pathFile):
            print("Create file or folder to \(pathFile): \(progress * 100) completed.")
        case .fetch(path: let pathFile):
            print("fecth file or folder to \(pathFile): \(progress * 100) completed.")
        default:
            break
        }
    }
}

@amosavian
Copy link
Owner

Are you sure you are using 0.15.2?

@CPiersigilli
Copy link
Author

Yes. Because I'm using this code in a new mac.
I made another test and I have found that Operation = webdavFile?.writeContents works with the message, if the file does not exist, and before I put operation = webdavFile?.create.

@CPiersigilli
Copy link
Author

I'm sure to use the 0.15.2 version, but how can I see it?
If you want, at your private email, I will send the code with user and pass to check?

@amosavian
Copy link
Owner

latest cocoa pods version is 0.15.1 if you are using pods

@CPiersigilli
Copy link
Author

No. I use FileProvider.xcodeproj and I downloaded the version 0.15.2 from Added progress for content(path:) method - Source code (zip).

@CPiersigilli
Copy link
Author

In the sample code above, I have tried to insert your:

let sessionDelegate = SessionDelegate(fileProvider: fileProvider, credential: fileProvider.credential)
let backgroundconfig = URLSessionConfiguration.background(withIdentifier: "com.company.myapp")
fileProvider.session = URLSession(configuration: backgroundconfig, delegate: sessionDelegate as URLSessionDelegate?, delegateQueue: fileProvider.operation_queue)

with the following error:
error

Where should I put the above code does not have errors?
It would be very interesting to set the session.

@amosavian
Copy link
Owner

Please initialize webdavFile inside viewDidLoad() and use that as singleton across all methods.

And questions:

  • operation = webdavFile?.create works fine with a message that the folder was created.
  • operation = webdavFile?.writeContents works but I do not receive any message that the file was created.

You should do writeContents() inside create(folder:) completion handler!

  • webdavFile?.contentsOfDirectory works fine, but when I put the result in self.folderList.stringValue works but with this error CoreAnimation: warning, deleted thread with uncommitted CATransaction; set CA_DEBUG_TRANSACTIONS=1 in environment to log backtraces.

That's a bug in Apple's framework. Don't pay attention to that.

  • Still will not work func fileproviderSucceed(_, func fileproviderFailed( and func fileproviderProgress(.

That works fine for me! That's probably because you are initializing provider inside functions which will be released before completion handler runs! If you initialize it inside viewDidLoad() and use it, this problem will be probably gone.

And thank you for noting that I forgot to make SessionDelegate initializer public. I'll do in next version.

@amosavian
Copy link
Owner

I've fixed it for you test it:

import Cocoa
import FileProvider

class ViewController: NSViewController, FileProviderDelegate {
    
    @IBOutlet weak var writeText: NSTextField!
    @IBOutlet weak var textSavedFromFile: NSTextField!
    @IBOutlet weak var folderList: NSTextField!
    
    var webdavFile: WebDAVFileProvider?
    var operation: OperationHandle?
    
    @IBAction func saveText(_ sender: NSButton) {
        let path = "newFile2.txt"
        let nameFolder = "Text"
        let atFolder = "/"
        let atFile = atFolder + nameFolder + atFolder + path

        if writeText.stringValue != "" {
            let data = writeText.stringValue.data(using: .utf8)
            
            operation = webdavFile?.create(folder: nameFolder, at: atFolder, completionHandler: { error in
                if error == nil {
                print("The folder was created successfully.")
                }
                else
                {
                print("The folder was not created for the following error: \(error)")
                }
                
                operation = webdavFile?.writeContents(path: atFile, contents: data, atomically: false, overwrite: true, completionHandler: { error in
                    if error == nil {
                        print("The file was created with: \(self.operation).")
                    }
                    else
                    {
                        print("The file was not created for the following error: \(error)")
                    }
                })
            })
        }
    }

    @IBAction func readText(_ sender: NSButton) {
        let path = "/Text/newFile2.txt"
        
        operation = webdavFile?.contents(path: path, completionHandler: {
            contents, error in
            if error == nil {
            if let contents = contents {
                print("The file contains: \(String(data: contents, encoding: .utf8))")
                self.textSavedFromFile.stringValue = String(data: contents, encoding: .utf8)!
                }
            }
            else
            {
                print("Error: \(error)")
            }
        })
    }
    
    @IBAction func folderList(_ sender: NSButton) {
        let atFolder = "/"
        
        webdavFile?.contentsOfDirectory(path: atFolder, completionHandler: {
            contents, error in
            if error == nil {
                var localFolderList = "Name Size Creation Date Modification Date"+"\n"
                for file in contents {
                    localFolderList += "\(file.name) \(file.size) \(file.creationDate!) \(file.modifiedDate!) \n"
                }
                print(localFolderList)
                self.folderList.stringValue = localFolderList
            }
            else
            {
             print("Error: \(error)")
            }
        })
    }
    

    override func viewDidLoad() {
        super.viewDidLoad()
        
        // Do any additional setup after loading the view.
        let user = "xxx@xxxxx.it"
        let password = "xxxxx"
        credential = URLCredential(user: user, password: password, persistence: .forSession)
        myUrlWebdav = URL(string: "https://webdav.pcloud.com")
        webdavFile = WebDAVFileProvider(baseURL: myUrlWebdav!, credential: credential)
        webdavFile?.delegate = self as? FileProviderDelegate
    }

    override var representedObject: Any? {
        didSet {
        // Update the view, if already loaded.
        }
    }

    func fileproviderSucceed(_ fileProvider: FileProviderOperations, operation: FileOperationType) {
        switch operation {
        case .fetch(path: let pathFile):
            print("fetch file from: \(pathFile).")
        case .modify(path: let pathFile):
            print("modify file: \(pathFile).")
        case .copy(source: let source, destination: let dest):
            print("\(source) copied to \(dest).")
        case .remove(path: let path):
            print("\(path) has been deleted.")
        case .create(path: let pathFile):
            print("created file: \(pathFile).")
        case .move(source: let source, destination: let dest):
            print("\(source) moved to \(dest).")
        default:
            print("\(operation.actionDescription) from \(operation.source!) to \(operation.destination) succeed")
        }
    }
    
    func fileproviderFailed(_ fileProvider: FileProviderOperations, operation: FileOperationType) {
        switch operation {
        case .create(path: let pathFile):
            print("create file: \(pathFile) failed.")
        case .modify(path: let pathFile):
            print("modify file: \(pathFile) failed.")
        case .copy(source: let source, destination: let dest):
            print("copy of \(source) to \(dest) failed.")
        case .remove:
            print("file can't be deleted.")
        default:
            print("\(operation.actionDescription) from \(operation.source!) to \(operation.destination) failed")
        }
    }
    
    func fileproviderProgress(_ fileProvider: FileProviderOperations, operation: FileOperationType, progress: Float) {
        switch operation {
        case .copy(source: let source, destination: let dest):
            print("Copy\(source) to \(dest): \(progress * 100) completed.")
        case .create(path: let pathFile):
            print("Create file or folder to \(pathFile): \(progress * 100) completed.")
        case .fetch(path: let pathFile):
            print("fecth file or folder to \(pathFile): \(progress * 100) completed.")
        default:
            break
        }
    }
}

@amosavian
Copy link
Owner

By the way to get writeContents() method progress, you should have case .modify(path: let pathFile): in your fileproviderProgress method

@CPiersigilli
Copy link
Author

With the changes, for each function, now the situation is:

operation = webdavFile?.create(folder: nameFolder, at: atFolder, completionHandler: { error in
                if error == nil {
                print("The folder was created successfully.")
                }
                else
                {
                print("The folder was not created for the following error: \(error)")
                }
                self.operation = self.webdavFile?.writeContents(path: atFile, contents: data, atomically: false, overwrite: true, completionHandler: { error in
                    if error == nil {
                        print("The file was created with: \(self.operation?.operationType).")
                    }
                    else
                    {
                        print("The file was not created for the following error: \(error)")
                    }
                })
            })
  • Now "writeContents" works, but I still do not receive information from "fileproviderSucceed" and "fileproviderProgress" but only from "print" inside the IF inside the "writeContents".

  • Still not working "webdavFile?.contents" that does not give any information. I do not know why.

  • "webdavFile?.contentsOfDirectory" it works, even if it continues to refuse to provide information from "fileproviderSucceed" and "fileproviderProgress", but only on the "print" inside "completionHandler" of "webdavFile?.contentsOfDirectory".

@amosavian
Copy link
Owner

Did you copy this line?

class ViewController: NSViewController, FileProviderDelegate {

@CPiersigilli
Copy link
Author

This is the error that I get by inserting FileProviderDelegate.
error

@amosavian
Copy link
Owner

Well, that's justifies why delegate doesn't work. I can't help you much if you can't conform your class to a protocol.

@CPiersigilli
Copy link
Author

With reference to the above code, how can I make the class ViewController conform to FileProviderDelegate class?

@amosavian
Copy link
Owner

Xcode should tell you which methods are unimplemented, but implementing all 3 methods, without omitting any of these, fileproviderSucceed, fileproviderFailed , fileproviderProgress makes your class conformable.

@CPiersigilli
Copy link
Author

Excuse me, I had commented fileproviderSucceed. Now works. Thank you.
At this point you have to help figure out how to operate with webdavFile?.contents.
Why did not it work?

@amosavian
Copy link
Owner

Can I have error returned by contents method?

@CPiersigilli
Copy link
Author

Unfortunately no errors. The procedure skips to the end of the completion handler.

@CPiersigilli
Copy link
Author

This is the code for webdavFile?.contents.

@IBAction func readText(_ sender: NSButton) {      
        let path = "newFile2.txt"       
        operation = webdavFile?.contents(path: path, completionHandler: { (contents, error) in
            if error == nil {
                if let contents = contents {
                    print("The file contains: \(String(data: contents, encoding: .utf8))")
                    self.textSavedFromFile.stringValue = String(data: contents, encoding: .utf8)!
                    }
                else
                {
                    print("ERRORE SCONOSCIUTO")
                }
                }
                else
                {
                    print("Error: \(error)")
                    }
            })
    }

@CPiersigilli
Copy link
Author

ERRORE SCONOSCIUTO in english: UNKNOWN ERROR. Excuse me.

@amosavian
Copy link
Owner

Does the completion handler is called or not?

@CPiersigilli
Copy link
Author

Probably not, because the code jump from operation to the end of completation handler ---> "})".

@amosavian
Copy link
Owner

That jump is because the completion handler will run asynchronously. That's normal. You should put.a breakpoint inside closure, like line 4 in this sample

@CPiersigilli
Copy link
Author

I added a breakpoint as shown in the screen shot below, but I got nothing, the procedure jumps from operation at the end of completation handler without going through the IF.
error

@CPiersigilli
Copy link
Author

newFile3.txt does not exist.

@CPiersigilli
Copy link
Author

I have tried to insert breakpoints anywhere without getting anything (line 5, 6, 7, 8 ....).

@CPiersigilli
Copy link
Author

In WebDAVFileProvider.swift session is not nil (see screen shot below).
screenshot 2017-04-05 19 40 13

And this screen shot shows the values that assumes webdavFile, before reaching the end of completation handler.
screenshot 2017-04-05 19 46 41

@amosavian
Copy link
Owner

amosavian commented Apr 5, 2017

I can't understand the purpose of that.

@amosavian
Copy link
Owner

This code is working for me. Can't find what's going wrong here. But I will do further testing later

@CPiersigilli
Copy link
Author

To test webdavFile?.contents I have also tried box.com, without results. I wait for your news.

@CPiersigilli
Copy link
Author

To perform other tests, I have rewritten the app for ios: but only webdavFile?.contents continue to give no message. I wait for your news. Thank you.

@CPiersigilli
Copy link
Author

This issue in

override func viewDidLoad() {
        super.viewDidLoad()

could be a problem?
screenshot 2017-04-07 20 14 12

and this:
screenshot 2017-04-07 20 17 44
Thank you.

@amosavian
Copy link
Owner

Not a problem only a hint. Just remove as? FileProviderDelegate to suppress warning

@CPiersigilli
Copy link
Author

Ok. Hint removed. And for webdavFile?.contents what you can you tell me?
I tried in every way, but I can not make it work.

@amosavian
Copy link
Owner

It works for me. I don't know what to do. It's open source and you can alter the codes which don't work.

@amosavian
Copy link
Owner

@CPiersigilli I've tested writeContents instead of contents, sorry I found the bug and fixed. Soon will update.

@amosavian amosavian reopened this Apr 9, 2017
@CPiersigilli
Copy link
Author

@amosavian I'm very happy. Thank you. I will wait for your news.

@amosavian
Copy link
Owner

Fixed in ff5e139 (version 0.15.3)

@CPiersigilli
Copy link
Author

I test my code with version (0.15.3) and now work fine. Thank you.
I will continue the testing of FileProvider.

@amosavian
Copy link
Owner

sorry for inconvenience

@CPiersigilli
Copy link
Author

Don't worry. Thanks for the library that you have written.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants