SWIFT 3 access JSON that is within a folder - ios

I have a lot of JSON files that all of them are in a new folder called assets. How can I access some of the JSON files that are in a folder within the assets folder. Here is a screenshot of the file I want to work with. http://prntscr.com/eiv7p4
UPDATE:
here is the code with which I access the file "mc-summer-0.json"
if let path = Bundle.main.path(forResource: "mc-summer-0", ofType: "json") {
do {
let jsonData = try NSData(contentsOfFile: path, options: NSData.ReadingOptions.mappedIfSafe)
do {
let jsonResult: NSDictionary = try JSONSerialization.jsonObject(with: jsonData as Data, options: JSONSerialization.ReadingOptions.mutableContainers) as! NSDictionary
if let times_to : [String] = jsonResult["times_to"] as? [String] {
for (value) in times_to {
print("\(value)")
}
}
} catch {}
} catch {}
}
but if I want to access a file that is in the "assets" folder I change the line into if let path = Bundle.main.path(forResource: "assets/mc-summer-1", ofType: "json") {
but unfortunately it doesnt work.

Those files are in groups in your project, not in separate folders. Very likely they will be in the root level of your app bundle, but we can't be sure based on what you've shown. I suggest building your app for the simulator and then opening the resulting bundle in the Finder and examining it.

alright, in case somebody get stuck just like me the real solution is to remove the assets "folder" and re add it and select to add them as reference instead as a group

Related

Get the names of files in an iCloud Drive folder that haven't been downloaded yet

I’m trying to get the names of all files and folders in an iCloud Drive directory:
import Foundation
let fileManager = FileManager.default
let directoryURL = URL(string: "folderPathHere")!
do {
let directoryContents = try fileManager.contentsOfDirectory(at: directoryURL, includingPropertiesForKeys: nil, options: [.skipsSubdirectoryDescendants, .skipsHiddenFiles])
for url in directoryContents {
let fileName = fileManager.displayName(atPath: url.absoluteString)
print(fileName)
}
} catch let error {
let directoryName = fileManager.displayName(atPath: directoryURL.absoluteString)
print("Couldnt get contents of \(directoryName): \(error.localizedDescription)")
}
It appears that any iCloud files that haven’t been downloaded to the device don’t return URLs.
I know I can check if a path contains a ubiquitous item when I already know the path with the code below (even if it isn’t downloaded):
fileManager.isUbiquitousItem(at: writePath)
Is there a way to get the URLs & names of those iCloud files without downloading them first?
The directory URL is a security-scoped URL constructed from bookmark data in case that makes any difference (omitted that code here for clarity).
Thanks
Found the answer. I was skipping hidden files with ".skipsHiddenFiles", but the non-downloaded files are actually hidden files, named: ".fileName.ext.iCloud".
Remove the skips hidden files option now works as expected.
You need to use a NSFileCoordinator to access the directory in iCloud Storage, and then normalize placeholder file names for items that haven't been downloaded yet:
let iCloudDirectoryURL = URL(...)
let fileCoordinator = NSFileCoordinator(filePresenter: nil)
fileCoordinator.coordinate(
readingItemAt: iCloudDirectoryURL,
options: NSFileCoordinator.ReadingOptions(),
error: nil
) { readingURL in
do {
let contents = try FileManager.default.contentsOfDirectory(
at: readingURL, includingPropertiesForKeys: nil
)
for url in contents {
print("\(canonicalURL(url))")
}
} catch {
print("Error listing iCloud directory: '\(error)'")
}
}
func canonicalURL(_ url: URL) -> URL {
let prefix = "."
let suffix = ".icloud"
var fileName = url.lastPathComponent
if fileName.hasPrefix(prefix), fileName.hasSuffix(suffix) {
fileName.removeFirst(prefix.count)
fileName.removeLast(suffix.count)
var result = url.deletingLastPathComponent()
result.append(path: fileName)
return result
} else {
return url
}
}

Multiple folder with Json file of same name swift 3

I'm facing difficulty to fetch the Json File.In my project there is one folder,in that folder multiple sub folders are there.And in every sub folder there is two json file.Json file name is common in every sub folder.Then how I fetch json file with subfolder name? Which means i want to differentiate json file through sub folder name.I'm new in Swift.Thank you.
(NS)Bundle provides a very convenient way to address subfolders, the optional parameter subdirectory of url(forResource: withExtension:)
if let jsonFileURL = Bundle.main.url(forResource: "jsonFile",
withExtension: "json",
subdirectory: "Subfolder1/SubFolder2") {
let json = try! String(contentsOf: jsonFileURL, encoding: .utf8)
print(json)
} else { fatalError("Check the file paths") }
You can get the file from different folders by providing the actual folder name in the document path.
Make sure that your files are added to resources.
if let docsPath = Bundle.main.resourcePath! + "/Resources/subfolder" {
let fileManager = FileManager.default
do {
let docsArray = try fileManager.contentsOfDirectory(atPath: docsPath)
//get the required json file from the documents array
} catch {
print(error)
}
}

Read local JSON file in XCUITest

I am writing UI tests for iOS application. I want to read data from a local json file.
I am using the following code to get the path for my json file:
func testExample() {
readJSON()
}
func readJSON(){
let bundle = Bundle(for:myTestClass.self)
if let path = bundle.url(forResource: "myurl", withExtension: "json"){
print("Got the path")
print(path)
}
else{
print("Invalid filename/path")
}
I have tried using the solution for the following stackoverflow question :
Reading in a JSON File Using Swift. Didn't work!
Also, I had a look at the following Apple documentation:
https://developer.apple.com/swift/blog/?id=37
Any help would be greatly appreciated!
First of all, you need to check the .json file is in the same target with the test file. If the file is in the main target, you have to use Bundle.main. However if it is in the same target with your test, use the below code.
let t = type(of: self)
let bundle = Bundle(for: t.self)
let path = bundle.path(forResource: "myurl", ofType: "json")
That's not how you read local json files from Bundle in iOS. It's done in the following way:
// "myUrl" is assumed to be your json file name
if let pathStr: String = Bundle.main.path(forResource: "myurl", ofType: ".json") {
print("json path: \(pathStr)")
}
I just found resources added to XCUITest targets will be placed under Bundle.main.resourcePath + "/PlugIns/<TARGET_NAME>.xctest/". However, I'm not sure if there were better ways to access them rather than hard-coding the sub-directory path.

Invalid filename/path when getting JSON

In my project Navigator I have this structure
-MyApp
--ViewController.swift
--AppDelegate.Swift
--Main.StoryBoard
--info.plist
--JSONFiles
---test.json
-MyAppUITests
As you can see, this is the very basic structure that happens when you create a new single view application.
I created a new group called JSONFiles and added in a JSON files called test.
When I try to get the file using:
if let path = Bundle.main.path(forResource: "JSONFiles/test", ofType: "json") {
do {
let data = try NSData(contentsOf: URL(fileURLWithPath: path), options: NSData.ReadingOptions.mappedIfSafe)
let jsonData : NSData = NSData(contentsOfFile: path)!
allEntries = (try! JSONSerialization.jsonObject(with: jsonData as Data, options: JSONSerialization.ReadingOptions.mutableContainers)) as! NSArray
print(allEntries)
} catch let error as NSError {
print(error.localizedDescription)
}
} else {
print("Invalid filename/path.")
}
I get the error:
Invalid filename/path.
If I move the JSON file our of the group folder and change the forResource to just "test" it works fine and prints in the console.
Can anyway tell me how to make it read from the folder? I could have all my JSON files in the root but I am wanting to tidy it up slightly.
Thanks
You must include your json file into "Copy Bundle Ressources". Go to your project target -> Build phases -> Copy Bundle ressources and there, add your json file.
Then, you should be able to retrieve the path using the function: Bundle.main.path(forResource: "test", ofType: "json") .

Swift .writeToFile does not update JSON file in mainBundle

I am trying a simple dictionary retrieve, update key value and write back to file. For some reason the writeToFile does not update the file in the main bundle.
the code reads:
let filename = "testFile"
if let path = NSBundle.mainBundle().pathForResource(filename, ofType: "json") {
var error: NSError?
let InputData: NSData? = NSData(contentsOfFile: path, options: NSDataReadingOptions(), error: &error)
var jsonDictionary: NSMutableDictionary = NSJSONSerialization.JSONObjectWithData(InputData!, options: NSJSONReadingOptions.MutableContainers, error: &error) as NSMutableDictionary
jsonDictionary.setValue(1, forKey: "levelRow")
let options = NSJSONWritingOptions.PrettyPrinted
var outputData : NSData? = NSJSONSerialization.dataWithJSONObject(jsonDictionary, options: options, error: &error)
outputData?.writeToFile(path, atomically: true)
}
the file looks like this:
{
"levelColumn" : 0,
"levelRow" : 0,
}
the read and update work fine... but the file doe not update levelRow to 1?
thanks in advance.
You cannot write to the main bundle. All files in the bundle are read-only. Copy your file into the application documents directory before modifying it.
If you need a different file in the bundle to include in your application, you can update it in the documents directory during development and then manually copy it to the bundle before shipping your app.

Resources