Swfit Data can not get value - ios

I want to get json file content, but jsonData always returns nil. What could be the reason behind that?
OS:10.12.2 XCode: 8.1 Swift 3.0

you have to give the file type of path as json
as
guard let jsonpath = bundle.main.path(forResource: "MainVCString", ofType: "json"),

How about this ?
if let fileURL = Bundle.main.url(forResource: "MainVCString", withExtension: "json"){
if let data = try? Data(contentsOf: fileURL, options: Data.ReadingOptions.uncached){
print("This works!")
}else{
print("Something wrong with the path.")
}
}

Related

How Update Local JSON file Swift ios 13 [duplicate]

This question already has answers here:
How to access file included in app bundle in Swift?
(8 answers)
File write with [NSBundle mainBundle] fails
(5 answers)
Closed 3 years ago.
I have a local json file, to read what I do as follows:
enter image description here
func readJson() {
if let path = Bundle.main.path(forResource: "text", ofType: "json") {
do {
let data = try Data(contentsOf: URL(fileURLWithPath: path), options: .mappedIfSafe)
let decoder = JSONDecoder()
let model = try decoder.decode(Textos.self, from: data)
print("model", model)
} catch {
print("error file")
}
} else {
print("error")
}
}
the read function works fine but when I want to update the file it doesn't update.
func saveJson(response: Textos) {
do {
let jsonEncoder = JSONEncoder()
let jsonData = try jsonEncoder.encode(response) //all fine with jsonData here
let json = String(data: jsonData, encoding: String.Encoding.utf8)
let data = Data(json!.utf8)
if let path = Bundle.main.path(forResource: "text", ofType: "json") {
do {
try? data.write(to: URL(fileURLWithPath: path)) **//not Working**
readJson()
}
}
} catch {
print(error)
}
}
the saveJson function works fine in a simulator but when I test it with a device it doesn't work.
Short answer:
You will never be able to save.
let path = Bundle.main.path(forResource: "text", ofType: "json")
The file is within the application bundle. Access is read only.
Saving would be possible to either the document or cache folder.
let documentPath = NSSearchPathForDirectoriesInDomains(FileManager.SearchPathDirectory.documentDirectory, FileManager.SearchPathDomainMask.userDomainMask, true)
(Example how to request the path to the user document folder. This folder is per application sandbox.

how to write bytes data in file swift

data coming from server is in ex.2035bytes I want to write this data in to file I am writing but data is not showing
Alamofire.request(url , method: .post, parameters: Parameters as? [String: Any] , encoding: URLEncoding.httpBody, headers: [
"Content-Type": "application/x-www-form-urlencoded"
]).responseData{ (response) in
print(response)
print(response.result.value!)
print(response.result.description)
guard let jsonData = response.result.value ,response.result.isSuccess else {
didFail(response.result.error!)
return
}
guard let id = ApplicantModel.shared.applicationId else {
return
}
let file = "application_\(id)" //this is the file. we will write to and read from it
let documentsPath1 = NSURL(fileURLWithPath: NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true)[0])
//let logsPath = documentsPath1.appendingPathComponent("f")
let fileURL = documentsPath1.appendingPathComponent("file")
let data: Data = response.result.value!
// print(logsPath)
//writing
do {
try FileManager.default.createDirectory(at: documentsPath1 as URL, withIntermediateDirectories: true, attributes: nil)
//try data.write(to: fileURL!, atomically: false, encoding: .utf8)
// try data.write(to: fileURL!, options: Data.WritingOptions.atomic)
try data.write(to: fileURL!) )
}
catch {/* error handling here */}
let json = JSON(jsonData)
didFinish(json)
}
here I am creating file and writing data in to it but its not showing
You can use this function to write data. Code is self explanatory, but I tried to make it more clear.
func writeToFile(data: Data, fileName: String){
// get path of directory
guard let directory = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).last else {
return
}
// create file url
let fileurl = directory.appendingPathComponent("\(fileName).txt")
// if file exists then write data
if FileManager.default.fileExists(atPath: fileurl.path) {
if let fileHandle = FileHandle(forWritingAtPath: fileurl.path) {
// seekToEndOfFile, writes data at the last of file(appends not override)
fileHandle.seekToEndOfFile()
fileHandle.write(data)
fileHandle.closeFile()
}
else {
print("Can't open file to write.")
}
}
else {
// if file does not exist write data for the first time
do{
try data.write(to: fileurl, options: .atomic)
}catch {
print("Unable to write in new file.")
}
}
}
You have a problem with creating the directory and naming the file you need to change it like this
let file = "application_\(id)"
let documentsPath1 = NSURL(fileURLWithPath: NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true)[0])
let logsPath = documentsPath1.appendingPathComponent("file")
do
{
try FileManager.default.createDirectory(atPath: logsPath!.path, withIntermediateDirectories: true, attributes: nil)
let fileURL = logsPath?.appendingPathComponent(file)
try data.write(to: fileURL!)
}
catch let error as NSError
{
NSLog("Unable to create directory \(error.debugDescription)")
}
I think you create a wrong folder. It due to you can't save that file in your folder. You can look at my example. Which I create 1 folder to contain files.
Step1: Get document path
let paths = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask)
Step2: create a destination URL. Where you would like to store
let url = paths[0].appendingPathComponent(self.fileImagejpeg)
Step 3: Write data in files
try? data.write(to: url)
You can use try catch to get log when write failure

