Fetch first element in JSON with Swift - json

I have a JSON string, an example is shown in the screenshot below. How can I print to the console the first element from a given array?
I've tried different options for converting a date to a string, but the string won't let me get the first element in its entirety

I recommend using a package like SwiftyJSON to work with JSON in Swift. You can add it via Swift Package Manager or CocoaPods, whichever you prefer.
Supposing to have this JSON string:
let json = "[{\"id\" : 0, \"text\" : \"hello\"},{\"id\" : 1, \"text\" : \"hi\"}]"
You can parse it as shown, and then retrieve and print to console the first item:
if let data = json.data(using: .utf8) {
if let json = try? JSON(data: data) {
print(json[0])
}
}
This will print on the console as:
{
"text" : "hello",
"id" : 0
}
Remember to import SwiftyJSON at the top of the swift file

Related

How can we format or convert the Xcode log or print in JSON format?

Is there a way we can convert the Xcode print or log in the JSON format?
Currently if we print or log a dictionary or JSON, it shows like this:
data = {
currentCity = Mycity;
friends = 4;
images = (
);
suggestions = 3;
}
but if we want Xcode to print in the proper json format like this, what can we do?
"data": {
"currentCity": "Mycity",
"friends": 4,
"images": [],
"suggestions": 3
}
Or is there any tool available that converts the Xcode print or log in pretty JSON format?
There is a very simpler way in swift
use need to use this pod: SwiftyJSON
Install the pod and use the following code:
import SwiftyJSON
func printInJSON {
var dictionary: [String : Any] = [:]
dictionary["build_number"] = "1.0"
dictionary["data"] = "Print in JSON format on iOS xcode"
// SwiftyJson magic
let json = JSON(dictionary)
print(json)
}
Output:
{
"build_number" : "1.0"
"data" : "Print in JSON format on iOS xcode"
}
If you are printing an object that is coming back from a network request, I find using Charles Proxy is usually easier. It will format it in JSON and it is a very useful debugging tool.
You may try in console:
po print(data)
It usually helped me

How can I decode a generic JSON response in Swift 4?

I'm building an app with Swift 4 that consumes a JSON-RPC API. The responses all have the same general format:
{
"jsonrpc": "2.0",
"result" : { "data_type" : [ ...a bunch of instances of data_type... ] }
"id": 1
}
Where data_type would be payments, channels, peers, and so on depending on the query.
I have Decodable struct definitions for each of the data types, but I don't know how to handle the main response.
I really don't care about the jsonrpc or id fields, I'm just interested in the contents of result.
I tried:
struct LightningRPCResponse: Decodable {
let id: Int
let result: String
let json_rpc: String
}
But I got the error:
Expected to decode String but found a dictionary instead
So I tried:
struct LightningRPCResponse: Decodable {
let id: Int
let result: Dictionary
let json_rpc: String
}
But I got the error:
Reference to generic type 'Dictionary' requires arguments in <...>
Is what I'm trying to do possible or do I need to create separate response decoders to correspond to every single RPC request?
Or...should I just use string manipulation to lop off the superfluous data?
You could make two structs:
struct generalStruct:Codable {
let jsonrpc:String
let id:Int
let result:[resultsStruct]
}
struct resultsStruct{
//assuming that you have strings in here, cause you didn't specify that. And it's considered as a Dictionary like: "data_tupe":"string_value" or if you have an array also here than just make another struct or just make data_type:[String]
let data_type:String
}
With that structs you can decode now. Example:
let json = try decoder.decode(generalStruct.self, from: response.data!)
//here you can get access to each element of your 'data_type'
for obj in json.result{
for data in obj.data_type {
//you have every element from dict access here if its more objects inside every 'data_type'
}
}

change JSON to String in Swift [duplicate]

