download Image and save it json using SwiftyJSON - ios

I have json in below format which I am fetching from server and parsing using SwiftyJSON.
{
name: "Ganesh"
imageURL:"www.abc.com/image.png"
}
I am downloading image using below code :
do{
let myData = try Data(contentsOf: url)
}catch{
Print("error")
}
Note: "url" contains url from json which is converted from string to URL
I want to save this "myData" in same json above with different key and access the same in future.
I am trying to save myData in json using SwiftyJSON method :
responseJSON["image"] = try JSON(data: myData)
Error which I am receiving :
"if Error while converting data into json The data couldn’t be read because it isn’t in the correct format."
I am not getting what is the problem?
Image is present at that url. if I convert myData into UIImage and If I assign it on UIImageView I can see it.

If you want to save an image in JSON, the best way would be to convert Data to Base64 string
if let base64encodedString = myData.base64EncodedString(){
responseJSON["image"] = base64encodedString
}
To restore image, try this
guard let base64encodedString = responseJSON["image"] as? String else { return }
guard let imageData = Data(base64Encoded: base64encodedString) else { return }
let image = UIImage(data: imageData)
Although Base64 - encoded images take approximately 33% more space than raw data, they are web and database safe - base64 strings contain neither control characters, nor quotes, and can be transferred as parameter in URL query strings.

Related

How to save image in memory and how to zip all the images in swift?

In our project when we captured an image we stored the image in local app path and it's in an encrypted format. And add some information. Finally, we have zip all the image and send it server, this is our current flow.
What we are trying to do is we convert an image into data and encoded a base64 format. But how to zip all the images(we need to capture more than 5 images).
Zip all the base64 format string and send it to the server . How to do that?
Do u have any idea about to save the image in memory and zip all those images and send to the server instead of the store an image in app folder?
1- convert each image into data and encoded a base64 format and zip it :
let strBase64 = imageData.base64EncodedString(options: .lineLength64Characters)
print(strBase64)
zip string using chilkat : https://www.example-code.com/swift/compress_decompress_string.asp
func chilkatTest() {
// This example requires the Chilkat API to have been previously unlocked.
// See Compression UnlockComponent for sample code.
var success: Bool
let sb = CkoStringBuilder()
var i: Int
for i = 1; i <= 20; i++ {
sb.Append("This is the original uncompressed string.\r\n")
}
let compress = CkoCompression()
compress.Algorithm = "deflate"
// Indicate that the utf-8 byte representation of the string should be compressed.
compress.Charset = "utf-8"
var compressedBytes: NSData
compressedBytes = compress.CompressString(sb.GetAsString())
// If the compressed data is desired in string format, then get the base64 representation of the bytes.
compress.EncodingMode = "base64"
var compressedBase64: String? = compress.CompressStringENC(sb.GetAsString())
print("Compressed Bytes as Base64: \(compressedBase64!)")
// Now decompress...
var decompressedString: String? = compress.DecompressString(compressedBytes)
print("The original string after decompressing from binary compressed data:")
print("\(decompressedString!)")
// To decompress from Base64...
compress.EncodingMode = "base64"
decompressedString = compress.DecompressStringENC(compressedBase64)
print("The original string after decompressing from Base64:")
print("\(decompressedString!)")
}
2- save it in json format :
[
{"1": "strBase64FromStep1"},
{"2": "strBase64FromStep1"},
.
.
.
]
3- save the json String to text file :
let file = "file.txt" //this is the file. we will write to and read from it
let text = "some text" //just a text
if let dir = FileManager.default.urls(for: .documentDirectory, in:
.userDomainMask).first {
let fileURL = dir.appendingPathComponent(file)
//writing
do {
try text.write(to: fileURL, atomically: false, encoding: .utf8)
}
catch {/* error handling here */}
//reading
do {
let text2 = try String(contentsOf: fileURL, encoding: .utf8)
}
catch {/* error handling here */}
}
4- save your file url to UserDefaults :
fileURL From step 3
NSUserDefaults.standardUserDefaults().setObject(fileURL, forKey: "path")
NSUserDefaults.standardUserDefaults().synchronize()
5 - use this file any time you want to send to server .

Best way to upload multiple images in a single batch

I was trying to upload multiple images in a single batch where I convert images into base64 strings, append them into a json and send. But when I append more than 3 or 4 images server gets null for json for some reason. I think it is because base64 strings are huge in length.
My requirement is like this, I want to upload multiple images which are under one upload id and each and every image should have its own tags.
My json was like this
{
"upload_id":[{
"tag1.tag2": "base64 string of image 1"
},
{
"tag3.tag4": "base64 string of image 2"
}]
}
and this is the code i used to make the json and upload
// Images are saved in the documents directory, image paths are saved in imgPathsArr array and tags are saved in tagsArr.
var uploadDict = [String: Any]()
var imgDictArr = [[String: Any]]()
for (indx,imgPath) in imgPathsArr.enumerated(){
do{
let imgData = try Data(contentsOf: URL(fileURLWithPath: imgPath))
let base64Str = imgData.base64EncodedString(options: .init(rawValue: 0))
let imageDict = [tagsArr[index]:base64Str]
imgDictArr.append(imageDict)
}catch let error{
print(error.localizedDescription)
}
}
uploadDict[nic!] = imgDictArr
Alamofire.request("url", method: .post, parameters: uploadDict, encoding: JSONEncoding.default, headers: nil).response { (response) in
//things after getting response
}
Any possible way to get my work done. Any help would be highly appreciated.
Multipart is better than sending it in pure binary-to-text like base64. In the multipart request, clients construct request to send files and data over to an HTTP Server. It is commonly used by browsers and HTTP clients to upload files to the server.
There is a link below which goes into Multipart a bit more in detail:
https://stackoverflow.com/a/19712083/7461562

