How to read file data Applications document directory in swift? - swift

I am new at Swift programming language. I want to download a movie from some tube servers and want to play offline. I am using Alamofire for downloading part. I can list the file(s) with that:
var file:String?
if let files = NSFileManager.defaultManager().contentsOfDirectoryAtPath(documentsDirectory, error: &error) as? [String] {
for filename in files {
// do stuff with filename
file = filename
println(filename)
}
}
But the problem is how i can use that file for my purpose. Let assume its image file and i want to show in imageview.
myImageView.image = UIImage(contentsOfFile: file) /* doesn't work*/
thank you for any help.

For Swift 2 you have to change something. Note: stringByAppendingPathComponent is not more available on String (only NSString):
var paths = NSSearchPathForDirectoriesInDomains(.DocumentDirectory, .UserDomainMask, true)[0] as NSString
var getImagePath = paths.stringByAppendingPathComponent("filename")
myImageView.image = UIImage(contentsOfFile: getImagePath)

Try this code:
var paths = NSSearchPathForDirectoriesInDomains(.DocumentDirectory, .UserDomainMask, true)[0] as String
var getImagePath = paths.stringByAppendingPathComponent("filename")
myImageView.image = UIImage(contentsOfFile: getImagePath)
I hope this work.

File manage is used for below functionality, Please check once.
1) create folder in document directory or temp directory,
2) copy file from temp to document directory, move path,
3) remove from document directory,
4) list all file from document directory, list file using extension from document directory (ex: if you have .mp3 and .jpg and .text files in document directory and you want only .mp3 file),
5) save file
6) get file path
https://github.com/IosPower/FileManage

At the moment you're just passing in the name of the file to UIImage(contentsOfFile). You need to pass in the entire path, i.e.:
myImageView.image = UIImage(contentsOfFile: "\(documentsDirectory!)/\(filename)") //hopefully does work!

Related

How can I iterate inside each directory in resource path

I have a simple scenario, there is a folder called content that contains image file, I want all the image file starting with nssl to be saved to an array , so I do below code, but I cannot seem to think or know a way to find out how I can move in each directory and search for such a file and append to my array , here is my code below , I can get the names of all the directories, but what to do next ?
let path = Bundle.main.resourcePath!
let fm = FileManager.default
do {
let items = try fm.contentsOfDirectory(atPath: path)
for item in items {
}
} catch {
}
FileManager is not needed.
Bundle provides urls(forResourcesWithExtension: subdirectory:) which returns multiple urls for a specific extension
if let urls = Bundle.main.urls(forResourcesWithExtension: "png", subdirectory: "content") {
for url in urls where url.lastPathComponent.hasPrefix("nssl") {
}
}
Change the png extension to the desired type.

Vapor uploads files to DerivedData instead of the Public folder in the project structure

When I try to upload files via my Vapor server, it always uploads files into the DerivedData folder instead of the Public folder inside the project structure.
I can verify that the file is created in the path, but the path is somewhere in DerivedData directory .. why? How am I going to server such file when it's not in the project's Public folder?
My upload code:
func create(request: Request) async throws -> HTTPStatus {
try CreateDogRequest.validate(content: request)
let createDogRequest = try request.content.decode(CreateDogRequest.self)
guard let userId = try request.auth.require(User.self).id else {
throw Abort(.notFound)
}
let dogId = UUID()
let directory = DirectoryConfiguration.detect()
let publicFolder = "Public"
let folderPath = URL(fileURLWithPath: directory.workingDirectory)
.appendingPathComponent(publicFolder, isDirectory: true)
.appendingPathComponent("dogProfiles", isDirectory: true)
.appendingPathComponent(userId.uuidString, isDirectory: true)
.appendingPathComponent(dogId.uuidString, isDirectory: true)
print("Starting writing to path: \(folderPath)")
let filePath = folderPath.appendingPathComponent("hello" + ".jpg", isDirectory: false)
try FileManager.default.createDirectory(at: folderPath, withIntermediateDirectories: true)
let data = Data(buffer: createDogRequest.dogImage.data)
try data.write(to: filePath, options: .atomic)
print("file uploaded at: \(filePath.relativePath)")
return .ok
}
Now this shows that the file is uploaded here:
/Users/<USERNAME>/Library/Developer/Xcode/DerivedData/<PROJECT_HANDLE>/Build/Products/Debug/Public/dogProfiles/62C340CE-262B-4DE4-9E2A-99B3B3126BB6/hello.jpg
Why? How can I serve such file then?
I debugged the DirectoryConfiguration class and the detect() method checks if the server is running via Xcode and it looks like this:
#if Xcode
if workingDirectory.contains("DerivedData") {
Logger(label: "codes.vapor.directory-config")
.warning("No custom working directory set for this scheme, using \(workingDirectory)")
}
#endif
But the funny thing is, if I put a file inside the Resource folder to read data from, and use the DirectoryConfiguration's detect() method and create a path to that file, it finds the file no problem ??!!! Why? How? :D That is a mystery to me
This is the code that I wrote for reading from the file:
let directory = DirectoryConfiguration.detect()
let configDir = "Resources"
let path = URL(fileURLWithPath: directory.workingDirectory)
.appendingPathComponent(configDir, isDirectory: true)
.appendingPathComponent("file.txt", isDirectory: false)
.relativePath
What am I missing here? How come the file put inside Resources folder gets read, but when I want to put something inside the Public folder it gets put inside DerivedData even tho I am using the same patter when creating the path ??
You need to set a custom working directory in Xcode so Vapor knows where to looks. See https://docs.vapor.codes/getting-started/xcode/#custom-working-directory
Ooookay, once again, I tried to think differently and I googled a bit and found this post:
How to get path of root directory of your project folder in Perfect 2.0?
and the answer from worthbak pointed to the conclusion that I should rather run the server from terminal using swift run and try if the file gets created, and guess what? It does!
This also explains how the file I put in the Resources folder was read, because it is inside a migration that you run from guess where? .. the Terminal :)