This question already has answers here:
Simple and clean way to convert JSON string to Object in Swift
(17 answers)
Closed 5 years ago.
I got JSON file from API but the content looks like this:
[
"https:\/\/seekingalpha.com\/article\/4125943-apple-homepod-delay-big-deal?source=feed_symbol_AAPL"
]
Suppose the JSON Object above is named as json. Then I just convert the object to string using String() method.
strings = String(json)
When I changed it to String type, it seems to get unnecessary '\n' and whitespace in it.
"[\n \"https:\\/\\/seekingalpha.com\\/article\\/4125943-apple-homepod-delay-big-deal?source=feed_symbol_AAPL\"\n]"
So it seems like the content of the JSON file is:
["\n""whitespace""whitespace""String""\n"]
When I changed it to String type, Swift just treats all the elements in it as a whole and wrapped it as a string.
My question is, how to extract the String inside so it looks like:
"https:\\/\\/seekingalpha.com\\/article\\/4125943-apple-homepod-delay-big-deal?source=feed_symbol_AAPL\"
As I am not so familiar with Swift so how to extract String or JSON Object is not easy for me. Any hints or help will be appreciated.
Swift 3,4 :
The given JSON format is Array of String.
if let json = try? JSONSerialization.jsonObject(with: data, options: .allowFragments) as? [String]{
let firstElement = json?.first ?? "Element Not Found!"
print(firstElement)
}
Swift 4:
if let json = try? JSONDecoder().decode(Array<String>.self, from: data){
let firstElement = json.first ?? "First Element Not Found!"
print(firstElement)
}
Note:
If your the Array contains more than one String. Here,urls is the class variable. i.e.,var urls = [String]()
Swift 3,4 :
if let json = try? JSONSerialization.jsonObject(with: data, options: .allowFragments) as? [String]{
if json != nil{
self.urls = json!
}
print(self.urls)
}
Swift 4:
if let json = try? JSONDecoder().decode(Array<String>.self, from: data){
self.urls = json
}
1. You will first have to convert JSON to Data
2. Convert data to string wrt to encoding
func jsonToString(jsonTOConvert: AnyObject){
do {
let data = try JSONSerialization.data(withJSONObject: jsonTOConvert, options: JSONSerialization.WritingOptions.prettyPrinted)
let convertedString = String(data: data, encoding: String.Encoding.utf8)
} catch let myJSONError {
print(myJSONError)
}
}
You are asking that a String be created with the contents:
[
"https:\/\/seekingalpha.com\/article\/4125943-apple-homepod-delay-big-deal?source=feed_symbol_AAPL"
]
The string object is doing exactly what you told it to — the thing you've asked it to represent begins with a square bracket, then there's a line break, then two spaces, etc, so the string contains a square bracket, then a line break, then two spaces, etc. There is no 'unnecessary' \n, there is only the \n you told it to put in.
If you obtained a JSON object then you need to parse it as JSON. JSONSerialization will do that job. What you've actually got is an array with a single item, which is a string. So JSONSerialization will return an array. The first item of that should be a string that is the seekingalpha.com URL.

AlamoFire 4.0 + SwiftyJSON Unwrapping deeply nested JSON

I'm having issues parsing the JSON I'm getting back from the Wiki API.
Podfile:
platform :ios, ’10.0’
inhibit_all_warnings!
use_frameworks!
target 'GemFinder' do
pod 'Alamofire', '~> 4.0’
pod 'SwiftyJSON', :git => 'https://github.com/appsailor/SwiftyJSON.git', :branch => 'swift3'
end
Swift Code:
import UIKit
import Alamofire
import SwiftyJSON
class WikiAPI: NSObject {
func MineralRequest(minID: (String)) {
Alamofire.request("https://en.wikipedia.org/w/api.php?action=query&titles=\(minID)&exintro=1&prop=pageimages%7Cextracts&format=json&pithumbsize=300", parameters: ["query": "pages"]).responseJSON { response in
if let values = response.result.value as? [String: AnyObject] {
let json = JSON(values)
// Returns null
print("otherJSON: \(json["query"]["pages"][0]["extract"])")
let JSONvalues = values as NSDictionary
print("JSONvalues: \(JSONvalues)")
// This is also working to retrieve everything from below "query"
let parse = JSONvalues.object(forKey: "query")
print("Parse: \(parse)")
let queryValues = values["query"]
// Returns nested "pages" object, but I need to go deeper.
print("queryvalues: \(queryValues?["pages"])")
}
}
}
}
I'm able to get a response, of course, and trying to go deeper, but I keep getting null values when trying to unwrap.
What am I missing? Here's an image of the tree. I'm trying to pull title, images and the extract out.
JSON response preview
Following this format, as seen here, still yields null values. Parameters didn't seem to benefit either: How do I access a nested JSON value using Alamofire and SwiftyJSON?
"pages" value is a dictionary so using [0] on it won't work, you need to use the key instead:
print("otherJSON: \(json["query"]["pages"]["1895477"]["extract"])")
Or if there are many items in pages and you want them all you can iterate through it like:
let pages = json["query"]["pages"]
for (_,page) in pages {
print(page["extract"])
}

How to parse JSON in Swift 2?

I have a PHP web api that returns json in the following format:
{"users":[
{"user": {id:"1","name":"ahmad"}},
...
]}
In my Swift 2 code, I am able to retrieve the data above store it in an NSArray named users
Now, I need to iterate throw each user to convert it into an object:
for user in users {
print("found: \(user)")
}
That ouputs something like:
found: {
user = {
id = 1;
name = ahmad;
};
}
but when I try to access any element of that object I get an error:
let id = user["user"]["id"] //does not work: Xcode wont compile
let id2 = user["user"]!["id"]! //does not work: Xcode wont compile
let id3 = user!["user"]!["id"]! //does not work: Xcode wont compile
Then I tried :
if let u=user["user"] { //does not work: Xcode wont compile
// do somthing
}
I put a break point at print("\(user)") to see what is going on, and here is what I found:
When I print the description of each individual user I get:
How can I access the elements of this JSON data in Swift 2?
A NSArray only holds AnyObject so you have to cast it (to Array<Dictionary<String, Dictionary<String, String>>>. Below you see the shorthand):
// this is a forced cast and you probably get runtime errors if users cannot be casted
for user in users as! [[String : [String : String]]] {
print("found: \(user)")
}