Access root file created by script Swift - 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)

Related

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 :)

How do I get the path of the "/Library/Containers/" directory

A sandboxed MacOS app can easily access data in two folders ...
~/Library/Containers/ProgramName/
~/Library/Group Containers/SecurityGroupName/
The following code will give me the "~/Library/Group Container/" path ...
let fileManager = FileManager.default
let directory = fileManager.containerURL(forSecurityApplicationGroupIdentifier: "myGroup")
print("path:",directory)
This will print:
"path: /Users/myName/Library/Group Containers/myGroup"
I want to get the path of the "~/Library/Containers/" directory, not the "~/Library/Group Containers/" directory.
This must be easy to do, as it is a common directory.
Does anybody know how to do this using a swift function.
I know I can just create it with ...
var path: String = "/Users/etc/Containers/" + programName
Ian
In the sandbox the API
let url = try FileManager.default.url(for: .libraryDirectory,
in: .userDomainMask,
appropriateFor: nil,
create: false)
points to the user library of the container of the current app.
file:///Users/myself/Library/Containers/com.myself.Greatapp/Data/Library/
You don't have access to the higher level folder ~/Library/Containers

Find current file path in Swift with Linux

Simple googling would lead me to the code:
let fileManager = FileManager.defaultManager()
// Get current directory path
let path = fileManager.currentDirectoryPath
print(path)
However, defeaultManager seems not to be accessible in Linux.
How can I find the current path using either Foundation or Glib in swift?
That code is for Swift 3. Here is the code for swift 4:
let fileManager = FileManager.default
// Get current directory path
let path = fileManager.currentDirectoryPath
print(path)

Copy TPK file from AppGroup Container to Documents

I have a file that exists within the AppGroup Shared Container and I was wondering if it was possible to copy the file from the Shared Container into the application bundle.
I am getting the file path as follows :
let filePath = NSFileManager.defaultManager().containerURLForSecurityApplicationGroupIdentifier("group.com.sharedBasemap")!.URLByAppendingPathComponent("localLayer.tpk")!.path
The reason I am trying to do this is it seems that the ArcGIS SDK will not recognize the TPK file from within the App Group so I am wondering if it will recognize it if I copy it into the app bundle.
EDIT: Based on Leo's comment it appears that you can not copy to the bundle, so I am trying to copy to the App Support folder.Here is my code now, I see the "file exists" message but then it is displaying the Oops message indicating it can not move the file :
let filePath = NSFileManager.defaultManager().containerURLForSecurityApplicationGroupIdentifier("group.com.sharedBasemap")!.URLByAppendingPathComponent("localLayer.tpk")!.path!
let appSupportFolder = String(NSFileManager.defaultManager().URLsForDirectory(.ApplicationSupportDirectory, inDomains: .UserDomainMask)[0]) + "localLayer.tpk"
let fileManager = NSFileManager.defaultManager()
if NSFileManager.defaultManager().fileExistsAtPath(filePath){
print("File exists at \(filePath)")
do {
try fileManager.copyItemAtPath(filePath, toPath: appSupportFolder)
}
catch let error as NSError {
print("Ooops! Something went wrong: \(error)")
}
} else {
print("File does not exist")
}
EDIT 2: I have modified the code again to just move the TPK file into the documents directory.I believe that piece is working but I receive an error message when trying to load the TPK file into ArcGIS.At this point in time, I am thinking that the issue is related to the ArcGIS SDK and that it does not support loading a TPK file from anywhere except the application bundle.
let destPath = NSSearchPathForDirectoriesInDomains(.DocumentDirectory, .UserDomainMask, true).first!
let fullDestPath = NSURL(fileURLWithPath: destPath).URLByAppendingPathComponent("localLayer.tpk")
let fullDestPathString = fullDestPath!.path!
im pretty sure the appSupportFolder doesn't exist by default -- nobody creates it unless needed -- try to verify that first and create it if needed
pseudocode if(!fileExists(supportFolder)) { createDirectory(supportFolder) }

How to read file data Applications document directory in 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!