Loading a previously saved audio file as base64 string

I record and save an audio file, this works and plays in the app as expected.
After the recording, however, I try to load it so I can pass the audio into a JSON object, but can't open it.
I get the following error:
The file “audio.m4a” couldn’t be opened because the text encoding of its contents can’t be determined.
This is call I'm making:
do {
let audioData = try NSData(contentsOfFile: String(contentsOf: audioURL!))
} catch {
print error
}
Any ideas how I can load the audio data as from the file in base64 encoding?
Thanks
You didn't explain how do you save your file, so i can only assume (according to file extension), that you are not saving it as base64 string.
Please refer to first answer of this question. To check if you save audio file as base64 string correctly.
But still you can use other way. At first load data:
let audioData = try Data(contentsOf: audioURL!)
Then convert it to base64 string:
let encodedString = audioData.base64EncodedString()
The problem is that you are using the wrong method. The audio data it is not a string it is a collection of bytes (an array of UInt8). To read your audio data you need to use the Data initializer Data(contentsOf: audioURL) and convert this data to base64 string using Data instance method base64EncodedString.
if let base64String = try? Data(contentsOf: audioURL).base64EncodedString() {
print(base64String)
}

How to remove xml tags before send to the json parser in swift

I want to use JSON data in my app. So I am using this webservice calling method to convert my json data to an array.
func getData(path: String, completion: (dataArray: NSArray)->()) {
let semaphore = dispatch_semaphore_create(0)
// var datalistArray = NSArray()
let baseUrl = NSBundle.mainBundle().infoDictionary!["BaseURL"] as! String
let fullUrl = "\(baseUrl)\(path)"
print("FULL URL-----HTTPClient \(fullUrl)")
guard let endpoint = NSURL(string:fullUrl) else {
print("Error creating endpoint")
return
}
let request = NSMutableURLRequest(URL: endpoint)
NSURLSession.sharedSession().dataTaskWithRequest(request,completionHandler: {(data,response,error) in
do {
guard let data = data else {
throw JSONError.NoData
}
guard let json = try NSJSONSerialization.JSONObjectWithData(data, options: []) as? NSArray else {//NSJSONReadingOptions.AllowFragments
throw JSONError.ConversionFailed
}
print(json)
if let data_list:NSArray = json {
completion(dataArray: data_list)
dispatch_semaphore_signal(semaphore);
}
}catch let error as JSONError {
print(error.rawValue)
} catch let error as NSError {
print(error.debugDescription)
}
}) .resume()
dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);
}
But now my service sending json data within xml tags like <string xmlns="http://tempuri.org/">json data</string so I am getting an exception when I try to convert my json data. The exception is this.
Error Domain=NSCocoaErrorDomain Code=3840 "Invalid value around character 0." UserInfo={NSDebugDescription=Invalid value around character 0.}
What should I change in my code to remove those tags before sending to json parser?
Please help me.
Thanks
I think your response that you get from server is in xml format not in json. If it is in xml format then you must do xml parsing instead of json parsing.
NSJSONSerialization.JSONObjectWithData is json parsing that give json object from data (data in json format).
But if you getting response in xml format from server then you should use NSXMLParser to parse the data.
If you don't have much idea about it then you can refer tutorial like
XML Parsing using NSXMLParse in Swift by The appguruz or can use third party libraries.

SwiftyJSON to read local file

So my app is using a JSON API response to read some data from server. Since the API is not yet ready i want to use a sample JSON file which is stored in my app itself. Since all my code uses SwiftyJSON i want to stick to it for the local file.
I am doing the following in my ViewDidLoad method and somehow this end result is a blank array. Do you know what should i change in this code to make it work?
//Direct JSON
if let path = NSBundle.mainBundle().pathForResource("XXYYXZZfile", ofType: "json")
{
do{
let pathAsData = try NSData(contentsOfFile: path, options: NSDataReadingOptions.DataReadingMappedIfSafe)
let json = JSON(pathAsData)
print(json)
} catch{
print("Some error")
}
}
When using SwiftyJSON with NSData you have to specify the "data:" parameter for the JSON initializer:
let json = JSON(data: pathAsData)
otherwise it tries to use other available initializers and will fail with an error or even, like in your case, will fail silently with a misinterpreted input and wrong output.

Resources