Fatal error Xcode 8 Swift 3

ok guys can I get a little help with my code. When running the app I get an error is there any way to fix this problem?
let fileUrl = dict["fileUrl"]as! String
let url = NSURL(string: fileUrl)
let data = NSData(contentsOf: url! as URL!)
let picture = UIImage(data: data! as Data!)
let photo = JSQPhotoMediaItem(image: picture)
self.messages.append(JSQMessage(senderId: senderId, displayName: senderName, media: photo))
Image here
Here I see 4 big fat problems with your code.
You are force casting the value of fileUrl of the dictionary dict to String. If your dictionary doesn't have the value for fileUrl, or if it's not castable to string, your code will crash. You should change that to optional cast like:
if let fileUrl = dict["fileUrl"] as? String
{
//your code if you have fileUrl
}
When creating the url to the file, you are using the wrong initialization method, you should be using this:
let url = URL(fileURLWithPath: fileUrl)
After you have the url to the file, you should also check if you have the data of the file, because contentsOfFile: initializer of the NSData returns the optional object, which may be nil, so another if check:
if let data = NSData(contentsOf: url) {\\ code with the data}
init?(data: Data) initializer of the UIImage also returns optional object, so if the required by latter code, you should also check if you have the image or nil with if statement.
The result code should be something like:
if let fileUrl = dict["fileUrl"] as? String {
let url = URL(fileURLWithPath: fileUrl)
if let data = NSData(contentsOf: url) {
let image = UIImage(data: data as Data) // you can cast NSData to Data without force or optional casting
let photo = JSQPhotoMediaItem(image: image)
self.messages.append(JSQMessage(senderId: senderId, displayName: senderName, media: photo))
}
}
Hope this helps.
Replace the first line of code with this line for optional binding check :-
guard let fileUrl = dict["fileUrl"] as! String else {return}
Yo should do validation in cases where the variable may be nil, the following is an example:
if let fileUrl = dict["fileUrl"] as? String {
let url = URL(string: fileUrl)
do {
let data = try Data(contentsOf: url!)
let picture = UIImage(data: data)
let photo = JSQPhotoMediaItem(image: picture)
self.messages.append(JSQMessage(senderId: senderId, displayName: senderName, media: photo))
} catch {
}
}

NSURL to NSDATA or Data is always nil

