Access the files/folders in the Assets folder for TVOS programmatically - ios

I am working on a TVOS 10 project with Swift 3.0 and I am trying to access the files in the Assets folder from the controller.
I have this array:
var posters: [String] = ["image1", "image2", "image3","image4", "image5"]
But I want to populate this array programmatically. So if i change the files in the assets, the content of the array should change.
Because later I do this:
//currentImage is an ImageView in storyboard
currentImage.image = UIImage(named: posters[currentPoster])
This is the hierarchy of my files.
This is what I have tried but it does not give me what I want.
if let resourcePath = Bundle.main().resourcePath {
print(resourcePath)
do {
let temp = try FileManager.default().contentsOfDirectory(atPath: resourcePath)
print(temp)
let assetsPath = resourcePath + "/" + temp[6]
let temp2 = try FileManager.default().contentsOfDirectory(atPath: assetsPath)
print (temp2)
}
catch let error as NSError {
print(error)
}
}
Output:
/var/containers/Bundle/Application/9AECCDB0-DD5F-4377-9237-6E7DA1E14A39/PosterAppTV.app
["Assets.car", "Base.lproj", "Frameworks", "Info.plist", "META-INF", "PkgInfo", "PosterAppTV", "_CodeSignature", "embedded.mobileprovision", "libswiftRemoteMirror.dylib"]
Error Domain=NSCocoaErrorDomain Code=256 "The file “PosterAppTV” couldn’t be opened." UserInfo={NSFilePath=/var/containers/Bundle/Application/9AECCDB0-DD5F-4377-9237-6E7DA1E14A39/PosterAppTV.app/PosterAppTV, NSUserStringVariant=(
Folder
), NSUnderlyingError=0x1740524e0 {Error Domain=NSPOSIXErrorDomain Code=20 "Not a directory"}}
Any help how to get a list of names of the files in the Assets/Posters folder?
Also, if this may not be possible, are there other ways to store some pictures into a folder and then access the names of those files programmatically?

When you are placing your images in assets it means xcode have remembered your all image names, there is no need to call any folder name or directory path, now you can directly call your image name in code.
Here is what you are looking for:
var posters: [String] = ["image1", "image2", "image3","image4", "image5"]
if let myImage = UIImage(named: posters[2]) {
imageView.image = myImage //image3 is called at the index of 2 in posters array
}
else {
print("image not found")
}
Or you can retrieve your images in one line like this:
imageView.image = UIImage(named: posters[2])

Related

Unsupported URL for image layer mapbox iOS

I am trying to learn mapbox maps iOS but am struggling with inserting an image layer.
The image is however, failing to load, throwing the error:
Error Domain=NSURLErrorDomain Code=-1002 "unsupported URL"
The docs for for this structure are here
Please help!!!
ViewController.swift:
mapView.mapboxMap.onNext(.mapLoaded) { _ in
self.addImageLayer()
}
internal func addImageLayer() {
var sourceId = "planet-source"
let style = mapView.mapboxMap.style
// Create an `ImageSource`. This will manage the image displayed in the `RasterLayer` as well
// as the location of that image on the map.
var imageSource = ImageSource()
// Set the `coordinates` property to an array of longitude, latitude pairs.
imageSource.coordinates = [
[-80.425, 46.437],
[-71.516, 46.437],
[-71.516, 37.936],
[-80.425, 37.936]
]
// Get the file path for the first radar image, then set the `url` for the `ImageSource` to that path.
let path = Bundle.main.path(forResource: "planet", ofType: "svg")!
imageSource.url = path
// Create a `RasterLayer` that will display the images from the `ImageSource`
var imageLayer = Layer(id: "planet-layer")
imageLayer.source = sourceId
do {
try style.addSource(imageSource, id: sourceId)
try style.addLayer(imageLayer)
} catch {
print("Failed to add the source or layer to style. Error: \(error)")
}
}

Save/create folder that it to be treated as a file with FileManager

