Iterating over arrays and extracting data from JSON file - ios

Here is a JSON that I'm receiving from the server
Doubt.JSON
My question is here I'm receiving two "imageData" which is of type Array. How do I extract each one of those and assign them to let's say collection view cells. As in 1st imageData should go to one cell and next so on.
I'm using ALAMOFIRE and SWIFTYJSON. If anybody could help me out using/ not using SwiftyJSON, I'd really appreciate it.
My JSON:
{
"response" : {
"start" : 0,
"docs" : [
{
"enrollmentId" : [
"2534534246"
],
"fieldName2" : [
"Languages"
],
"locality" : [
"XYZ"
],
"active" : [
true
],
"sex" : [
"Male"
],
"latitude" : [
1.2340
],
"city" : [
"udya"
],
"imageData" : [
"data:image\/png;base64,iVBORw0KGgoAAAANSUhEUgAAAEgAAABkCAYAAAAlg3YKAAA1wklEQVR4AcWd95Nc13XnT+c405MHMyACARDMoCxSibYsrWtXP7h2\/1XXbklea4vyWlW2apUp0SbBIJIgEQaYgMk9nXs\/n\/umgUEgCUis8gN7uvv1fffd+70nn3Mfc3fu3BnHf9IxuXHua76\/\/X5dfRbfeeedr3l4X93dZAJjZpFzKvw3OZcf8fn4e+ppPE6THeeO3\/kxAUsbP+QiH\/l0YsxX\/nF+lBtxnn9++QuP4l94\/VdePnaCOQbLa3LkR+PI8523bFJpokyWJuMAISHhx3Qd1xf4YTwaMXFBEqB8DDkfuTxtvSIhNOn+HjDe2+Pkve81esIPXxtATj+N5z4OaTJOoNfrpVen04n9vf3YvXs3Dvb24sbNm7GxtcUE8lEoFWg5juFwwGsYxWIxSoVClHOFmKrVol7le6kS5y9diHPPXohKvZHwGQp0uie0dIxTAvEYnJM4TBbr5Lkv+2z7Pxugyep4g7wrzpGjQwfnivUHg1i\/cydu81pfX48bN67HzRs3Y8Dkh\/y2v7MXnV4nWRqE79z3\/wOcrF6q09MBWgAAAABJRU5ErkJggg=="
],
"fieldValue2" : [
"English, Hindi, Kannada"
],
"fieldValue1" : [
"11 years"
],
"state" : [
"Karnataka"
],
"id" : "Iuusofijpw",
"email" : [
"cont#dontcare.com"
],
"longitude" : [
12.4352
],
"firstName" : [
"Praqwer"
],
"_version_" : 1521637513434759168,
"experience" : [
10
],
"caseTypes" : [
"A Particular caseType let's say Bheema",
],
"lastName" : [
"Bsdtty"
],
"mode" : [
"Lawyer"
],
"fieldName1" : [
"Experience"
]
},
{
"state" : [
"Karnataka"
],
"languages" : [
"English",
"Hindi",
"Kannada"
],
"lastName" : [
"KWE"
],
"firstName" : [
"RANDARTY"
],
"sex" : [
"Male"
],
"caseTypes" : [
"Bheema",
],
"enrollmentId" : [
"4253646"
],
"mobile" : [
42534346
],
"id" : "Iurweoin",
"imageData" : [
"data:image\/png;base64,iVBORw0KGgoAAAANSUhEUgAAAFcAAABkCAYAAADzJqxvAAAgAElEQVR4XjS9ebBv2VkdtvY+8zm\/8c5vfj2r1VJrQgNEiMkYi0m2kmAbE3DhlAPEqcSuciquVIrgMhCTgF1BQgSMkW0EthkEGCQQIAQCScgSaqk19Ot+3W++872\/8Yz7nL1T6zvP\/Qelbu793XP28H3rW2t9308d3P2iaxEggIdivcBgmCDQPirTwA8UqlIhiDV8pdB0JZz2AevBg4+mrgHTAoHGMElR1DX8MIJvLKzXojMafgg0dQMFwPM9dI2D8g06aHidD4sWjXYAFBLto1WAcw3asoNrLaxSsF0vLKiqrrJc3fu6t12JWqm5qdnbeWJUJF8OipsQ8UJGq6cvVNjU9MWIbHQUeNhbJxGDSYVn0TPQUv4GxJKG0Skpv+tuHWBqbXQ6WSyOjA\/VtRCUqZYrH4UUv2\/ziJ\/f\/aiwX2jbsXKz3ga\/aN+4CG28vb9o27Fys94Gv2jfuAhtvL2\/aNuxcrPeBr\/g2M2m9YyIB6mAAAAABJRU5ErkJggg=="
],
"active" : [
true
],
"mode" : [
"Kelsa"
],
"city" : [
"Udya"
],
"_version_" : 15216,
"email" : [
"Him#somenone.com"
],
"experience" : [
18223
],
"locality" : [
"XYZ"
]
}
],
"numFound" : 2
},
"responseHeader" : {
"status" : 0,
"QTime" : 5,
"params" : {
"q" : "mode:(\"Lawyer\", \"CA\") AND active:true AND city:(\"Bereello\") AND locality:(\"XYZ\") AND caseTypes:(\"Momerty\")",
"wt" : "json"
}
}
}
My code:
Alamofire.request(.GET, url!)
.validate()
.responseJSON{ response1 in
switch response1.result{
case .Success:
let json33 = JSON(data: response1.data!)
print(json33)
if let userDict = json33["response"].dictionary{
if let array = userDict["docs"]?.array{
for imgd in array{
let me:String! = imgd["imageData"][0].string
let url = NSURL(string: me)!
let data = NSData(contentsOfURL: url)!
let image = UIImage(data: data)
let imgView = UIImageView(image: image!)
imgView.frame = CGRect(x: 0, y: 0, width: 200, height: 200)
self.view.addSubview(imgView)
}
}
}

Each one of your dictionaries has one entry for the image text, and these dictionaries are in an array.
I would use flatMap to quickly get these image strings:
let allImageStrings = json["response"]["docs"].flatMap { $0.1["imageData"].first?.1 }
Explanation: we iterate over json["response"]["docs"] and we access the second part of the tuple (remember, a SwiftyJSON object always has (index, value)) and from there we take the second part of the first tuple inside ["imageData"].
It looks complex like that but when you look at the JSON structure it's actually rather clear.

Related

hive table to view the avro records which is streamed using flume getting Block size invalid or too large for this implementation: -40

I am creating the hive serde external table to view the twitter records which is streaming using flume.
My property file
# Naming the components on the current agent.
TwitterAgent.sources = Twitter
TwitterAgent.channels = MemChannel
TwitterAgent.sinks = HDFS
# Describing/Configuring the source
TwitterAgent.sources.Twitter.type = org.apache.flume.source.twitter.TwitterSource
TwitterAgent.sources.Twitter.consumerKey = xxx
TwitterAgent.sources.Twitter.consumerSecret = xxx
TwitterAgent.sources.Twitter.accessToken = xxx
TwitterAgent.sources.Twitter.accessTokenSecret = xxx
TwitterAgent.sources.Twitter.keywords = kafka
# Describing/Configuring the sink
TwitterAgent.sinks.HDFS.type = hdfs
TwitterAgent.sinks.HDFS.hdfs.path = hdfs://xxx:8000/topics/flumedata
TwitterAgent.sinks.HDFS.hdfs.fileType = DataStream
TwitterAgent.sinks.HDFS.hdfs.writeFormat = Text
TwitterAgent.sinks.HDFS.hdfs.batchSize = 10000
TwitterAgent.sinks.HDFS.hdfs.rollSize = 0
TwitterAgent.sinks.HDFS.hdfs.rollCount = 100000
TwitterAgent.sinks.hdfs.serializer=Text
# Describing/Configuring the channel
TwitterAgent.channels.MemChannel.type = memory
TwitterAgent.channels.MemChannel.capacity = 100000
TwitterAgent.channels.MemChannel.transactionCapacity = 1000
TwitterAgent.channels.MemChannel.byteCapacity = 6912212
# Binding the source and sink to the channel
TwitterAgent.sources.Twitter.channels = MemChannel
TwitterAgent.sinks.HDFS.channel = MemChannel
Query to create a hive external table
CREATE EXTERNAL TABLE twitter_tweets
COMMENT "just drop the schema right into the HQL"
ROW FORMAT SERDE 'org.apache.hadoop.hive.serde2.avro.AvroSerDe'
STORED AS INPUTFORMAT 'org.apache.hadoop.hive.ql.io.avro.AvroContainerInputFormat'
OUTPUTFORMAT 'org.apache.hadoop.hive.ql.io.avro.AvroContainerOutputFormat'
TBLPROPERTIES (
'avro.schema.literal'='{
"type" : "record",
"name" : "Doc",
"doc" : "adoc",
"fields" : [ {
"name" : "id",
"type" : "string"
}, {
"name" : "user_friends_count",
"type" : [ "int", "null" ]
}, {
"name" : "user_location",
"type" : [ "string", "null" ]
}, {
"name" : "user_description",
"type" : [ "string", "null" ]
}, {
"name" : "user_statuses_count",
"type" : [ "int", "null" ]
}, {
"name" : "user_followers_count",
"type" : [ "int", "null" ]
}, {
"name" : "user_name",
"type" : [ "string", "null" ]
}, {
"name" : "user_screen_name",
"type" : [ "string", "null" ]
}, {
"name" : "created_at",
"type" : [ "string", "null" ]
}, {
"name" : "text",
"type" : [ "string", "null" ]
}, {
"name" : "retweet_count",
"type" : [ "long", "null" ]
}, {
"name" : "retweeted",
"type" : [ "boolean", "null" ]
}, {
"name" : "in_reply_to_user_id",
"type" : [ "long", "null" ]
}, {
"name" : "source",
"type" : [ "string", "null" ]
}, {
"name" : "in_reply_to_status_id",
"type" : [ "long", "null" ]
}, {
"name" : "media_url_https",
"type" : [ "string", "null" ]
}, {
"name" : "expanded_url",
"type" : [ "string", "null" ]
} ]
}');
LOAD DATA INPATH '/topics/flumedata/FlumeData.*' OVERWRITE INTO TABLE twitter_tweets;
After creating the table, when i hit select * from twitter_tweets;
It is not giving any data, it throughs an error
org.apache.hive.service.cli.HiveSQLException: java.io.IOException: org.apache.avro.AvroRuntimeException: java.io.IOException: Block size invalid or too large for this implementation: -40
Where i went wrong, i dono why iam getting this block size issue. Can anyone guide me.

Creating a Request body for Alamofire

I need to make a request body looking like this:
{
"accepted" : [
{
"deposit" : 2000,
"name" : "Tuxedo",
"rent" : 100,
"id" : 3,
"favourited_by" : [
],
"tag_id" : 21,
"status" : "unknown",
"image_url" : "https:\/\/www.moss.co.uk\/images\/extralarge\/965549415_01.jpg",
"addresses" : [
]
},
{
"deposit" : 3000,
"name" : "ps4",
"rent" : 50,
"id" : 2,
"favourited_by" : [
],
"tag_id" : 16,
"status" : "unknown",
"image_url" : "http:\/\/www.spokeslabs.com\/jstone\/ps4_images\/ps4-hrdware-large18.jpg",
"addresses" : [
]
},
{
"deposit" : 1000,
"name" : "Electric drill",
"rent" : 100,
"id" : 1,
"favourited_by" : [
],
"tag_id" : 11,
"status" : "unknown",
"image_url" : "https:\/\/static.independent.co.uk\/s3fs-public\/styles\/story_medium\/public\/thumbnails\/image\/2016\/06\/20\/12\/ryobi-rpd800-k-percussion-d.jpg",
"addresses" : [
]
}
],
"rejected" : [
],
"address" :
{
"city" : "Hong Kong",
"lng" : "114.162699999745",
"country" : "Hong Kong",
"street" : "Barker Road",
"id" : "0",
"label" : "Home",
"lat" : "22.269837686727"
}
}
Unfortunantly I'm sending this:
{
"accepted" : [
{
"deposit" : 2000,
"name" : "Tuxedo",
"rent" : 100,
"id" : 3,
"favourited_by" : [
],
"tag_id" : 21,
"status" : "unknown",
"image_url" : "https:\/\/www.moss.co.uk\/images\/extralarge\/965549415_01.jpg",
"addresses" : [
]
},
{
"deposit" : 3000,
"name" : "ps4",
"rent" : 50,
"id" : 2,
"favourited_by" : [
],
"tag_id" : 16,
"status" : "unknown",
"image_url" : "http:\/\/www.spokeslabs.com\/jstone\/ps4_images\/ps4-hrdware-large18.jpg",
"addresses" : [
]
},
{
"deposit" : 1000,
"name" : "Electric drill",
"rent" : 100,
"id" : 1,
"favourited_by" : [
],
"tag_id" : 11,
"status" : "unknown",
"image_url" : "https:\/\/static.independent.co.uk\/s3fs-public\/styles\/story_medium\/public\/thumbnails\/image\/2016\/06\/20\/12\/ryobi-rpd800-k-percussion-d.jpg",
"addresses" : [
]
}
],
"rejected" : [
],
"address" : [
{
"city" : "Hong Kong",
"lng" : "114.162699999745",
"country" : "Hong Kong",
"street" : "Barker Road",
"id" : "0",
"label" : "Home",
"lat" : "22.269837686727"
}
]
}
The difference is in the last section of the JSON. What I'm sending contains an array of addresses but I want to be sending just contains one address object.
This request body gets created the following way:
var parameters = [String:[AnyObject]]()
parameters["rejected"] = rejectedItemsArray as [AnyObject]
parameters["accepted"] = acceptedItemsArray as [AnyObject]
parameters["address"] = addressArray as [AnyObject]
let request = NSMutableURLRequest(URL: NSURL(string: urlString)!)
request.setValue(self.token!, forHTTPHeaderField: Constant.tokenUserDefaultsKey)
request.HTTPMethod = "POST"
do {
let data = try NSJSONSerialization.dataWithJSONObject(parameters, options: .PrettyPrinted)
let requestBodyString = String(data: data, encoding: NSUTF8StringEncoding)
NSLog("Request Body: %#", requestBodyString!)
request.HTTPBody = data
} catch ( _) {
NSLog("Failed to encode json for Post Items")
}
How do I fix it?
I want to have 2 arrays in my JSON:
1 - "accepted"
2 - "rejected"
And 1 single object in my JSON:
1 - "address"
Problem is in this line parameters["address"] = addressArray as [AnyObject]. You are setting Array with address key instead of that you need to set dictionary. So create addressDic like this.
let adddressDic = ["city" : "Hong Kong", "lng" : "114.162699999745", "country" : "Hong Kong",
"street" : "Barker Road", "id" : "0", "label" : "Home", "lat" : "22.269837686727"]
Now set this Dictionary with address key
parameters["address"] = adddressDic
Edit: You need to also change the declaration of parameters like this.
var parameters = [String:AnyObject]()
parameters["address"] = addressArray as [Any]
Here (in this line of code) you are assigning array instance. Create a JSON object (Dictionary) of 'addressArray' and then assign it to parameter["address"]
e.g.
var addresArray = [String : Any]()
//Store json values/information in it and then
parameters["address"] = addressArray as [String : Any]

create json array in swift alamofire

Here is the request format that server requires ,
{
"internal_name": "SDSSD",
"display_name": "SDSDSDSD",
"image": "sesse.jpg",
"notes": "sdsdsdsdsdsdsdsd",
"short_description": "ssdsdsd",
"long_description": "sdsdsdsd",
"ean_code": "3434343434",
"status": "not_verified",
"state": "active",
"quantity": 1,
"brand": {
“name”: “My Brand”
},
"categories": [
{
“id”: “My Category”
}
]
}
In here , as you can see , it requires , categories as an array , so my question is how can i create an array . using swift . here is my swift code
let parameters :[String:AnyObject] = [
"internal_name":product.displayName,
"display_name":product.displayName,
"language":Constant.Language.LAN_ENGLISH,
"notes":product.initialName,
"image": product.photo,
"short_description":product.longDescription,
"long_description":product.longDescription,
"ean_code":product.eanCode,
"status":product.status,
"state":Constant.Status.STATUS_ACTIVE,
"categories": [
"id":product.categoryObject.id
],
"quantity":1,
]
this doesnt accept from the server since its not an array , what am i missing here
Try below code :
let parameters :Parameters = [
"internal_name":product.displayName,
"display_name":product.displayName,
"language":Constant.Language.LAN_ENGLISH,
"notes":product.initialName,
"image": product.photo,
"short_description":product.longDescription,
"long_description":product.longDescription,
"ean_code":product.eanCode,
"status":product.status,
"state":Constant.Status.STATUS_ACTIVE,
"brand" : ["name" : "My Brand"],
"categories": [
["id":product.categoryObject.id]
],
"quantity":1,
]

Sorting Through NSData Results

I use a Web API from Spotify in my app to find a track by a particular artist within Spotify. The results look like this:
"tracks" : {
"href" : "https://api.spotify.com/v1/search?query=track%3A%22Dude+Looks+Like+A+Lady+%22+artist%3A%22+Aerosmith%22&offset=0&limit=1&type=track",
"items" : [ {
"album" : {
"album_type" : "album",
"available_markets" : [ "CA", "MX", "US" ],
"external_urls" : {
"spotify" : "https://open.spotify.com/album/3XYqOJI1YlX40kJTdzFEzp"
},
"href" : "https://api.spotify.com/v1/albums/3XYqOJI1YlX40kJTdzFEzp",
"id" : "3XYqOJI1YlX40kJTdzFEzp",
"images" : [ {
"height" : 640,
"url" : "https://i.scdn.co/image/948208cdb26864468ee4320070cd10e6b580d852",
"width" : 640
}, {
"height" : 300,
"url" : "https://i.scdn.co/image/087aeee7ed7b7397f5cf5a4c90bc0532d7a3319c",
"width" : 300
}, {
"height" : 64,
"url" : "https://i.scdn.co/image/562e9fa179952065137a17b175b5bca0647d5f47",
"width" : 64
} ],
"name" : "Permanent Vacation (Remastered)",
"type" : "album",
"uri" : "spotify:album:3XYqOJI1YlX40kJTdzFEzp"
},
"artists" : [ {
"external_urls" : {
"spotify" : "https://open.spotify.com/artist/7Ey4PD4MYsKc5I2dolUwbH"
},
"href" : "https://api.spotify.com/v1/artists/7Ey4PD4MYsKc5I2dolUwbH",
"id" : "7Ey4PD4MYsKc5I2dolUwbH",
"name" : "Aerosmith",
"type" : "artist",
"uri" : "spotify:artist:7Ey4PD4MYsKc5I2dolUwbH"
} ],
"available_markets" : [ "CA", "MX", "US" ],
"disc_number" : 1,
"duration_ms" : 265773,
"explicit" : false,
"external_ids" : {
"isrc" : "USIR10000454"
},
"external_urls" : {
"spotify" : "https://open.spotify.com/track/6gQUbFwwdYXlKdmqRoWKJe"
},
"href" : "https://api.spotify.com/v1/tracks/6gQUbFwwdYXlKdmqRoWKJe",
"id" : "6gQUbFwwdYXlKdmqRoWKJe",
"name" : "Dude (Looks Like A Lady)",
"popularity" : 55,
"preview_url" : "https://p.scdn.co/mp3-preview/7d85766664041815e16b54eb014d3d120f883db8",
"track_number" : 5,
"type" : "track",
"uri" : "spotify:track:6gQUbFwwdYXlKdmqRoWKJe"
} ],
"limit" : 1,
"next" : "https://api.spotify.com/v1/search?query=track%3A%22Dude+Looks+Like+A+Lady+%22+artist%3A%22+Aerosmith%22&offset=1&limit=1&type=track",
"offset" : 0,
"previous" : null,
"total" : 7
}
The only part that I actually need is the FINAL external_urls line that looks like this:
"external_urls" : {
"spotify" : "https://open.spotify.com/track/6gQUbFwwdYXlKdmqRoWKJe"
},
As this is the one that contains the specific app. I have done about 100 tries with the Web API, and this is the way it always appears. So my question is HOW can I pull out JUST this one area?

different data type using dictionary in swift?

I just learned about NSURLSession. I want to make POST request. it needs JSON as the body.
when using Objective-C I used NSDictionary, but in swift I Dictionary only hold 1 data type. what is the alternative to implement this in swift?
{
"userID" : "xxxxxxxx",
"full_name" : "xxxxxxxxx",
"pob" : "xxxxxxxxxx"
"dob" : "xxxxxxxxxxx",
"status" : 3,
"phone_number" : null,
"education" : [
{
"university" : "xxxxxx",
"location": {
latitude: "xxxxxxx",
longitude: "xxxxxxxx"
},
"degree": "xxxxxx"
},
{
"university" : "xxxxxx",
"location": {
latitude: "xxxxxxx",
longitude: "xxxxxxxx"
},
"degree": "xxxxxx"
}
]
}
i'm really stuck, I've looking for the solution for hours but no luck. haven't found any tutorial about this in google.
thank you very much, sorry for my bad English.
Just use Dictionary<Any, Any>, it's like NSDictionary
You can still use NSDictionary:
var dictionary: NSDictionary = [
"userID" : "xxxxxxxx",
"full_name" : "xxxxxxxxx",
"pob" : "xxxxxxxxxx",
"dob" : "xxxxxxxxxxx",
"status" : 3,
"phone_number" : NSNull(),
"education" : [
[
"university" : "xxxxxx",
"location": [
"latitude" : "xxxxxxx",
"longitude" : "xxxxxxxx"
],
"degree": "xxxxxx"
],
[
"university" : "xxxxxx",
"location": [
"latitude": "xxxxxxx",
"longitude": "xxxxxxxx"
],
"degree": "xxxxxx"
]
]
]
For easy working with JSON responses you can use libraries like:
https://github.com/owensd/json-swift
https://github.com/SwiftyJSON/SwiftyJSON
Try like this :-
var dictionary = Dictionary<String, Any>
dictionary["userID"] = "xxxxxxxx"
dictionary["status"] = 200
like that ...

Resources