Access root file created by script Swift

From this question: How can I get all image names in asset catalog group?
I want to access a file created in the root of an App in Swift.
My App is called Challenge and my script is
# Type a script or drag a script file from your workspace to insert its path.
#!/bin/sh
>./Challenge/fileNames.txt
for FILE in ./Challenge/Images.xcassets/actions/*; do
echo $FILE >> ./Challenge/fileNames.txt
done
I have tried
let fileManager = FileManager.default
let imagePath = Bundle.main.resourcePath! + "fileNames.txt"
let imageNames = try! fileManager.contentsOfDirectory(atPath: imagePath)
And many other combinations .
This is not homework, I have tried various solutions but as I am not sure where the file is within the file system (how the root can be accessed within the App) I seem unable to locate the file.
Question: How to read ./Challenge/fileNames.txt from an App called challenger, created by a script during the build phase.
The file is located in the main bundle folder, not resource path:
let fileManager = FileManager.default
let imagePath = Bundle.main.path(forResource: "fileName", ofType: "txt")
let content = try! String(contentsOfFile: imagePath)

Where do I get the OSX volume for replacing "/" [duplicate]

When using
let directoryEnumerator = FileManager().enumerator(at: ...
in Swift 3, I get all files from the folder, e.g.
"file:///Volumes/MacOS/fasttemp/Fotos/"
The results are not including the leading path (here "/Volumes/MacOS"). So I get
"file:///fasttemp/Fotos/2005/"
How can I get the fullpath (directly from the enumerator) or convert them. I want to use URL functions, not string function manipulating by assumptions.
If "MacOS" is the name of your current startup disk then "/Volumes/MacOS" is a symbolic link to "/", so both "/fasttemp/Fotos/2005/" and "/Volumes/MacOS/fasttemp/Fotos/" are absolute paths to the same file.
In order to get a unique file name representation you can query
a URL for its canonical path. Example:
let url = URL(fileURLWithPath: "/Volumes/MacOS/Applications/Utilities/")
if let cp = (try? url.resourceValues(forKeys: [.canonicalPathKey]))?.canonicalPath {
print(cp)
}
// Output: "/Applications/Utilities"
This requires macOS 10.12/iOS 10 or later. On older systems you can
use the realpath() system call:
if let rp = url.withUnsafeFileSystemRepresentation ({ realpath($0, nil) }) {
let fullUrl = URL(fileURLWithFileSystemRepresentation: rp, isDirectory: true, relativeTo: nil)
free(rp)
print(fullUrl.path)
}
// Output: "/Applications/Utilities"
Note that you want to use URL wherever possible, from the NSURL documentation:
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.
Here’s an example of how to get all the objects from a directory:
import Foundation
let manager = FileManager.default
// Get URL for the current user’s Documents directory
// Use URL instead of path, it’s more flexible and preferred
if let documents = manager.urls(for: .documentDirectory, in: .userDomainMask).first,
// Get an Enumerator for the paths of all the objects in the directory
// but do not descend into directories or packages
let directoryEnumerator = manager.enumerator(at: documents, includingPropertiesForKeys: [URLResourceKey.pathKey], options: [.skipsSubdirectoryDescendants, .skipsPackageDescendants]) {
// iterate through the objects (files, directories, etc.) in the directory
for path in directoryEnumerator {
print(path)
}
}

How do I iterate over the contents of a folder within the current working directory in Swift?

New to Swift.
Having checked that a folder called data exists within the current working directory using this code:
// Get the current working directory
let fileManager = FileManager()
let cwd = fileManager.currentDirectoryPath
var isDir: ObjCBool = false
if (fileManager.fileExists(atPath: cwd + "/data", isDirectory: &isDir)){
if (isDir.boolValue) {
// There is a directory called `data`
}
}
I cannot figure out how to iterate through the contents of the data folder. Specifically, I'm just trying to store the names of all top-level folders within the data folder. I've looked at the FileManager.contentsOfDirectory(at:includingPropertiesForKeys:options:) function but I think that takes a URL not a String and I don't know how to convert my path (cwd) to a URL.
The fileManager.contentsOfDirectory(atPath:) function does take a String but I don't think it returns an iteratable result.
Can anybody help?