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

Crash AFTER trying to retrieve contents of directory from FTP #79

Closed
gouen95 opened this issue Jan 3, 2018 · 10 comments
Closed

Crash AFTER trying to retrieve contents of directory from FTP #79

gouen95 opened this issue Jan 3, 2018 · 10 comments
Labels

Comments

@gouen95
Copy link

gouen95 commented Jan 3, 2018

Hi, I'm trying to list down the contents of directory from a ftp server.

iOS: 11.2
XCode: 9.2, Swift 4

Here is the crash error :
*** -[FilesProvider.FileProviderStreamTask respondsToSelector:]: message sent to deallocated instance 0x1c01c4ec0

Below is the code :

        let credential = URLCredential(user: hostList![row].username!, password: hostList![row].password!, persistence: .permanent)
        
        let ftpFileProvider = FTPFileProvider(baseURL: URL(string: hostList![row].serverUrl!)!, passive: true, credential: credential, cache: nil)
        
        ftpFileProvider?.contentsOfDirectory(path: "", completionHandler: { (contents, error) in
            print(error)
            
            for file in contents {
                print("Name: \(file.name)")
                print("Size: \(file.size)")
                print("Creation Date: \(file.creationDate)")
                print("Modification Date: \(file.modifiedDate)")
            }
        }) 
@amosavian
Copy link
Owner

You get this error every time?

@gouen95
Copy link
Author

gouen95 commented Jan 3, 2018

Yes, unfortunately. : (

@amosavian
Copy link
Owner

amosavian commented Jan 3, 2018

This sample code has a flaw. It does not retain ftpFileProvider instance object. You must store it as a global variable or as instance variable.

@gouen95
Copy link
Author

gouen95 commented Jan 3, 2018

Hi, thank you for the quick reply. I've tried to make it as an instance variable. The issue still persist. I'm sorry if I'm unfamiliar with the framework implementation.

Below is the code of my whole controller.

//
//  ContentListingViewController.swift
//  

import UIKit
import FilesProvider

class ContentListingViewController: UIViewController {
    
    //MARK:- Variables
    var host: HostBean?
    var ftpFileProvider: FTPFileProvider?
    
    //MARK:- Application Lifecycles
    override func viewDidLoad() {
        super.viewDidLoad()

        if host != nil {
            listDirectories()
        }
    }

    //MARK:- Private Functions
    private func listDirectories() {
        let credential = URLCredential(user: (host?.username!)!, password: (host?.password!)!, persistence: .permanent)
        
        ftpFileProvider?.delegate = self as FileProviderDelegate
        
        ftpFileProvider = FTPFileProvider(baseURL: URL(string: (host?.serverUrl!)!)!, passive: true, credential: credential, cache: nil)
        
        ftpFileProvider?.contentsOfDirectory(path: "/", completionHandler: { (contents, error) in
            print(error)
            
            for file in contents {
                print("Name: \(file.name)")
                print("Size: \(file.size)")
                print("Creation Date: \(file.creationDate)")
                print("Modification Date: \(file.modifiedDate)")
            }
        })
    }
}

extension ContentListingViewController: FileProviderDelegate {
    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 \(String(describing: operation.destination)) succeed")
        }
    }
    
    func fileproviderFailed(_ fileProvider: FileProviderOperations, operation: FileOperationType, error: Error) {
        switch operation {
        case .copy(source: let source, destination: let dest):
            print("copy of \(source) failed. huh? \(dest)")
        case .remove:
            print("file can't be deleted.")
        default:
            print("\(operation.actionDescription) from \(operation.source) to \(String(describing: 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.")
        default:
            break
        }
    }
}

@amosavian
Copy link
Owner

amosavian commented Jan 3, 2018

My test unit is passing on my mac. My apps work well too. I cant reproduce :/

@amosavian amosavian added the bug label Jan 3, 2018
@gouen95
Copy link
Author

gouen95 commented Jan 5, 2018

Hi, I've been trying a few public ftp server out there and try to find out if any of them is same with my own desktop ftp server. I've found a public ftp server which is ftp://speedtest.tele2.net/ (username: anonymous, no password), this ftp server caused the application to crash while others don't.. I don't understand why this is happening hope it helps.

Edit : new crash error

objc[4597]: Class _NSZombie_OS_xpc_uuid is implemented in both ?? (0x1c4248df0) and ?? (0x1c4248ee0). One of the two will be used. Which one is undefined.
2018-01-05 16:24:57.788994+0800 TestFTP[4597:1119160] [MC] Lazy loading NSBundle MobileCoreServices.framework
2018-01-05 16:24:57.790122+0800 TestFTP[4597:1119160] [MC] Loaded MobileCoreServices.framework
2018-01-05 16:26:11.914376+0800 TestFTP[4597:1119160] *** -[FilesProvider.FileProviderStreamTask respondsToSelector:]: message sent to deallocated instance 0x1c01cb310

@amosavian
Copy link
Owner

amosavian commented Jan 5, 2018

The problem was zombie objects. Thanks for your report.
Adding these lines has fixed issue as far as I tested.

@buba447
Copy link

buba447 commented Apr 21, 2018

Im having a similar crash. Using the example code for retrieving directory contents. I am retaining the FTPFileProvider. The crash happens immediately AFTER the completion block returns. The contents are retrieved properly then the app crashes with EXC_BAD_ACCESS (code=EXC_I386_GPFLT)

example code

class CameraFileManager {
  
  let ipAddress: URL
  let documentProvider: FTPFileProvider?
  
  init(ipAddress: URL) {
    self.ipAddress = ipAddress
    
    self.documentProvider = FTPFileProvider(baseURL: ipAddress)
  }
  
  func getCameraName() {
    ///tmp/fuse_d/NAME/

    documentProvider?.contentsOfDirectory(path: "/tmp/fuse_d/NAME/", rfc3659enabled: false, completionHandler: {
      contents, error in
      for file in contents {
        print("Name: \(file.name)")
        print("Size: \(file.size)")
        print("Creation Date: \(file.creationDate)")
        print("Modification Date: \(file.modifiedDate)")
      }
    })
  }
}```

@buba447
Copy link

buba447 commented Apr 21, 2018

Heres a zombie trace for the error

screen shot 2018-04-21 at 10 58 42 am

@amosavian amosavian reopened this Apr 21, 2018
@amosavian amosavian reopened this Apr 22, 2018
@amosavian
Copy link
Owner

@buba447 Please pull latest commit and check again

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

3 participants