SwiftyJSON to read local file - ios

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.

Related

download Image and save it json using SwiftyJSON

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.

use of "po" to get data from server response in console log

i know this is very basic question that i am gonna ask but i need to ask how can i access data which is dictionary that is getting from server.
here is my response
JSON: {
message = "The email must be a valid email address.";}
now i want to do "po" in console log so what to write after in po statement
Thanks
All you need type
po yourResponseAsDictionary["message"]
UPDATED
Sorry I was thinking you already converted it.
If you are not using anything like SwiftyJSON or ObjectMapper to parse your json data then you can do just the following.
But I would recommend to use some lib to convert response directly to your model
let yourResponseFromNetwork = "{ \"country_code\" : \"+9\", \"user_id\" : 123456}"
if let data = yourResponseFromNetwork.data(using: String.Encoding.utf8) {
do {
if let dic = try JSONSerialization.jsonObject(with: data, options: .mutableContainers) as? [String:Any] {
let countryCode = dic["country_code"]
let userId = dic["user_id"]
}
} catch {
print("Error occurred")
}
}

IOS How to save and load JSON String to memory

I am using NSUserDefaults.standardUserDefaults() to save my JSON String got from WebService to iPhone memory. When I load it to use with my parser function, the processing speed is so slow. I don't want to use RealmIO or any database because that thing doesn't necessary. I would like to ask is there any way faster than NSUserDefaults? Please check my JSON file (I need store more than 20 files like that)
Instead of saving your data to NSUserDefaults, you should save it to a different file, this will be much more efficient.
Here is how you can do it :
// Build file url
let documentsURL = NSFileManager.defaultManager().URLsForDirectory(.DocumentDirectory, inDomains: .UserDomainMask).last!
let fileURL = documentsURL.URLByAppendingPathComponent("file_1.json", isDirectory: false)
// Write
let jsonString = "..."
let jsonData = jsonString.dataUsingEncoding(NSUTF8StringEncoding)
do {
try jsonData?.writeToURL(fileURL, options: NSDataWritingOptions())
} catch {
NSLog("Writing file to `\(fileURL)` failed with error : \(error)")
}
// Read
do {
let jsonData = try NSData(contentsOfURL: fileURL, options: NSDataReadingOptions())
let jsonString = String(data: jsonData, encoding: NSUTF8StringEncoding)
} catch {
NSLog("Reading file at url `\(fileURL)` failed with error : \(error)")
}
NSUserDefaults is not a database. If your JSON documents are more than 100 KB altogether store them into separate documents. Note that every time you change any user default, all the user defaults have to be written to a file. If you have 20 JSON documents of 1MB each, that's writing 20MB or more for every user default the you change.

parse string and send as Json in swift

I have real big problem finding the right code which helps me to parse String to JSON and then send to external server. I'm using xCode 6.1, so some ways of parsing won't work for me, like SwiftyJSON.
On internet i only can find the way to send String , but not JSON, or if i found something it won't work.
I'm beginner in iOS and it would really help me if someone can explain me how to do it.
Thank you a lot.
If you have JSON String convert to NSData object.Check the data object before sending to an external server if data is valid JSON format or not by using NSJSONSerialization.I am giving sample code to how can check JSON Data valid or not.
suppose you String is like this,
let jsonString = "{\"device\":\"iPhone 6\",\"OS\":\"iOS 9\",\"name\":\"Apple\"}"
let data = jsonString.dataUsingEncoding(NSUTF8StringEncoding)
do {
let responseData = try NSJSONSerialization.JSONObjectWithData(data!, options: .AllowFragments)
if responseData != nil { // valid JSON
//Now pass data object to server
}
} catch {
NSLog("ERROR when parse JSON")
}

How can I process multiple links of JSON data?

