johnsundell / files Goto Github PK
View Code? Open in Web Editor NEWA nicer way to handle files & folders in Swift
License: MIT License
A nicer way to handle files & folders in Swift
License: MIT License
Just wondering why Files uses strings instead of URLs?
Apple states:
Where possible, you should use instances of NSURL to represent paths—the operating system deals with URLs more efficiently than with string representations of paths.
Sorry if this "meta" question is out of place in the issue queue.
This breaks Packages that depend on Files
and want to support Swift 4.0 on Linux.
Code:
import Foundation
import Files
print(Folder.current.path)
print(Folder.home.path)
Xcode run
or marathon run
output is right.
/Users/xxx/Desktop/AppIcon/
/Users/xxx/
When I use command application: exec
, output result is wrong.
/Users/xxx/
/Users/xxx/
The following explains that the folder 'clone' failed to delete.
Failed to delete item: Folder(name: clone, path: /Users/robertnash/.marathon/Scripts/Temp/https:--github.com-johnsundell-testdrive.git/clone/)
- deleteFailed : Folder(name: clone, path: /Users/robertnash/.marathon/Scripts/Temp/https:--github.com-johnsundell-testdrive.git/clone/)
This is likely a permissions issue or some other trivial problem. But I'm more interested in how to find the underlying error.
What's your opinion on capturing the underlying error here ?
public func delete() throws {
do {
try fileManager.removeItem(atPath: path)
} catch let underlyingError as NSError {
throw OperationError.deleteFailed(self, underlyingError)
} catch {
throw OperationError.deleteFailed(self, _)
}
}
Or something like that.
Taking inspiration from NSError, further investigation into an error could be done by unwrapping objects associated with keys like NSUnderlyingErrorKey or NSValidationMultipleErrorsError.
Hi, I am using Swift 4.1 on Linux Debian and I am getting the following error.
/home/rock64/FileCreator/.build/checkouts/Files.git-4953067514002805256/Sources/Files.swift:1040:34: error: cannot invoke initializer for type 'Bool' with an argument list of type '(ObjCBool)'
var boolValue: Bool { return Bool(self) }
The new File.open() is only defined if AppKit can be imported. However, in a Mac Catalyst app, AppKit is available but NSWorkspace is not. This result in a compilation when adding Files.swift to a Mac Catalyst project.
I want to rename some folders recursively. For example, I have a folder structure:
Folder1
-Folder2
And I want to replace "Folder" word with "Project" word. When I use Folder.makeSubfolderSequence(recursive:includeHidden:)
method, I can't rename Folder2
after Folder1
renaming, because it has old path - Folder1/Folder2
. How I can deal with it? Maybe Item.rename(to:keepExtension:)
method should update paths of subfolders?
Hi
While installing in the package getting the below error:-
**error: dependency graph is unresolvable; found these conflicting requirements:
Dependencies:
https://github.com/JohnSundell/Files @ 4.1.1..<5.0.0**
Any help will really be appreciated.
In Package file:-
.package(
url: "https://github.com/JohnSundell/Files",
.upToNextMajor(from: "4.1.1")
),
Thanks,
Aanchal
Hey @JohnSundell 👋
The Files 4.0 release looks great, lots a solid improvements. Those improvements, however, have broken some of the open PRs that myself and others have written. I'm wondering whether it's worth the effort to update my PRs to work with 4.0 or whether those updates will be for naught. I'd love to see them merged, but don't want to waste any time.
If those PRs won't ever be merged, will you let me and others know so we can close them out?
Best,
Clay
Discussion
Would it be better to return instances of URL wherever possible, instead of stringPath ?
URL objects are the preferred way to refer to local files. Most objects that read data from or write data to a file have methods that accept an NSURL object instead of a pathname as the file reference. For example, you can get the contents of a local file URL as an NSString object using the init(contentsOf:encoding:) initializer, or as an NSData object using the init(contentsOf:options:) initializer.
You can also use URLs for interapplication communication. In macOS, the NSWorkspace class provides the open(:) method to open a location specified by a URL. Similarly, in iOS, the UIApplication class provides the openURL(:) method.
Additionally, you can use URLs when working with pasteboards, as described in NSURL Additions Reference (part of the AppKit framework).
The NSURL class is “toll-free bridged” with its Core Foundation counterpart, CFURL. See Toll-Free Bridging for more information on toll-free bridging.
Often I use simple error handling in catch
block:
print("\(error.localizedDescription)")
For pretty-printed error messages I add confirmation of LocalizedError
protocol and implement localizedDescription
property. What's your opinion about this approach? Why you don't use it?
In Files-mac-OS, 40 / 43 tests failed due to the following error,
Error Domain=NSCocoaErrorDomain Code=513 "“AppTranslocation” couldn’t be removed because you don’t have permission to access it." UserInfo={NSFilePath=/var/folders/rz/_1zd0tj50rdbrdpy47j1s6j40000gn/T/AppTranslocation/, NSUserStringVariant=(
Remove
), NSUnderlyingError=0x101953f10 {Error Domain=NSPOSIXErrorDomain Code=66 "Directory not empty"}}
Hi,
There seems to be a danger passing File
around, by reference.
If I have the following
let file = try folder.file(named: "name.pdf")
And I pass it into the following function.
func store(_ file: File) throws
Moving forward, if I interact with this same File
reference, it may no longer have a valid path. The store
function above may perform moveItem
, for example.
Perhaps we could create an alias?
Might it be worth making a distinction between a File
that you know exists and a PotentialFile
that hasn't been confirmed to exist? You see this kind of 'evaluate at last minute' mentality throughout Swift.
The same kind of mentality as
I suppose we would have to handle a change in state, in both directions.
PotentialFile
becoming File
File
becoming PotentialFile
Perhaps we could harness this API?
Have you considered extending files with this?
let observer = try FileObserver(file: file)
observer.start {
print("File was changed")
}
Some guy called @JohnSundell wrote this as a blog post 😜 #SwiftBySundell
class FileObserver {
private let file: File
private let queue: DispatchQueue
private var source: DispatchSourceFileSystemObject?
init(file: File) {
self.file = file
self.queue = DispatchQueue(label: "com.myapp.fileObserving")
}
func start(closure: @escaping () -> Void) {
// We can only convert an NSString into a file system representation
let path = (file.path as NSString)
let fileSystemRepresentation = path.fileSystemRepresentation
// Obtain a descriptor from the file system
let fileDescriptor = open(fileSystemRepresentation, O_EVTONLY)
// Create our dispatch source
let source = DispatchSource.makeFileSystemObjectSource(fileDescriptor: fileDescriptor,
eventMask: .write,
queue: queue)
// Assign the closure to it, and resume it to start observing
source.setEventHandler(handler: closure)
source.resume()
self.source = source
}
}
Hi,
There is API for the docs directory, but it's not public. Any reason for this?
The 'home' API seems to work as follows
let home = Folder.home.path
macOS: /Users/robertnash/
iOS: /Users/robertnash/Library/Developer/CoreSimulator/Devices/91BA8C3F-9B72-42AB-89D1-6401B183E5EB/data/Containers/Data/Application/
The docs directory is a little deeper.
let documentDirectory = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first!
macOS: file:///Users/robertnash/Documents/
iOS: file:///Users/robertnash/Library/Developer/CoreSimulator/Devices/91BA8C3F-9B72-42AB-89D1-6401B183E5EB/data/Containers/Data/Application/A568FA48-5C29-4368-9123-008EAC5DA331/Documents/
Would be good to get the applicationSupportDirectory too
let storeDirectory = FileManager.default.urls(for: .applicationSupportDirectory, in: .userDomainMask).first!
macOS: file:///Users/robertnash/Library/Application%20Support/
iOS: file:///Users/robertnash/Library/Developer/CoreSimulator/Devices/91BA8C3F-9B72-42AB-89D1-6401B183E5EB/data/Containers/Data/Application/A568FA48-5C29-4368-9123-008EAC5DA331/Library/Application Support/
Trying to locate the actual path where my project is located. for example, Users/userName/Desktop/porjectName.
however, when I run:
Folder.current.path
I get the following:
/Users/userName/Library/Developer/Xcode/DerivedData/projectName-ajpbrmlcmenwspeipndfoqpvyzce/Build/Products/Debug/
perhaps this is not how I get the actual directory of the project, if not, can someone please help to figure out how I can get the project directory as in "Users/userName/Desktop/porjectName."
I am using macOS commandLine tool btw,
thank you
Hi, John! I want to copy existing file to another folder. How I can do it? I found only Item.move(to:)
method, but I want to keep original file.
It would be great to have a way of getting all files in a folder using a glob pattern
let files = folder.glob("*.swift")
You could use Glibc.glob
on Linux and Darwin.glob
on Darwin
Hi I have next code:
guard
let url = self.documentDirURL,
let folder = try? Folder(path:url.path)
else { return }
DispatchQueue.global().async {
folder.makeSubfolderSequence(recursive: true).forEach { folder in
let list = folder.subfolders.filter({
$0.extension == self.projectExtention && $0.nameExcludingExtension != self.excludeProject
}).flatMap { $0.parent }
urls += list
}
}
as you may see - it scans all subfolders for subfolders with specific extension excluding specific filename, and put their parent folders in a list.
But when I put it in a DispatchQueue.global().async {} block (as shown above) - it stops at
while let parentReferenceRange = path.range(of: "../") {
line in method
func pathByFillingInParentReferences(for path: String, prependCurrentFolderPath: Bool = false) throws -> String {
with error: Thread 2: EXC_BAD_ACCESS (code=2, address=0x70000bf20ff0)
In a stack I see over 1000 calls of FileSystemIterator.next()
, so I think it's a recursion.
What I did wrong and how to fix it?
For the longest time, I was under the impression that the following would throw, if the file (or folder) didn't exist.
let rulesDocument = try folder.file(named: "Rules.pdf")
The code seems to read: "Try to build a path to this file named Rules.pdf
at this location."
Similar to how a browser might behave if you "try" a URL to nowhere.
Might it be worth making a distinction between a File that you know exists and a PotentialFile that hasn't been confirmed to exist? You see this kind of 'evaluate at last minute' mentality throughout Swift.
The same kind of mentality as
Hello, yes, my English is still so bad.
I recently tried to write a Cloud Document manager in Files, and I found that in a particular case, the loadModificationDate method might crash my application. My guess is that Cloud is downloading or synchronizing files.
I tried to find the reason, and finally found that try! fileManager.attributesOfItem(atPath: path) is likely to make a mistake, because at this time it may not be able to get any attributes at all. Or return attributes[FileAttributeKey.modificationDate] as! Date is wrong because it may not have this attribute.
So I think Files, the way to read file attributes, should be nil. This makes Files more rigorous..
Just like this:
func loadModificationDate() -> Date? {
let attributes = try? fileManager.attributesOfItem(atPath: path)
return attributes?[FileAttributeKey.modificationDate] as? Date
}
Hey @JohnSundell
Love the work you're doing for the community!
I must be doing something stupid as I just cannot figure this out. I am testing Files, for the first time and followed the read me. So, I created a script with the very following:
let folder = try Folder(path: "/Users/robert/TestFolder")
let file = try folder.createFile(named: "file.json")
try file.write(string: "{\"hello\": \"world\"}")
What I expected
For a folder named 'TestFolder' to be created in the /Users/robert/
directory
What actually happened
I received the following error in Terminal
💥 Failed to run script
👉 Fatal error: Error raised at top level: Invalid path given: /Users/robert/TestFolder/: file /BuildRoot/Library/Caches/com.apple.xbs/Sources/swiftlang_Fall2018/swiftlang_Fall2018-1000.11.37.1/src/swift/stdlib/public/core/ErrorType.swift, line 191
/bin/bash: line 1: 21533 Illegal instruction: 4 /Users/robert/.marathon/Scripts/Cache/-Users-robert-Developer-MyApp-Scripts-TestScript/.build/debug/TestScript
Is there something I am misunderstanding or doing wrong here?
If I create the folder manually, the script works and adds the file.json
to the folder. Its the folder creation that seems to be the issue.
Appreciate any insight / help into this
Thanks for Files
! I wrote a script with it for a database validation task at work, had a very nice warm feeling being able to write Swift scripts 😄
I have a suggestion though, I was a bit surprised that Files
's writes only override but no support for appending. Can we have file append? Similar to >>
in bash.
I'm happy to create a PR, but I want to make sure if this sounds like a good addition. I'm thinking to add new methods func append(data: Data) throws
and its string counterpart. Or, we could change write to func write(data: Data, shouldAppend: Bool = false) throws
. I prefer the former though, let me know what you think.
let folders = Array(try Folder(path: "/xx/xx/").makeSubfolderSequence(recursive: true, includeHidden: false));
This is the swift code, I'm not running in the main thread main, and when my files are less, it's no problem. But if I have more files (about 150), there will be a problem, and Xcode directly locate the error.
CurrentChildIterator = childIteratorQueue.removeFirst()
I can't understand what this is, and I hope to be able to get the solution.
Can yo add method to a file, which will no replace current content in the file but instead add a new content at the end on the file, please.
UPD. I see that community already done it. I tested the parallel branch with that functional. It work nice.
A lot of the below code from the docs is causing me issue:
let folder = try Folder(path: "/users/john/folder")
let file = try folder.createFile(named: "file.json")
try file.write(string: "{\"hello\": \"world\"}")
try file.delete()
try folder.delete()
That first line gives:
Incorrect argument label in call (have 'path:', expected 'storage:')
As the init(path:) is in the parent protocol extension, I'm not sure quite how this works. This project is making me see there is a lot I don't know about swift.
Any help or input is appreciated.
Since the Swift Package Manager is now integrated into Xcode, all of my open source projects will stop supporting CocoaPods + Carthage starting with their next major version, which for Files will be 5.0
. There's no set timeline for when Files 5.0
will be released, it might take months (or even years), but I just want to give all users who depend on Files using either of those two package managers a heads-up so that you can plan accordingly.
In the current implementation there's a privet extension on FileManager
with this cool method: itemKind(atPath path: String) -> FileSystem.Item.Kind?
.
I'd love to see something like this being public, so it's easier to decide what we can do with this item.
We can make current implementation public
by simply creating wrapper in FileSystem
, but the problem is that this method relies of existence of this Item
, so we can't simply say: itemKind(atPath: "fake/path/to/something.txt")
, cause we'll get nil
. We can use URL
's method called hasDirectoryPath()
, but strangely, Xcode shows warning, so I had to put #available
check (which is kinda limiting...) as this API is available since iOS 9.
This kind of functionality can bring a nice and unified way of creating new Items
at specific path, like: createItem(atPath: String) -> Item
and createItemIfNeeded(atPath: String) -> Item
.
What do you guys think about having a method just for checking the type of Item
at specified path without requiring existence? I'm still not sure whether this isn't something beyond the scope of Files?
Hello, really nice lib. Did you plan swift 4 migration ?
I added Files as dependency to sasha project. Everything worked fine, but now I have an error during build:
artemnovichkov@ sasha (master) $ swift build -c release -Xswiftc -static-stdlib
Compile Swift Module 'Swiftline' (28 sources)
Compile Swift Module 'Files' (1 sources)
/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.13.sdk/System/Library/Frameworks/Foundation.framework/Headers/Foundation.apinotes:8:28: error: unknown key 'SwiftImportAsNonGeneric'
SwiftImportAsNonGeneric: true
^
<unknown>:0: error: could not build Objective-C module 'Foundation'
/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.13.sdk/System/Library/Frameworks/Foundation.framework/Headers/Foundation.apinotes:8:28: error: unknown key 'SwiftImportAsNonGeneric'
SwiftImportAsNonGeneric: true
^
<unknown>:0: error: could not build Objective-C module 'Foundation'
<unknown>:0: error: build had 2 command failures
error: exit(1): /Applications/XcodeOLD.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/swift-build-tool -f /Users/artemnovichkov/Documents/Projects/sasha/.build/release.yaml
What I do wrong? BTW, I use Xcode GM.
My Xcode is 9.0.1, macOS 10.12.6. I used cocoapods(1.3.1) to integrate this library (1.12.0).
After that, I can see a new folder named "Files" under my "Pods" folder
When I tried to use "import Files", I got this compile error - "Can't load underlying module for 'Files'"
Can you help me to work it out? Thank you.
A
B
inside A
C
inside B
.
├─ A
└─ B
└─ C
B
to same level as A
.
├─ A
├─ B
└─ C
C
with b.subfolder(named: "C")
- errorInvalid path given: /Users/clay/.filesTest/BC/
This is because move(to:)
removes the trailing /
from the moved item's path. I'm submitting a PR that fixes this along with a test to catch this in the future.
Hey ! Could you upload the latest version to cocoapods ?
Cheers
Fully appreciate the work you have put in to this.
Humbly ask: Would be good to have a bit more documentation?
Struggled a bit with #57
When asking if a folder contains a file, the API is currently
let folder = try Folder(named: "Foo")
let contains: Bool = folder.containsFile(named: "NameOfFile")
Could we extend this to handle an actual file variable instead?
let file: File = ...
let folder = try Folder(named: "Foo")
let contains: Bool = folder.containsFile(file)
An interesting point to add: I was getting a false result when using name
instead of nameExcludingExtension
.
let name = file.nameExcludingExtension
let doesContain = folder.containsFile(named: name) // true
let name = file.name
let doesContain = folder.containsFile(named: name) // false
I can understand why this happens, but it was unexpected at first.
Hello,
I was running the tests on official Swift Docker image while working on #5 (fed3fb9), and encountered three failures.
Here's the test log:
$ swift test
Compile Swift Module 'Files' (1 sources)
Compile Swift Module 'FilesTests' (1 sources)
Linking ./.build/debug/FilesPackageTests.xctest
Test Suite 'All tests' started at 18:19:24.811
Test Suite 'debug.xctest' started at 18:19:24.811
Test Suite 'FilesTests' started at 18:19:24.812
Test Case 'FilesTests.testCreatingAndDeletingFile' started at 18:19:24.812
Test Case 'FilesTests.testCreatingAndDeletingFile' passed (0.002 seconds).
Test Case 'FilesTests.testCreatingAndDeletingFolder' started at 18:19:24.814
Test Case 'FilesTests.testCreatingAndDeletingFolder' passed (0.001 seconds).
Test Case 'FilesTests.testRenamingFile' started at 18:19:24.815
Test Case 'FilesTests.testRenamingFile' passed (0.001 seconds).
Test Case 'FilesTests.testRenamingFileWithNameIncludingExtension' started at 18:19:24.815
Test Case 'FilesTests.testRenamingFileWithNameIncludingExtension' passed (0.001 seconds).
Test Case 'FilesTests.testReadingFileWithRelativePath' started at 18:19:24.816
Test Case 'FilesTests.testReadingFileWithRelativePath' passed (0.001 seconds).
Test Case 'FilesTests.testReadingFileWithTildePath' started at 18:19:24.816
Test Case 'FilesTests.testReadingFileWithTildePath' passed (0.001 seconds).
Test Case 'FilesTests.testRenamingFolder' started at 18:19:24.817
Test Case 'FilesTests.testRenamingFolder' passed (0.0 seconds).
Test Case 'FilesTests.testMovingFiles' started at 18:19:24.817
Test Case 'FilesTests.testMovingFiles' passed (0.001 seconds).
Test Case 'FilesTests.testEnumeratingFiles' started at 18:19:24.818
Test Case 'FilesTests.testEnumeratingFiles' passed (0.001 seconds).
Test Case 'FilesTests.testEnumeratingFilesIncludingHidden' started at 18:19:24.819
Test Case 'FilesTests.testEnumeratingFilesIncludingHidden' passed (0.001 seconds).
Test Case 'FilesTests.testEnumeratingFilesRecursively' started at 18:19:24.820
Test Case 'FilesTests.testEnumeratingFilesRecursively' passed (0.001 seconds).
Test Case 'FilesTests.testEnumeratingSubfolders' started at 18:19:24.821
Test Case 'FilesTests.testEnumeratingSubfolders' passed (0.001 seconds).
Test Case 'FilesTests.testEnumeratingSubfoldersRecursively' started at 18:19:24.822
/root/Files/Tests/FilesTests/FilesTests.swift:227: error: FilesTests.testEnumeratingSubfoldersRecursively : XCTAssertEqual failed: ("["1", "2", "1B", "1A", "2B", "2A"]") is not equal to ("["1", "2", "1A", "1B", "2A", "2B"]") -
Test Case 'FilesTests.testEnumeratingSubfoldersRecursively' failed (0.001 seconds).
Test Case 'FilesTests.testFirstAndLastInFileSequence' started at 18:19:24.824
/root/Files/Tests/FilesTests/FilesTests.swift:238: error: FilesTests.testFirstAndLastInFileSequence : XCTAssertEqual failed: ("Optional("C")") is not equal to ("Optional("A")") -
/root/Files/Tests/FilesTests/FilesTests.swift:239: error: FilesTests.testFirstAndLastInFileSequence : XCTAssertEqual failed: ("Optional("B")") is not equal to ("Optional("C")") -
Test Case 'FilesTests.testFirstAndLastInFileSequence' failed (0.001 seconds).
Test Case 'FilesTests.testParent' started at 18:19:24.825
Test Case 'FilesTests.testParent' passed (0.001 seconds).
Test Case 'FilesTests.testRootFolderParentIsNil' started at 18:19:24.826
Test Case 'FilesTests.testRootFolderParentIsNil' passed (0.0 seconds).
Test Case 'FilesTests.testOpeningFileWithEmptyPathThrows' started at 18:19:24.826
Test Case 'FilesTests.testOpeningFileWithEmptyPathThrows' passed (0.0 seconds).
Test Case 'FilesTests.testDeletingNonExistingFileThrows' started at 18:19:24.827
Test Case 'FilesTests.testDeletingNonExistingFileThrows' passed (0.001 seconds).
Test Case 'FilesTests.testWritingDataToFile' started at 18:19:24.827
Test Case 'FilesTests.testWritingDataToFile' passed (0.012 seconds).
Test Case 'FilesTests.testWritingStringToFile' started at 18:19:24.840
Test Case 'FilesTests.testWritingStringToFile' passed (0.011 seconds).
Test Case 'FilesTests.testFileDescription' started at 18:19:24.851
Test Case 'FilesTests.testFileDescription' passed (0.001 seconds).
Test Case 'FilesTests.testFolderDescription' started at 18:19:24.852
Test Case 'FilesTests.testFolderDescription' passed (0.0 seconds).
Test Case 'FilesTests.testAccessingHomeFolder' started at 18:19:24.852
Test Case 'FilesTests.testAccessingHomeFolder' passed (0.0 seconds).
Test Case 'FilesTests.testNameExcludingExtensionWithLongFileName' started at 18:19:24.853
Test Case 'FilesTests.testNameExcludingExtensionWithLongFileName' passed (0.001 seconds).
Test Case 'FilesTests.testUsingCustomFileManager' started at 18:19:24.853
Test Case 'FilesTests.testUsingCustomFileManager' passed (0.001 seconds).
Test Case 'FilesTests.testAccessingDocumentFolder' started at 18:19:24.854
Test Case 'FilesTests.testAccessingDocumentFolder' passed (0.0 seconds).
Test Case 'FilesTests.testAccessingLibraryFolder' started at 18:19:24.854
Test Case 'FilesTests.testAccessingLibraryFolder' passed (0.0 seconds).
Test Suite 'FilesTests' failed at 18:19:24.854
Executed 27 tests, with 3 failures (0 unexpected) in 0.041 (0.041) seconds
Test Suite 'debug.xctest' failed at 18:19:24.855
Executed 27 tests, with 3 failures (0 unexpected) in 0.041 (0.041) seconds
Test Suite 'All tests' failed at 18:19:24.855
Executed 27 tests, with 3 failures (0 unexpected) in 0.041 (0.041) seconds
System information:
DISTRIB_ID=Ubuntu
DISTRIB_RELEASE=16.04
DISTRIB_CODENAME=xenial
DISTRIB_DESCRIPTION="Ubuntu 16.04.1 LTS"
NAME="Ubuntu"
VERSION="16.04.1 LTS (Xenial Xerus)"
ID=ubuntu
ID_LIKE=debian
PRETTY_NAME="Ubuntu 16.04.1 LTS"
VERSION_ID="16.04"
HOME_URL="http://www.ubuntu.com/"
SUPPORT_URL="http://help.ubuntu.com/"
BUG_REPORT_URL="http://bugs.launchpad.net/ubuntu/"
VERSION_CODENAME=xenial
UBUNTU_CODENAME=xenial
Swift version 3.0.2 (swift-3.0.2-RELEASE)
Dear John,
Thank you for the excellent lib. I am trying to learn how to use it. How can I iterate over all files with .md
extension in the current folder?
I am stuck with:
for file in try Folder(path: Folder.current).files {
...
}
What is the proper use?
Thank you.
Good day.
Is it possible to expand the current methods of writing and reading files, adding the ability to use encryption, as is common in the documentation?
Thank you!
Hi @JohnSundell ,
I'm enjoying the Files API and I'm glad I can help in any way. Even if my contributions are just discussion points that lead to potential pull requests from others.
I have, yet another, discussion point to raise. I hope you don't mind.
Unless I examine the source, it's not clear here if newName
is name only
or name + extension
.
public func rename(to newName: String, keepExtension: Bool = true) throws
Further, I currently have a situation where the above API is inconvenient.
At the moment I'm unpacking a .pdf file from a CKAsset instance (CloudKit).
.pdf
extension.Perhaps, we might want to have something like the following?
public func rename(to newName: String) throws
And maybe we can examine the name to see if it contains a "."
Do you think this is a valid issue and do you have any ideas on this?
First of all thanks for a great job like "Files";
It would be great to obtain bytesWritten/totalBytesInFile.
This way it would be possible to control the traffic and implement progressIndicators or some other visual progress help.
Thanks for all.
Hello,
As a new to Swift developer, I found your great code when trying to manipulate files!
With my Swift knowledge being not so shiny so far, my problem is that your example codes generate errors in Xcode (Version 11.3.1), so they just cannot be build and run.
E.g you wrote:
Move all files in a folder to another:
let originFolder = try Folder(path: "/users/john/folderA")
let targetFolder = try Folder(path: "/users/john/folderB")
try originFolder.files.move(to: targetFolder)
Now Xcode gives me the same error at all the above lines:
Errors thrown from here are not handled.
So what is the proper coding to use Files?
E.g. what is the full code to move all files in a folder to another? Could you put it down it, please?
Thanks a lot in advance!
Devy
Hi
Thanks for a nice library! Very useful. I run my code thru swiftlint (https://github.com/realm/SwiftLint) and got a bunch of warnings on this code. You should maybe do this to. With regards, Johan
What are your thoughts on removing the .xcodeproj
from the repo in favor of generating it using swift package generate-xcodeproj
?
I was going to submit a quick PR to update Files to Swift 4.2, but I noticed that the .xcodeproj
is committed to the repo. I was going to gitignore it, since that seems recommended for SPM libraries, but I wanted to ask first.
Note: This will require Codable
from Swift 3.2/4, which is why I'm not submitting a PR for this yet.
This is a proposal for adding convenience methods to use the Codable
protocol, to allow reading a File
directly to a decoded object type.
Example JSON Decodable
convenience:
extension File {
func readAsDecodedJSON<D: Decodable>(using decoder: JSONDecoder = .init()) throws -> D {
let fileData = try read()
return try decoder.decode(D.self, from: fileData)
}
}
Example JSON Decodable
call site:
let myObjectFile = File(path: ...)
let myObject: DecodedJSONObject = try myObjectFile.readAsDecodedJSON()
Hello,
let rootFolder = try Folder(path: "/")
let subfolder = rootFolder.subfolders.first
print(subfolder?.parent?.path)
Expected result: Optional("/")
Actual result: current working directory
Because of this bug, iterating over a folder parents triggers an inifinite loop.
I will submit a pull request with the fix.
When setting up a permanent directory structure for an App, it might be good to create dedicated subclasses of Folder for frequent use. Could the following code be inside a failable initialiser?
var rulesFolder: Folder {
let folder = try! Folder(path: FileSystem().homeFolder.path)
let documents = try! folder.subfolder(named: "Documents")
return try! documents.createSubfolderIfNeeded(withName: "Rules")
}
RulesFolder.swift
init?() {
do {
// self =
} catch {
return nil
}
}
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.