• Stars
    star
    2,289
  • Rank 20,117 (Top 0.4 %)
  • Language
    Swift
  • License
    MIT License
  • Created about 9 years ago
  • Updated over 1 year ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

Simple and expressive file management in Swift
Installation • Usage • License • Documentation

FileKit is a Swift framework that allows for simple and expressive file management.

Development happens in the develop branch.

Installation

Compatibility

  • OS X 10.9+ / iOS 8.0+ / watchOS 2.0 / tvOS 9.0

  • Xcode 7.1+, Swift 2.1+

Install Using CocoaPods

CocoaPods is a centralized dependency manager for Objective-C and Swift. Go here to learn more.

  1. Add the project to your Podfile.

    use_frameworks!
    
    pod 'FileKit', '~> 5.0.0'
  2. Run pod install and open the .xcworkspace file to launch Xcode.

  3. Import the FileKit framework.

    import FileKit

Install Using Carthage

Carthage is a decentralized dependency manager for Objective-C and Swift.

  1. Add the project to your Cartfile.

    github "nvzqz/FileKit"
    
  2. Run carthage update and follow the additional steps in order to add FileKit to your project.

  3. Import the FileKit framework.

    import FileKit

Usage

Paths

Paths are handled with the Path structure.

let home = Path("~")
let drive: Path = "/Volumes/Macintosh HD"
let file:  Path = "~/Desktop/file\(1)"

Operations

New Files

A blank file can be written by calling createFile() on an Path.

try Path(".gitignore").createFile()
New Directories

A directory can be created by calling createDirectory() on an Path.

try Path("~/Files").createDirectory()
try Path("~/Books").createDirectory(withIntermediateDirectories: false)

Intermediate directories are created by default.

New Symlinks

A symbolic link can be created by calling createSymlinkToPath(_:) on an Path.

try Path("path/to/MyApp.app").symlinkFile(to: "~/Applications")
print(Path("~/Applications/MyApp.app").exists)  // true
Finding Paths

You can find all paths with the ".txt" extension five folders deep into the Desktop with:

let textFiles = Path.userDesktop.find(searchDepth: 5) { path in
    path.pathExtension == "txt"
}

A negative searchDepth will make it run until every path in self is checked against.

You can even map a function to paths found and get the non-nil results:

let documents = Path.userDocuments.find(searchDepth: 1) { path in
    String(path)
}
Iterating Through Paths

Because Path conforms to SequenceType, it can be iterated through with a for loop.

for download in Path.userDownloads {
    print("Downloaded file: \(download)")
}
Current Working Directory

The current working directory for the process can be changed with Path.Current.

To quickly change the current working directory to a path and back, there's the changeDirectory(_:) method:

Path.userDesktop.changeDirectory {
    print(Path.current)  // "/Users/nvzqz/Desktop"
}
Common Ancestor

A common ancestor between two paths can be obtained:

print(Path.root.commonAncestor(.userHome))       // "/"
print("~/Desktop"  <^> "~/Downloads")            // "~"
print(.UserLibrary <^> .UserApplicationSupport)  // "/Users/nvzqz/Library"
+ Operator

Appends two paths and returns the result

// ~/Documents/My Essay.docx
let essay = Path.userDocuments + "My Essay.docx"

It can also be used to concatenate a string and a path, making the string value a Path beforehand.

let numberedFile: Path = "path/to/dir" + String(10)  // "path/to/dir/10"
+= Operator

Appends the right path to the left path. Also works with a String.

var photos = Path.userPictures + "My Photos"  // ~/Pictures/My Photos
photos += "../My Other Photos"                // ~/Pictures/My Photos/../My Other Photos
% Operator

Returns the standardized version of the path.

let path: Path = "~/Desktop"
path% == path.standardized  // true
* Operator

Returns the resolved version of the path.

let path: Path = "~/Documents"
path* == path.resolved  // true
^ Operator

Returns the path's parent path.

let path: Path = "~/Movies"
path^ == "~"  // true
->> Operator

Moves the file at the left path to the right path.

Path counterpart: moveFile(to:)

File counterpart: move(to:)

->! Operator

Forcibly moves the file at the left path to the right path by deleting anything at the left path before moving the file.

+>> Operator

Copies the file at the left path to the right path.

Path counterpart: copyFile(to:)

File counterpart: copy(to:)

+>! Operator

Forcibly copies the file at the left path to the right path by deleting anything at the left path before copying the file.

=>> Operator

Creates a symlink of the left path at the right path.

Path counterpart: symlinkFile(to:)

File counterpart: symlink(to:)

=>! Operator

Forcibly creates a symlink of the left path at the right path by deleting anything at the left path before creating the symlink.

Subscripting

Subscripting an Path will return all of its components up to and including the index.

let users = Path("/Users/me/Desktop")[1]  // /Users
standardize()

Standardizes the path.

The same as doing:

somePath = somePath.standardized
resolve()

Resolves the path's symlinks.

The same as doing:

somePath = somePath.resolved

Files

A file can be made using File with a DataType for its data type.

let plistFile = File<Dictionary>(path: Path.userDesktop + "sample.plist")

Files can be compared by size.

Operators

|> Operator

Writes the data on the left to the file on the right.

do {
    try "My name is Bob." |> TextFile(path: Path.userDesktop + "name.txt")
} catch {
    print("I can't write to a desktop file?!")
}

TextFile

The TextFile class allows for reading and writing strings to a file.

Although it is a subclass of File<String>, TextFile offers some functionality that File<String> doesn't.

|>> Operator

