SkillAgentSearch skills...

FileProvider

FileManager replacement for Local, iCloud and Remote (WebDAV/FTP/Dropbox/OneDrive) files -- Swift

Install / Use

/learn @amosavian/FileProvider

README

File Provider

This Swift library provide a swifty way to deal with local and remote files and directories in a unified way.

<center>

[![Swift Version][swift-image]][swift-url] ![Platform][platform-image] [![License][license-image]][license-url] [![Build Status][travis-image]][travis-url] [![Codebeat Badge][codebeat-image]][codebeat-url]

[![Release version][release-image]][release-url] [CocoaPods version][cocoapods] ![Carthage compatible][carthage-image] [![Cocoapods Downloads][cocoapods-downloads]][cocoapods] [![Cocoapods Apps][cocoapods-apps]][cocoapods]

</center> <!--- [![Cocoapods Doc][docs-image]][docs-url] [![codecov](https://codecov.io/gh/amosavian/FileProvider/branch/master/graph/badge.svg)](https://codecov.io/gh/amosavian/FileProvider) --->

This library provides implementaion of WebDav, FTP, Dropbox, OneDrive and SMB2 (incomplete) and local files.

All functions do async calls and it wont block your main thread.

Features

  • [x] LocalFileProvider a wrapper around FileManager with some additions like builtin coordinating, searching and reading a portion of file.
  • [x] CloudFileProvider A wrapper around app's ubiquitous container API of iCloud Drive.
  • [x] WebDAVFileProvider WebDAV protocol is defacto file transmission standard, supported by some cloud services like ownCloud, Box.com and Yandex.disk.
  • [x] FTPFileProvider While deprecated in 1990s due to serious security concerns, it's still in use on some Web hosts.
  • [x] DropboxFileProvider A wrapper around Dropbox Web API.
    • For now it has limitation in uploading files up to 150MB.
  • [x] OneDriveFileProvider A wrapper around OneDrive REST API, works with onedrive.com and compatible (business) servers.
  • [ ] AmazonS3FileProvider Amazon storage backend. Used by many sites.
  • [ ] GoogleFileProvider A wrapper around Goodle Drive REST API.
  • [ ] SMBFileProvider SMB2/3 introduced in 2006, which is a file and printer sharing protocol originated from Microsoft Windows and now is replacing AFP protocol on macOS.
    • Data types and some basic functions are implemented but main interface is not implemented yet!.
    • For now, you can use amosavian/AMSMB2 framework to connect to SMB2.

Requirements

  • Swift 4.0 or higher
  • iOS 8.0 , OSX 10.10
  • XCode 9.0

Legacy version is available in swift-3 branch.

Installation

Important: this library has been renamed to avoid conflict in iOS 11, macOS 10.13 and Xcode 9.0. Please read issue #53 to find more.

Cocoapods / Carthage / Swift Package Manager

Add this line to your pods file:

pod "FilesProvider"

Or add this to Cartfile:

github "amosavian/FileProvider"

Or to use in Swift Package Manager add this line in Dependencies:

.Package(url: "https://github.com/amosavian/FileProvider.git", majorVersion: 0)

Manually

To have latest updates with ease, use this command on terminal to get a clone:

git clone https://github.com/amosavian/FileProvider

You can update your library using this command in FileProvider folder:

git pull

if you have a git based project, use this command in your projects directory to add this project as a submodule to your project:

git submodule add https://github.com/amosavian/FileProvider

Then you can do either:

  • Copy Source folder to your project and Voila!

  • Drop FilesProvider.xcodeproj to you Xcode workspace and add the framework to your Embeded Binaries in target.

Design

To find design concepts and how to implement a custom provider, read Concepts and Design document.

Usage

Each provider has a specific class which conforms to FileProvider protocol and share same syntax.

Find a sample code for iOS here.

Initialization

For LocalFileProvider if you want to deal with Documents folder:

import FilesProvider

let documentsProvider = LocalFileProvider()

// Equals with:
let documentsProvider = LocalFileProvider(for: .documentDirectory, in: .userDomainMask)

// Equals with:
let documentsURL = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first!
let documentsProvider = LocalFileProvider(baseURL: documentsURL)

Also for using group shared container:

import FilesProvider

let documentsProvider = LocalFileProvider(sharedContainerId: "group.yourcompany.appContainer")
// Replace your group identifier

You can't change the base url later. and all paths are related to this base url by default.

To initialize an iCloud Container provider look at here to see how to update project settings then use below code, This will automatically manager creating Documents folder in container:

import FilesProvider

let documentsProvider = CloudFileProvider(containerId: nil)

For remote file providers authentication may be necessary:

import FilesProvider

let credential = URLCredential(user: "user", password: "pass", persistence: .permanent)
let webdavProvider = WebDAVFileProvider(baseURL: URL(string: "http://www.example.com/dav")!, credential: credential)
  • In case you want to connect non-secure servers for WebDAV (http) or FTP in iOS 9+ / macOS 10.11+ you should disable App Transport Security (ATS) according to this guide.

  • For Dropbox & OneDrive, user is clientID and password is Token which both must be retrieved via OAuth2 API o. There are libraries like p2/OAuth2 or OAuthSwift which can facilate the procedure to retrieve token. The latter is easier to use and prefered. Please see OAuth example for Dropbox and OneDrive for detailed instruction.

For interaction with UI, set delegate property of FileProvider object.

You can use url(of:) method if provider to get direct access url (local or remote files) for some file systems which allows to do so (Dropbox doesn't support and returns path simply wrapped in URL).

Delegates

For updating User interface please consider using delegate method instead of completion handlers. Delegate methods are guaranteed to run in main thread to avoid bugs.

There's simply three method which indicated whether the operation failed, succeed and how much of operation has been done (suitable for uploading and downloading operations).

Your class should conforms FileProviderDelegate class:

override func viewDidLoad() {
	documentsProvider.delegate = self as 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 \(operation.destination) succeed")
	}
}

func fileproviderFailed(_ fileProvider: FileProviderOperations, operation: FileOperationType) {
    switch operation {
	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.")
	default:
		break
	}
}

Note: fileproviderProgress() delegate method is not called by LocalFileProvider currently.

It's recommended to use completion handlers for error handling or result processing.

Controlling file operations

You can also implement FileOperationDelegate protocol to control behaviour of file operation (copy, move/rename, remove and linking), and decide which files should be removed for example and which won't.

fileProvider(shouldDoOperation:) method is called before doing a operation. You sould return true if you want to do operation or false if you want to stop that operation.

fileProvider(shouldProceedAfterError:, operation:) will be called if an error occured during file operations. Return true if you want to continue operation on next files or false if you want stop operation further. Default value is false if you don't implement delegate.

Note: In LocalFileProvider, these methods will be called for files in a directory and its subfolders recursively.

Directory contents and file attributes

There is a FileObject class which holds file attributes like size and creation date. You can retrieve information of files inside a directory or get information of a file directly.

For a single file:

documentsProvider.attributesOfItem(path: "/file.txt", completionHandler: {
	attributes, error in
	if let attributes = attributes {
		print("File Size: \(attributes.size)")
		print("Creation Date: \(attributes.creationDate)")
		print("Modification Date: \(attributes.modifiedDate)")
		print("Is Read Only: \(attributes.isReadOnly)")
	}
})

To get list of files in a directory:

documentsProvider.contentsOfDirectory(path: "/", 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)")
	}
})

To get size of strage and used/free space:

func storageProperties(completionHandler: { to

Related Skills

View on GitHub
GitHub Stars112
CategoryDevelopment
Updated14d ago
Forks23

Languages

Swift

Security Score

100/100

Audited on Mar 17, 2026

No findings