I have a iOS/CatalystMacOS-app that can create, save, open custom text-files (with my own file extension). This works fine. However, now I need more than text. I want to save optional files in this file as well. Apparently macOS (and iOS?) can treat folders as files. But I cannot get it to work as wanted. The folder is still treated as a folder, even if it has a file extension.
This is the code I use to create the folder:
func showNewFilePathDialog(from viewController: UIViewController, saveCompleted: URLCallback?) {
guard !isPresenting else {
return
}
let objectToSave = ...
// Find an available filename
var number = 0
var exportURL: URL!
var data: Data!
var fullFileName = ""
while true {
let numberText = number == 0 ? "" : number.asString()
fullFileName = "baseFileName" + "\(numberText).myFileExtension"
exportURL = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first!.appendingPathComponent(fullFileName)
let dict = objectToSave.toDict()
let json = dict.json!
data = json.data(using: .utf8)!
if FileManager.default.fileExists(atPath: exportURL.path) {
number += 1
continue
} else {
break
}
}
do {
try FileManager.default.createDirectory(atPath: exportURL.path, withIntermediateDirectories: true, attributes: nil)
} catch {
NSLog("Couldn't create document directory")
viewController.presentErrorDialog(from: error)
return
}
// 2. Create containing json file
do {
try data.write(to: exportURL.appendingPathComponent("content.json"))
} catch {
viewController.presentErrorDialog(from: error)
return
}
isPresenting = true
self.onSaveDialogComplete = saveCompleted
let pickerViewController = UIDocumentPickerViewController(url: exportURL, in: .exportToService)
pickerViewController.delegate = self
viewController.present(pickerViewController, animated: true)
}
And then it appears like this in macOS finder:
It will show up similar in iOS, not allowing me to open the folder as a single file either.
Edit: Using UIDocument/public.composite-content/FileWrapper seems to work as well, but the problem still consists: When viewed in macOS finder it is still treated as a folder. Also when trying to open the app from the open-dialog via UIDocumentPickerViewController trying to open the file-bundle only opens the folder and wont let me open it into the app :(
This is my info.list Export Type UTIs:
Edit2: Also tried with removing all but com.apple.package but does not work either. Still cannot open my custom type as it behaves like a folder.
Got it working. Seemed as old builds of my app was interfering with the system file types. So I searched for my app name and removed old builds from my computer. Then the system recognized my file suffix and opened it right away!
But I lost the icon this time, but that's another issue :)

FireBase Storage Download Error Domain=FIRStorageErrorDomain Code=-13000

I'm Currently trying to use the quick start examples for firebase storage from github. Where you simply upload an image and then download it to a another view once that view is loaded. I can upload images to storage fine but when I try to download the images this error occurs.
Error Domain=FIRStorageErrorDomain Code=-13000 "An unknown error occurred, >please check the server response." UserInfo={bucket=****.appspot.com, >object=379f921d-a0bb-44b5-b04e-f21cc7953848/485423329797/IMG_0003.JPG, ResponseErrorDomain=NSCocoaErrorDomain, NSDestinationFilePath=/file:/Users/mark******/Library/Developer/CoreSim>ulator/Devices/B600E8B9-95ED-4963-8282-9CDD43B7C25D/data/Containers/Data/Application/8FFB7EB0-0AFD-4E10-AAB6-D7340F8E3DDB/Documents/myimage.jpg, NSLocalizedDescription=An unknown error occurred, please check the server response., NSUserStringVariant=(
Move
), NSSourceFilePathErrorKey=/Users/mark******/Library/Developer/CoreSimula>tor/Devices/B600E8B9-95ED-4963-8282->9CDD43B7C25D/data/Containers/Data/Application/8FFB7EB0-0AFD-4E10-AAB6->D7340F8E3DDB/tmp/CFNetworkDownload_5ZmlMp.tmp, NSFilePath=/Users/mark******/Library/Developer/CoreSimulator/Devices/B6>00E8B9-95ED-4963-8282->9CDD43B7C25D/data/Containers/Data/Application/8FFB7EB0-0AFD-4E10-AAB6->D7340F8E3DDB/tmp/CFNetworkDownload_5ZmlMp.tmp, NSUnderlyingError=0x7f8036a682d0 {Error Domain=NSPOSIXErrorDomain Code=2 >"No such file or directory"}, ResponseErrorCode=4}
I've checked the paths on the Firebase Storage side of things and the file paths are correct, it just can't seem to retrieve the image.
The code to download the image is in the viewdidload() func of the download file
override func viewDidLoad() {
super.viewDidLoad()
storageRef = FIRStorage.storage().reference()
let paths = NSSearchPathForDirectoriesInDomains(NSSearchPathDirectory.DocumentDirectory,
NSSearchPathDomainMask.UserDomainMask, true)
let documentsDirectory = paths[0]
let filePath = "file:\(documentsDirectory)/myimage.jpg"
let storagePath = NSUserDefaults.standardUserDefaults().objectForKey("storagePath") as! String
print("---------------")
print(filePath)
print("---------------")
print(storagePath)
// [START downloadimage]
storageRef.child(storagePath).writeToFile(NSURL.fileURLWithPath(filePath),
completion: { (url, error) in
if let error = error {
print("Error downloading:\(error)")
self.statusTextView.text = "Download Failed"
return
}
self.statusTextView.text = "Download Succeeded!"
self.imageView.image = UIImage.init(contentsOfFile: filePath)
})
// [END downloadimage]
}
}
Looks like the issue here is actually your download file path isn't correct (The error being thrown is actually an NSCocoaErrorDomain rather than a networking issue--it looks like our error message is too specific to the network).
The main issue I see is that your file path looks like /file:/Users/... while I believe that file URLs are supposed to look like file:///Users/...
I typically create local files like so like so:
NSURL *tmpDirURL = [NSURL fileURLWithPath:NSTemporaryDirectory()];
NSURL *fileURL = [[tmpDirURL URLByAppendingPathComponent:#"hello"] URLByAppendingPathExtension:#"txt"];
You can also use NSHomeDirectoryForUser to get the base directory for the user.

iOS Dropbox error loading thumbnails

I wanna get thumbnails for dropbox files that I display on a view. I know that I've to use the loadThumbnail method, but I don't get exactly how to do it.
I wrote this :
for file in dropboxMetadata.contents {
dbRestClient.loadThumbnail(file.path, ofSize: "s", intoPath: "https://api-content.dropbox.com/1/thumbnails/auto/")
}
but I get some errors like this :
error making request to /1/thumbnails/dropbox/star.jpg - (4) Error Domain=NSCocoaErrorDomain Code=4 "The operation couldn’t be completed.
Thanks for your help !
Petesh has the right idea. intoPath is the destination directory for those thumbnails.
Try this:
func createTempDirectory() -> String? {
let tempDirectoryTemplate = NSTemporaryDirectory().stringByAppendingPathComponent("XXXXX")
let fileManager = NSFileManager.defaultManager()
var err: NSErrorPointer = nil
// remove any previous temporary folder that's there, in case it's there
fileManager.removeItemAtPath(tempDirectoryTemplate)
if fileManager.createDirectoryAtPath(tempDirectoryTemplate, withIntermediateDirectories: true, attributes: nil, error: err) {
return tempDirectoryTemplate
} else {
print("can't create temporary directory at \(tempDirectoryTemplate)")
return nil
}
}
The above code for which I found in this question
Then you could change your own code to do something like:
let temporaryDirectory = createTempDirectory()
for file in dropboxMetadata.contents {
dbRestClient.loadThumbnail(file.path, ofSize: "s", intoPath: temporaryDirectory)
}
If this works, then you could change the "intoPath" parameter into any directory you think is more appropriate.

Swift: copying files gives Cocoa Error 262

I'm trying to move my files up a level in some random directory in the default Documents directory. But when copying, Swift gave me the error Cocoa Error 262: NSFileReadUnsupportedSchemeError. Why did I get this error? I ran a quick search and pretty much everyone who'd encountered this problem was trying to copy files out of the camera roll, but I'm not. Any thoughts? Thanks in advance.
Code here:
private func copyFilesInDirectory(fromDir: String, toDirectory toDir: String, withCompletionHandler handler: ()->()){
println("from: \(fromDir)\nto: \(toDir)")
var error: NSError?
var contents = fileManager.contentsOfDirectoryAtPath(fromDir, error: &error)
if let dirContents = contents{
let enumerator = (dirContents as NSArray).objectEnumerator()
while let file = enumerator.nextObject() as? String{
let filePath = fromDir.stringByAppendingString("/\(file)")
println("copying \(filePath)")
if(fileManager.copyItemAtURL(NSURL(fileURLWithPath: filePath)!, toURL: NSURL(string: toDir)!, error: &error)){
println("COPIED")
}
else{
println("COPY ERROR: \(error!.localizedDescription)")
}
}
handler()
}
}
and here's the log if anyone's interested:
from: /Users/dolce/Library/Developer/CoreSimulator/Devices/05566649-BABB-44BE-BE6F-AFF7B41E3065/data/Containers/Data/Application/F5A83C94-C177-4826-BDD5-3A50E7508239/Documents/Hello/tmp
to: /Users/dolce/Library/Developer/CoreSimulator/Devices/05566649-BABB-44BE-BE6F-AFF7B41E3065/data/Containers/Data/Application/F5A83C94-C177-4826-BDD5-3A50E7508239/Documents/Hello
copying /Users/dolce/Library/Developer/CoreSimulator/Devices/05566649-BABB-44BE-BE6F-AFF7B41E3065/data/Containers/Data/Application/F5A83C94-C177-4826-BDD5-3A50E7508239/Documents/Hello/tmp/test.png
COPY ERROR: The operation couldn’t be completed. (Cocoa error 262.)
The toURL parameter of copyItemAtURL() must not be the destination
directory, but the URL of the destination file. This can be
created with
let destPath = toDir.stringByAppendingPathComponent(file)
You should also replace
let filePath = fromDir.stringByAppendingString("/\(file)")
with
let filePath = fromDir.stringByAppendingPathComponent(file)
There is also a copyItemAtPath() method which saves you from
converting the paths to URLs.
On an iOS device, the simple answer is you can't do that. On the simulator things are little different. What you're probably dealing with is file permissions on the directory you're trying to write to.
As a general rule on iOS, you can write to the designated directories like the documents/caches and nothing else.

Resources