Appends the string on the left to the TextFile on the right.

let readme = TextFile(path: "README.txt")
try "My Awesome Project" |> readme
try "This is an awesome project." |>> readme

NSDictionaryFile

A typealias to File<NSDictionary>.

NSArrayFile

A typealias to File<NSArray>

NSDataFile

A typealias to File<NSData>

DataFile

The DataFile class allows for reading and writing Data to a file.

Although it is a subclass of File<Data>, DataFile offers some functionality that File<Data> doesn't. You could specify Data.ReadingOptions and Data.WritingOptions

Encodable/Decodable

You can use any Codable object with File.

extension AnyCodableClass: JSONReadableWritable {} // if you want json encoding/decoding

let codableFile = File<AnyCodableClass>(path: path)
try codableFile.write(toEncode)
let decoded: AnyCodableClass = try codableFile.read()

Alternatively you can use utility methods

try FileKit.write(toEncode, to: path)
let decoded: AnyCodableClass = try FileKit.read(from: path)

File Permissions

The FilePermissions struct allows for seeing the permissions of the current process for a given file.

let swift: Path = "/usr/bin/swift"
print(swift.filePermissions)  // FilePermissions[read, execute]

Data Types

All types that conform to DataType can be used to satisfy the generic type for File.

Readable Protocol

A Readable type must implement the static method read(from: Path).

All Readable types can be initialized with init(contentsOfPath:).

Writable Protocol

A Writable type must implement write(to: Path, atomically: Bool).

Writing done by write(to: Path) is done atomically by default.

WritableToFile

Types that have a write(toFile:atomically:) method that takes in a String for the file path can conform to Writable by simply conforming to WritableToFile.

WritableConvertible

If a type itself cannot be written to a file but can output a writable type, then it can conform to WritableConvertible and become a Writable that way.

FileKitError

The type for all errors thrown by FileKit operations is FileKitError.

Errors can be converted to String directly for any logging. If only the error message is needed, FileKitError has a message property that states why the error occurred.

// FileKitError(Could not copy file from "path/to/file" to "path/to/destination")
String(FileKitError.copyFileFail(from: "path/to/file", to: "path/to/destination"))

License

FileKit and its assets are released under the MIT License. Assets can be found in the assets branch.

More Repositories

1

RandomKit

Random data generation in Swift
Swift
1,473
star
2

divan

Fast and simple benchmarking for Rust projects
Rust
895
star
3

static-assertions

Ensure correct assumptions about constants, types, and more in Rust
Rust
566
star
4

Sage

A cross-platform chess library for Swift
Swift
376
star
5

impls

A Rust macro to determine if a type implements a logical trait expression
Rust
246
star
6

Menubar-Colors

A macOS app for convenient access to the system color panel
Swift
175
star
7

fruity

Rusty bindings for Apple libraries
Rust
169
star
8

swift-bindgen

Bridging the gap between Swift and Rust
Rust
149
star
9

Unreachable

Unreachable code path optimization hint for Swift
Swift
103
star
10

Threadly

Type-safe thread-local storage in Swift
Swift
74
star
11

condtype

Choose Rust types at compile-time via constants
Rust
59
star
12

embed-plist-rs

Embed property list files like Info.plist directly in your Rust executable binary
Rust
39
star
13

Roman

Seamless Roman numeral conversion in Swift
Swift
36
star
14

rosy

Rust and Ruby, sitting in a tree 🌹
Rust
23
star
15

byte-set-rs

Efficient sets of bytes for Rust
Rust
19
star
16

cargo-emit

Talk to Cargo easily at build time
Rust
16
star
17

Clockmoji

Simple and intuitive time formatting using clock emoji.
Swift
13
star
18

XO

A cross-platform tic-tac-toe library for Swift
Swift
13
star
19

Lazy

Save the hard work for later, lazily evaluate values anywhere
Swift
12
star
20

Weak

Weak and Unowned as native Swift types
Swift
10
star
21

typebool

Type-level booleans in Rust for compile-time hackery
Rust
8
star
22

c-utf8-rs

UTF-8 encoded C strings for Rust
Rust
6
star
23

malloced

A malloc-ed box pointer type for Rust
Rust
5
star
24

dotfiles

Personal dotfiles
Shell
5
star
25

aloxide

Compile Rubies on Linux, macOS, and Windows
Rust
5
star
26

mods

Simpler Rust module declaration
Rust
5
star
27

bit-collection-rs

Iterate over bits in Rust
Rust
5
star
28

unsafe-unwrap-rs

Unsafely unwrap Result and Option types without checking in Rust
Rust
5
star
29

uncon-rs

Unchecked and unsafe type conversions in Rust
Rust
4
star
30

head-rs

Common Rust types with inline headers, such as HeaderVec for Vec
Rust
4
star
31

bad-rs

Unlicensed bad ideas
Rust
4
star
32

rust-workshop

A workshop on the Rust programming language
3
star
33

OneOrMore

A Swift collection of one or more elements
Swift
3
star
34

fmty

Rust library of composable `core::fmt` utilities
Rust
3
star
35

mem-cmp-rs

Safe memory comparison between types in Rust
Rust
2
star
36

ShiftOperations

A µframework for a needed ShiftOperations protocol that does not appear in the Swift standard library
Swift
1
star
37

rust-selector-example

My attempt at creating Objective-C selectors in Rust at compile time
Shell
1
star
38

asygnal

Handle signals (e.g. ctrl-c) efficiently and asynchronously in Rust
Rust
1
star
39

chance-rs

Random number generation in Rust
Rust
1
star