I am trying to upload a video to a server file through Alamofire but I couldn't get the "data" going to be passed..its always nil
var videoURL = NSURL(string: "")
//returns Optional(file:///private/var/mobile/Containers/Data/Application/1FB40086-228B-4011-A9D4-7874E2EEF9F4/tmp/4A6AAD76-B899-4B67-8E96-925DA4AE9E93.mov)
let videodata = NSData(contentsOfFile: (videoURL?.absoluteString)!)
//nil
let url = NSURL(fileURLWithPath: (videoURL?.absoluteString)!)
let videodata = NSData(contentsOf: url as URL)
//nil
If I get data would lead a way for me to do this:
Alamofire.upload(multipartFormData: { multipartFormData in
multipartFormData.append (videodata as! Data, withName: "file", fileName: "file.mov", mimeType: "video/quicktime")
enter code here
EDIT::
thank you guys, with your help I have struggled my way out of there to this file not found error, but I can see the file is being saved in my gallery, any clue would save my day.
print (videoURL!)
//returns file:///private/var/mobile/Containers/Data/Application/3F280477-DA16-4A67-AE60-D6247143352E/tmp/1E4AC002-6AD0-41E1-9E0D-A09B697F81F7.mov
print (videoURL!.path!)
// returns /private/var/mobile/Containers/Data/Application/3F280477-DA16-4A67-AE60-D6247143352E/tmp/1E4AC002-6AD0-41E1-9E0D-A09B697F81F7.mov
var videoData = NSData()
let path = videoURL!.path!
if FileManager.default.fileExists(atPath: path) {
}else {
print("Could not fin file at url: \(videoURL!.path!)")
// here it throws file not found
}
In Swift 3 use native URL and Data instead of NSURL and NSData.
if let videoURL = URL(string: urlString), let videodata = try? Data(contentsOf: videoURL) {
//Add code of Alamofire here
}
Using absoluteString returns a string that includes file:// at the beginning and you don't want that. You need to return the path of the URL
guard let videoPathString = videoURL.path as? String else {
//handle error here if you can't create a path string
return
}
var videoData = NSData()
//check if file exists at this path first
if (NSFileManager.defaultManager().fileExistsAtPath(videoPathString)) {
videoData = NSData(contentsOfFile: NSString(videoPathString))
} else {
//if file does not exist at that path, handle here
}

How to read a playground text resource files with Swift 2 and Xcode 7

Xcode 7 Playgrounds now supports loading files from the nested Resources directory.
I can get SKScene(fileNamed: "GameScene") when I have a GameScene.sks in my Resources or NSImage(named:"GameScene.png") if I have a GameScene.png in your Resources.
But how can I read a regular text file from the Playground Resources directory as well?
We can use the Bundle.main
So, if you have a test.json in your playground like
You can access it and print its content like that:
// get the file path for the file "test.json" in the playground bundle
let filePath = Bundle.main.path(forResource:"test", ofType: "json")
// get the contentData
let contentData = FileManager.default.contents(atPath: filePath!)
// get the string
let content = String(data:contentData!, encoding:String.Encoding.utf8)
// print
print("filepath: \(filePath!)")
if let c = content {
print("content: \n\(c)")
}
Will print
filepath: /var/folders/dm/zg6yp6yj7f58khhtmt8ttfq00000gn/T/com.apple.dt.Xcode.pg/applications/Json-7800-6.app/Contents/Resources/test.json
content:
{
"name":"jc",
"company": {
"name": "Netscape",
"city": "Mountain View"
}
}
Jeremy Chone's answer, updated for Swift 3, Xcode 8:
// get the file path for the file "test.json" in the playground bundle
let filePath = Bundle.main.path(forResource: "test", ofType: "json")
// get the contentData
let contentData = FileManager.default.contents(atPath: filePath!)
// get the string
let content = String(data: contentData!, encoding: .utf8)
// print
print("filepath: \(filePath!)")
if let c = content {
print("content: \n\(c)")
}
You can use String directly with a URL. Example in Swift 3:
let url = Bundle.main.url(forResource: "test", withExtension: "json")!
let text = String(contentsOf: url)
Swift 5
It is possible to get to files in your Resources folder by the bundle in a Playground.
import UIKit
Here are two ways to get the JSON data.
Path:
guard let path = Bundle.main.path(forResource:"test", ofType: "json"),
let data = FileManager.default.contents(atPath: path) else {
fatalError("Can not get json data")
}
URL:
guard let url = Bundle.main.url(forResource:"test", withExtension: "json") else {
fatalError("Can not get json file")
}
if let data = try? Data(contentsOf: url) {
// do something with data
}
Another short way (Swift 3):
let filePath = Bundle.main.path(forResource: "test", ofType: "json")
let content: String = String(contentsOfFile: filePath!, encoding: .utf8)
Added try for swift3.1:
let url = Bundle.main.url(forResource: "test", withExtension: "json")!
// let text = String(contentsOf: url)
do {
let text = try String(contentsOf: url)
print("text: \n\(text)")
}
catch _ {
// Error handling
}
// --------------------------------------------------------------------
let filePath2 = Bundle.main.path(forResource: "test", ofType: "json")
do {
let content2: String = try String(contentsOfFile: filePath2!, encoding: .utf8)
print("content2: \n\(content2)")
}
catch _ {
// Error handling
}

Resources