Get Reference to SceneKit Catalog Swift - ios

I must be missing something simple - I'm trying to iterate through the
files in an .scnassets folder but can't seem to get a reference to the
folder/catalog.
Here's the organizer:
Models.scnassets contains one file. I tried this:
let fileManager = FileManager.default
let urls = fileManager.urls(for: .documentDirectory, in: .userDomainMask)
let docsURL = urls.first
let assetFolderPath = docsURL?.appendingPathComponent("Models.scnassets").path
And I tried this and several other variants:
let modelPathString = "ARAds/Models.scnassets"
Then I attempted to count the files with both of the above paths:
do {
let modelPathDirectoryFiles = try fileManager.contentsOfDirectory(atPath: assetFolderPath!)
//or modelPathString
print(modelPathDirectoryFiles.count)
} catch {
print("error getting list of files")
}
I get the error message in all cases.
I assume there must be some special way to get a reference to a SceneKit
Catalog but I have not been able to find that in the Apple docs nor SO.
Any guidance would be appreciated. iOS 11.4 Xcode 10.0

Looking at your code, the first thing I see, is that you are referencing the Documents Directory which isn't actually where your folder is.
The Documents Directory is a folder on your actual device where you might save user data or other files which can be accessed at a latter date (for example via iTunes Sharing).
If you move your Models.scnassets folder under the yellow ArAds folder you should be able to access your content like so:
let myModelToLocate = SCNScene(named: "Models.scnassets/Phone_01.scn")
Hope it helps...

You've pointed me in a better direction, but I can already get the scn and make a node if I know the name. What I really want to do is populate a tableview with the options that are available - so I need to find the current list of scene files.
I think this will work:
let subdir = Bundle.main.resourceURL!.appendingPathComponent("Models.scnassets").path
do {
let modelPathDirectoryFiles = try fileManager.contentsOfDirectory(atPath: subdir)
print(modelPathDirectoryFiles.count) //this works
//then do my thing with the array
} catch {
print("error getting list of files")
}
This seems to work, whether I move the folder or not.

Related

Bundle.main does not find file in folder structure

Overview
I want to find my core data model as part of the initialisation of NSPersistentContainers (local and cloud) to make sure that they share the same model.
Code
The code I planned to use to achieve this:
static let model: NSManagedObjectModel = {
guard let url = Bundle.main.url(forResource: "BookKeeping", withExtension: "momd") else {
fatalError("Failed to locate model file.")
}
guard let managedObjectModel = NSManagedObjectModel(contentsOf: url) else {
fatalError("Failed to load model file.")
}
return managedObjectModel
}()
However this does not do trick, as it fails with the first fatalError "Failed to locate model file".
I presume it has something to do with my folder structure, which is the following:
Folder Structure
In "Persistence" the initialisation takes places, "BookKeeping" is the name of the model file.
Approaches so far
I tried to add the file as Bundle Resource in the Build Phase, I checked that the target membership of the file is right, FileManager is in my opinion not the right approach to get it done and I looked into Bundle identifiers, however it seems to me they are used in different use cases.
If you could put me in the right direction I'd be happy.
Any help is greatly appreciated! Thanks!

Beginner question: Reading a resource text file on MacOS using Swift

I'm new to this and apologize if it's basic. I have tried to research and I either get iOS posts, or old Xcode posts - none that are helping me with a basic need.
I want to have a bundled text file in my Swift/SwiftUI/MacOS app. It's just a text file, say sample.txt
I want to read it and do something with it.
I did the following:
Created a folder called "Resources" in my project
Added the text file - sample.txt
In my SwiftUI code, I did the following
if let filepath = Bundle.main.path(forResource: "sample", ofType: "txt") {
do {
print("...getting resource")
let contents = try String(contentsOfFile: filepath)
print(contents)
} catch {
// contents could not be loaded
print(error)
}
} else {
print("no such file!")
}
And I get no such file
I changed the forResource: "sample" to forResource: "Resource/sample" and that didn't help either.
What should I be doing?
Thank you
It's not necessary to create an extra folder Resources. Just add the file to the project. It will be moved into the Resources folder of the app while being built.
And make sure that the Target Membership checkbox of the file is checked.

Importing Documents from iMessage into App - Deleting temp files placed in "Inbox"