The code works perfectly. The problem is that, after trying for a while, I cannot figure out how to make my program process a second link of different JSON data.
Here is my viewDidLoad where everything goes on:
override func viewDidLoad() {
super.viewDidLoad()
var err: NSError?
let urlPath: String = "https://na.api.pvp.net/api/lol/na/v1.4/summoner/by-name/" + searchFieldDataPassed + "?api_key=(removed my private api key for obvious reasons"
var url: NSURL = NSURL(string: urlPath)!
let session = NSURLSession.sharedSession()
let task = session.dataTaskWithURL(url) { data, response, error in
// cast response as NSHTTPURLResponse and switch on statusCode if you like
if let httpResponse = response as? NSHTTPURLResponse { switch httpResponse.statusCode { case 200..<300: println("OK") default: println("Not OK") } }
// parse JSON using NSJSONSerialization if you've got data
if let jsonResult = NSJSONSerialization.JSONObjectWithData(data, options: NSJSONReadingOptions.MutableContainers, error: &err) as? NSDictionary,
let include = jsonResult.objectForKey(self.searchFieldDataPassed) as? NSDictionary {
if let summLevel = include[ "summonerLevel" ] as? NSNumber {
dispatch_async(dispatch_get_main_queue()) {
self.summonerLevel.text = "\(summLevel.integerValue)"
println("summoner level: \(summLevel.integerValue)")
}
}
if let profIconId = include[ "profileIconId" ] as? NSNumber {
dispatch_async(dispatch_get_main_queue()) {
self.profileIconId.text = "\(profIconId.integerValue)"
println("profile icon id: \(profIconId.integerValue)")
}
}
if let idNum = include [ "id" ] as? NSNumber {
dispatch_async(dispatch_get_main_queue()) {
self.idNumber = idNum
println("id number: \(self.idNumber)")
}
}
}
// spawn off another network call here if you like
}
task.resume()
}
That is from my secondViewController where all the processing goes on for JSON and then is displayed.
Here is the JSON data that I'm processing (for the first JSON parsing):
{"soon2challenger":{"id":43993167,"name":"soon2challenger","profileIconId":844,"summonerLevel":30,"revisionDate":1435549418000}}
All of that works fine, now, I want to process this JSON data which actually takes the id from the first parsed JSON data and uses it in the link to process more data, which I would like to output, part of it, to the screen.
Second JSON data:
{"summonerId":43993167,"playerStatSummaries":[{"playerStatSummaryType":"AramUnranked5x5","wins":25,"modifyDate":1423007927000,"aggregatedStats":{"totalChampionKills":676,"totalTurretsKilled":20,"totalAssists":991}},{"playerStatSummaryType":"CAP5x5","wins":15,"modifyDate":1429065922000,"aggregatedStats":{"totalChampionKills":312,"totalMinionKills":4885,"totalTurretsKilled":31,"totalNeutralMinionsKilled":511,"totalAssists":216}},{"playerStatSummaryType":"CoopVsAI","wins":28,"modifyDate":1421882181000,"aggregatedStats":{"totalChampionKills":266,"totalMinionKills":2802,"totalTurretsKilled":50,"totalNeutralMinionsKilled":385,"totalAssists":164,"maxChampionsKilled":0,"averageNodeCapture":0,"averageNodeNeutralize":0,"averageTeamObjective":0,"averageTotalPlayerScore":49,"averageCombatPlayerScore":0,"averageObjectivePlayerScore":49,"averageNodeCaptureAssist":0,"averageNodeNeutralizeAssist":0,"maxNodeCapture":0,"maxNodeNeutralize":0,"maxTeamObjective":0,"maxTotalPlayerScore":49,"maxCombatPlayerScore":0,"maxObjectivePlayerScore":49,"maxNodeCaptureAssist":0,"maxNodeNeutralizeAssist":0,"totalNodeNeutralize":0,"totalNodeCapture":0,"averageChampionsKilled":0,"averageNumDeaths":0,"averageAssists":0,"maxAssists":0}},{"playerStatSummaryType":"CoopVsAI3x3","wins":15,"modifyDate":1421882181000,"aggregatedStats":{"totalChampionKills":140,"totalMinionKills":1114,"totalTurretsKilled":9,"totalNeutralMinionsKilled":449,"totalAssists":91}},{"playerStatSummaryType":"OdinUnranked","wins":1,"modifyDate":1421882181000,"aggregatedStats":{"totalChampionKills":31,"totalAssists":45,"maxChampionsKilled":10,"averageNodeCapture":4,"averageNodeNeutralize":4,"averageTeamObjective":0,"averageTotalPlayerScore":843,"averageCombatPlayerScore":268,"averageObjectivePlayerScore":575,"averageNodeCaptureAssist":3,"averageNodeNeutralizeAssist":1,"maxNodeCapture":6,"maxNodeNeutralize":7,"maxTeamObjective":2,"maxTotalPlayerScore":1468,"maxCombatPlayerScore":529,"maxObjectivePlayerScore":939,"maxNodeCaptureAssist":5,"maxNodeNeutralizeAssist":2,"totalNodeNeutralize":22,"totalNodeCapture":25,"averageChampionsKilled":5,"averageNumDeaths":5,"averageAssists":8,"maxAssists":19}},{"playerStatSummaryType":"RankedSolo5x5","wins":116,"losses":120,"modifyDate":1433630047000,"aggregatedStats":{"totalChampionKills":1699,"totalMinionKills":33431,"totalTurretsKilled":219,"totalNeutralMinionsKilled":6501,"totalAssists":1969}},{"playerStatSummaryType":"RankedTeam3x3","wins":0,"losses":0,"modifyDate":1377726216000,"aggregatedStats":{}},{"playerStatSummaryType":"RankedTeam5x5","wins":3,"losses":0,"modifyDate":1383784473000,"aggregatedStats":{"totalChampionKills":28,"totalMinionKills":636,"totalTurretsKilled":6,"totalNeutralMinionsKilled":101,"totalAssists":41}},{"playerStatSummaryType":"Unranked3x3","wins":9,"modifyDate":1421882181000,"aggregatedStats":{"totalChampionKills":90,"totalMinionKills":1427,"totalTurretsKilled":11,"totalNeutralMinionsKilled":428,"totalAssists":105}},{"playerStatSummaryType":"URF","wins":4,"modifyDate":1435024847000,"aggregatedStats":{"totalChampionKills":68,"totalMinionKills":642,"totalTurretsKilled":14,"totalNeutralMinionsKilled":182,"totalAssists":55}},{"playerStatSummaryType":"Unranked","wins":566,"modifyDate":1435549418000,"aggregatedStats":{"totalChampionKills":8419,"totalMinionKills":128213,"totalTurretsKilled":960,"totalNeutralMinionsKilled":26117,"totalAssists":7812}}]}
Heres the link of the second JSON data I want to parse (just adding it, could be useful, but not sure):
https://na.api.pvp.net/api/lol/na/v1.3/stats/by-summoner/43993167/summary?season=SEASON2015&api_key=(took-out-my-private-api-key-for-obvious-reasons)
The link doesn't work because I have to keep my api key private to myself, but the JSON data that it displays is right above the link, which is the what it would result if you were to use the link with the api key.
Just to restate, I would like to process the second part (above of this) of JSON data, but I do not understand how to process multiple links of JSON. I have the first JSON data parsed, but am unable to parse the second JSON data.
I believe Apple is deprecating NSURLConnection. Take a look at NSURLSession. Using it, you can pass in a completion block that takes three arguments: NSData?, NSURLResponse?, and NSError?. The data object contains the JSON you can pass into the JSON serializer. After that, if you need to make another network call, just call it from inside the completion block with another NSURLSession data task. Alamofire is a great framework, but sometimes you don't need everything it provides, and it adds complexity into your app that if something goes wrong or doesn't behave the way you intend/understand, you may not fully understand why. If you want to keep it simple and under your control, use NSURLSession.
let session = NSURLSession.sharedSession()
let task = session.dataTaskWithURL(url) { data, response, error in
// cast response as NSHTTPURLResponse and switch on statusCode if you like
// parse JSON using NSJSONSerialization if you've got data
// spawn off another network call here if you like
}
task.resume() // or in Swift 2, task?.resume()
First, i would totally prefer using some common frameworks for http requests - expecially if youre new in swift. For example here with alamofire.
https://github.com/Alamofire/Alamofire
There is also a version with integrated SwiftyJSON, so you are able to parse JSON Responses very easily.
https://github.com/SwiftyJSON/Alamofire-SwiftyJSON
So if you want to make a request, use this:
Alamofire.request(.GET, "http://httpbin.org/get")
.responseJSON { (_, _, json, _) in
var json = JSON(json)
// get the id out (depends on your structure of JSON):
let id = json["id"].int
}
Now you are able to perform a second Request (with the same Code) - Read the Documentation, how to make different Requests (like with POST) and add Parameters.
If you want to use Segues, so you want to load more data from the ID in another ViewController, you can use Segues to push the data to a second ViewController, and Load the new Content from JSON when the new ViewController is initialised.
Check out this how to send data through segues:
Sending data with Segue with Swift

Resources