I have defined a UTI for a custom document format. I can export files from my app and append them to text messages, email, etc. I can import the files into my app by tapping on the document icon in iMessage. By tapping on the document icon, I have the option to copy to my app. That triggers a call in my AppDelegate to handle the incoming file.
What's bugging me is that the url for the incoming file is:
file:///private/var/mobile/Containers/Data/Application/21377C94-1C3C-4766-A62A-0116B369140C/Documents/Inbox/...
Whereas, when saving documents to the .documents directory, I use this URL:
file:///var/mobile/Containers/Data/Application/21377C94-1C3C-4766-A62A-0116B369140C/Documents/...
The difference being the /private/ and /Inbox/ path components.
Question: how can I purge the /private/.../Inbox/ path of the files that were copied to my app from iMessage? I noticed this when testing my app and when I tapped on the same document icon in iMessage it started generating file copies with the same name but adding -1, then -2, then -3 to the file name of the document from iMessage. It appears that copies are building up in that /private/.../Inbox/ path.
Is that something that gets flushed on its own or can I access that directory to remove those files? It's also annoying because based upon the filename, it appears to be a different file thus allowing multiple copies of the same file to be imported with a slightly different file name.
Ok, this took a fair amount of digging, but I'll post my solution that seems to work thus far in case anyone runs across the same problem.
let fileManager = FileManager.default
// get the URL for the "Inbox"
let tmpDirURL = fileManager.urls(for: .documentDirectory, in: .userDomainMask)[0].appendingPathComponent("Inbox")
// get all the files in the "Inbox" directory
let anythingThere = try? fileManager.contentsOfDirectory(at: tmpDirURL, includingPropertiesForKeys: nil)
if anythingThere?.count ?? 0 > 0 {
for eachURL in anythingThere! {
// for each url pointing to a file in that directory, get its path extension
let pathExtension = eachURL.pathExtension
// test to see if it's a UTI that you're interested in deleting
// in my case, the three "OCC" strings are the relevant UTI extensions
if pathExtension == "OCCrcf" || pathExtension == "OCCrdi" || pathExtension == "OCCsrf" {
// attempt to delete the temporary file that was copied to the
// "Inbox" directory from importing via email, iMessage, etc.
try fileManager.removeItem(at: eachURL)
}
}
}
If anyone has a more elegant solution, please respond as well. Thanks.

File Not Created in iPhone Documents

I'm trying to save a bunch of GPS locations in a text file on an iPhone. I've been following suggestions that I've gleaned from the web, but, while the app runs fine, no file is being created. At least, nothing is visible under XCode Window -> Devices and Simulators -> (app name).
The goal is to create a file named "1" in a folder called "position" under a folder named after the date/time the app is launched, which is in turn under the Document folder. Example: 2018-07-21-16-35-43/position/1
I'm writing this in Swift 4.2 in XCode 9.(latest)
I get the Document folder as follows (rideStart = Date()):
let urls = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask)
if let docUrl = urls.first {
let dateFormatter = DateFormatter()
dateFormatter.dateFormat = "yyyy-MM-dd-HH-mm-ss"
let dateText = dateFormatter.string(from: rideStart)
positionUrl = docUrl.appendingPathComponent(dateText)
}
When I'm ready to write out some lines of text I do the following (locationCache is an array of CLLocation objects, and textForFile is an extension property that formats the information I want as a comma-separated set of values, terminated with \r\n):
try? FileManager.default.createDirectory(at: positionUrl, withIntermediateDirectories: true)
let curUrl = positionUrl.appendingPathComponent("\(fileNumber)")
for loc in locationCache {
do {
let line = loc.textForFile
print(line)
try line.write(to: curUrl, atomically: true, encoding: .utf8)
}
catch {
print(error)
}
}
No errors are thrown when the code runs, and the text lines print to the console in the expected format.
I'm new to iOS and to Swift, the vast majority of my experience being in C# under Windows, along with javascript. I'm obviously missing something simple and/or basic. What am I doing wrong?
Additional Info
Based on feedback, I ran the app in a simulator. After figuring out where the iPhone 6 simulator was located in my Library folder, I determined that the file I was trying to create was, in fact, created (note: I'm currently using a FileHandle based approach to writing the file, as opposed to what's in the code shown in this posting -- but I've tested that FileHandle approach against the physical iPhone hardware, and it still doesn't create any file visible from within XCode's Devices and Simulators window.
Which brings up a point raised in the comments: is it even possible to examine the files on a connected/paired iPhone from within XCode? I thought from what I've read in various places that it should be possible...but that may not be the case.

Valid file path for archiverootobject and unarchiverootobject

I am making an iPhone app and in a previous question I was told that I needed a valid file path for archiverootobject and unarchiverootobject but I don't know how to make one. So what is a valid file path to save arrays of custom classes?
Follow up question: On the linked question I have set up my methods to use invalid saves but it still works would anyone know why?
You can save it to a subdirectory folder named with your bundleID inside the application support folder or you can also save it to the preferences folder located inside the library directory:
let preferencesDirectoryURL = FileManager.default.urls(for: .libraryDirectory, in: .userDomainMask).first!.appendingPathComponent("Preferences", isDirectory: true)
let fileURL = preferencesDirectoryURL.appendingPathComponent("fileName.plist")
print(fileURL.path) // "/var/folders/.../Library/Preferences/fileName.plist

Resources