Unable to append an array of images to another array swift - arrays

MY JSON:
{
"response" : {
"start" : 0,
"docs" : [
{
"enrollmentId" : [
"KAR\KDF6"
],
"fieldName2" : [
"Languages"
],
"locality" : [
"Boret"
],
"active" : [
true
],
"sex" : [
"Male"
],
"latitude" : [
12.457
],
"city" : [
"Booer"
],
"imageData" : [
"data:image\/png;base64,iVBORw0KGgoAAAANSUhEUgAAAEgAAABkCAYAAAAlg3YKAAA1wklEQVR4AcWd95Nc13XnT+c405MHMyACARDMoCxSibYsrWtXP7h2\/1XXbklea4vyWlW2apUp0SbBIJIgEQaYgMk9nXs\/n\/umgUEgCUis8gN7uvv1fffd+70nn3Mfc3fu3BnHf9IxuXHua76\/\/X5dfRbfeeedr3l4X93dZAJjZpFzKvw3OZcf8fn4e+ppPE6THeeO3\/kxAUsbP+QiH\/l0YsxX\/nF+lBtTOn4857H+MY7zIDhiY2AsKKWFzuAiRIOJfGbptjDCQO7GkRBVMaOBCPBMCJC9JvGY7ZTQSJfwq8ErLBmxrLTX4av1lZYb+ykg+XTEKbGZjGSfdIvocPCWCQAFaHzdzCbTnw3DMXAGqO68hpIT\/MiXnrJsL5\/atYzFTD+gS9RAmwfBor4xAg2cj\/cYlU6x42DcYZnpbVJGl4\/U\/X0ITsNeIaJz4BwflOjgyDybcMqNz+7oEBtgSNA0kwCU4alt85w0TSD\/yx42Qs8u5pm6X\/e4Gkfgyq1mn6wauhuvTkXhdAvc9F8n2yPzxln1Cf7GIEgFNsGaemh3P+8x6OxmIHt0ZNszmlhHCWYh9kFSgBWZQA4woXxc4UByOu1bIvUaSl+5AOfncuE7fE4Xl4WRqE79z3\/wOcrF6q09MBWgAAAABJRU5ErkJggg=="
],
"fieldValue2" : [
"English, Hindi, Kannada"
],
"fieldValue1" : [
"11 years"
],
"state" : [
"Kerr"
],
"id" : "sdffsdfsdf",
"email" : [
"me#some.com"
],
"longitude" : [
77.552492
],
"firstName" : [
"Prashya"
],
"_version_" : 145434759168,
"experience" : [
12
],
"caseTypes" : [
"some some"
],
"lastName" : [
"Bhaer"
],
"mode" : [
"Lawyer"
],
"fieldName1" : [
"Experience"
]
},
{
"state" : [
"Rater"
],
"languages" : [
"English",
"Hindi",
"Kannada"
],
"lastName" : [
"K"
],
"firstName" : [
"Rresr"
],
"sex" : [
"Male"
],
"caseTypes" : [
"So many"
],
"enrollmentId" : [
"KARdsfs"
],
"mobile" : [
98453445
],
"id" : "Rajfsdsg",
"imageData" : [
"data:image\/png;base64,iVBORw0KGgoAAAANSUhEUgAAAFcAAABkCAYAAADzJqxvAAAgAElEQVR4XjS9ebBv2VkdtvY+8zm\/8c5vfj2r1VJrQgNEiMkYi0m2kmAbE3DhlAPEqcSuciquVIrgMhCTgF1BQgSMkW0EthkEGCQQIAQCScgSaqk19Ot+3W++872\/8Yz7nL1T6zvP\/Qelbu793XP28H3rW2t9308d3P2iaxEggIdivcBgmCDQPirTwA8UqlIhiDV8pdB0JZz2AevBg4+mrgHTAoHGMElR1DX8MIJvLKzXojMafgg0dQMFwPM9dI2D8g06aHidD4sWjXYAFBLto1WAcw3asoNrLaxSsFCIAw1oD0p1aIyF5\/nwPaCrOvhRgLyukIUx6qaCFwZo8gpRmuDC9YtQqoVdnsM2FaraomkrFMbBMw424ucEcI3hA6IuGwSJj6Zr0Rog8Bw8P0DTOrTGwnVAGFh0ms9p4Ssf4LvWCspqtNpBKeD85BTq+OBFZ42DcgodOvi+B2NbaOcjgsa6qRFFGs4CbeMQRB5MW8M0LbIgg+9ZlMbJH3D8DNPBtwZhNkDTVEiyEcqmhG4VoshDVXcI\/QCds2iqHHGSwlmH2vL3W3g6hIKCaVv4AdBw84xFFPnouk7+hlVA11l4yke3+cSnLBW0vLKiqrrJc3fu6t12JWqm5qdnbeWJUJF8OipsQ8UJGq6cvVNjU9MWIbHQUeNhbJxGDSYVn0TPQUv4GxJKG0Skpv+tuHWBqbXQ6WSyOjA\/VtRCUqZYrH4UUv2\/ziJ\/f\/aiwX2jbsXKz3ga\/aN+4CG28vb9o27Fys94Gv2jfuAhtvL2\/aNuxcrPeBr\/g2M2m9YyIB6mAAAAABJRU5ErkJggg=="
],
"active" : [
true
],
"mode" : [
"Lawyer"
],
"city" : [
"Bangalore"
],
"_version_" : 15214536,
"email" : [
"me#me.com"
],
"experience" : [
18
],
"locality" : [
"bajaj"
]
}
],
"numFound" : 2
},
"responseHeader" : {
"status" : 0,
"QTime" : 1,
"params" : {
"q" : "mode:(\"Lawyer\", \"CA\") AND active:true AND city:(\"Boret\") AND locality:(\"bajaj\") AND caseTypes:(\"fly fly\")",
"wt" : "json"
}
}
}
I've declared a global array private var items = [UIImage]() and private var cellsIsOpen = [Bool]() .
I'm converting the bas64 imageData strings obtained from JSON data and returning an array of UIImage like
public func loadimages(url: String!) -> [UIImage]{
let unsafe = url
var data1 = [UIImage]()
let bingo = NSURL(string: unsafe!)
Alamofire.request(.GET, bingo!)
.validate()
.responseJSON{ response in
switch response.result{
case .Success:
let json33 = JSON(data: response.data!)
let allImageStrings = json33["response"]["docs"].flatMap { $0.1["imageData"].first?.1}
for Bro in allImageStrings{
let url = NSURL(string: Bro.string!)
let data = NSData(contentsOfURL: url!)!
let image = UIImage(data: data)
data1.append(image!)
}
self.items = data1
//print(self.items.count)
case .Failure(let error):
print(error)
}
}
return data1
}
And in
override public func collectionView(collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
print(self.items.count)
return self.items.count
}
the count is showing 0. The Array items is not getting appended AT ALL. How do I append it? I'm even trying to do
override public func viewDidLoad() {
// Do any additional setup after loading the view.
itemSize = CGSize(width: 214, height: 264)
super.viewDidLoad()
let gt: [UIImage] = loadimages("someurl&wt=json")
items.append(gt) //Error: Cannot convert value of type '[UIImage]' to expected argument type 'UIImage'
print(items.count)
}
And there it this function
func collectionView(collectionView: UICollectionView, willDisplayCell cell: UICollectionViewCell, forItemAtIndexPath indexPath: NSIndexPath) {
guard let cell = cell as? CollectViewCell else { return }
// var index = indexPath.row % 4
//let info = items
for item in items{
cell.backgroundImageView.image = item
}
cell.cellIsOpen(cellsIsOpen[indexPath.row], animated: false) //Here
collectionView.reloadData()
}
*Here, it crashes saying Index out of range.
Help Please?

It looks like your problem might be with your Alamofire request. Either it fails and so nothing it appended since you append under your success case, or you're trying to print the items before anything is loaded because it is an asynchronous request. Try appending an image under your failure case.
Also the reason you are getting the error "Cannot convert value of type '[UIImage]' to expected argument type 'UIImage' " is because you are trying to append an entire array to an array, when you need to just append a single element, in this case, a UIImage.
try this to test the size of your array instead
let gt: UIImage = UIImage()
items.append(gt)
print(items.count)

Alamofire is nice that it grabs the main thread in the callback making UI easy to update. Your first call to collectionView's dataSource methods will be before the request is done. However. calling collectionView.reloadData() after setting self.items should solve your issue.
case .Success:
let json33 = JSON(data: response.data!)
let data = json33["response"].stringValue.dataUsingEncoding(NSUTF8StringEncoding, allowLossyConversion: false)
let json = JSON(data: data!)
let allImageStrings = json["docs"].flatMap { $0["imageData"].first?.stringValue }
for Bro in allImageStrings{
let imgString = Bro.stringByReplacingOccurrencesOfString("data:image/png;base64," , withString: "")
let imgData = imgString.dataUsingEncoding(NSUTF8StringEncoding, allowLossyConversion: false)
let image = UIImage(data: imgData)
data1.append(image!)
}
self.items = data1
//Add
self.collectionView.reloadData()
All data source methods are recalled on the collectionView when reloadData() is called so if you have successfully created images (This may be an underlying problem as well), you should get a count the next time these dataSource methods are called.

Try this
Replace this array type
var data1 = [UIImage]()
with this type of array for type safety sometime array not getting correct format so failed to append value
Use this Array:-
var data1 = [AnyObject]()
I hope this will help you.

Related

Find value json array swift

I'm trying to find a specific value in my JSON.
this my json
[
{
"airportName" : "Simon Mwansa Kapwepwe Intl",
"longitude" : 28.664999999999999,
"geometry" : {
"type" : "Point",
"coordinates" : [
28.664999999999999,
-12.994999999999999
]
},
"countryCode" : "ZMB",
"countryName" : "Zambia",
"latitude" : -12.994999999999999,
"cityName" : "Ndola",
"airportCode" : "FLSK"
},
{
"airportName" : "Mafikeng",
"longitude" : 25.544469444444445,
"geometry" : {
"type" : "Point",
"coordinates" : [
25.544469444444445,
-25.807447222222223
]
},
"countryCode" : "ZAF",
"countryName" : "South African Rep",
"latitude" : -25.807447222222223,
"cityName" : "Mafikeng",
"airportCode" : "FAMM"
}]
now if I write this code it works!
for item in 0...json.count {
i = i+1
if json[i]["airportName"] == "Simon Mwansa Kapwepwe Intl" {
print ("I found it")
}
if I try to pass the parameter to search with a function it doesn't work, swift give me a error say :Binary operator '==' cannot be applied to operands of type 'JSON' and 'String'
func cerca (nomeApt: String){
var i = 0
for item in 0...json.count {
i = i+1
if json[i]["airportName"] == nomeApt { // error I don't know
print ("I found it")
}
}
}
Honestly, I don't know why? any idea how to solve the issue? thanks a lot
You can try to use decodable,
And that will give you a simple array where you can loop and access the properties.
import Foundation
let json = """
[
{
"airportName" : "Simon Mwansa Kapwepwe Intl",
"longitude" : 28.664999999999999,
"geometry" : {
"type" : "Point",
"coordinates" : [
28.664999999999999,
-12.994999999999999
]
},
"countryCode" : "ZMB",
"countryName" : "Zambia",
"latitude" : -12.994999999999999,
"cityName" : "Ndola",
"airportCode" : "FLSK"
},
{
"airportName" : "Mafikeng",
"longitude" : 25.544469444444445,
"geometry" : {
"type" : "Point",
"coordinates" : [
25.544469444444445,
-25.807447222222223
]
},
"countryCode" : "ZAF",
"countryName" : "South African Rep",
"latitude" : -25.807447222222223,
"cityName" : "Mafikeng",
"airportCode" : "FAMM"
}
]
""".data(using: .utf8)!
struct Geometry: Decodable {
var type: String
var coordinates: [Double]
}
struct Airports: Decodable {
var airportName : String
var longitude : Double
var geometry: Geometry
var countryCode : String
var countryName: String
var latitude: Double
var cityName: String
var airportCode :String
}
func findSpecifAirport(airportName: String) -> Bool {
if let myStruct = try? JSONDecoder().decode([JsonDecoder].self, from: json) {
let foundSpecific = myStruct.filter { $0.airportName == airportName }
return !foundSpecific.isEmpty;
}
return false
}
you could use it like this
let hasFoundIt = findSpecifAirport(airportName: "Simon Mwansa Kapwepwe Intl")
Convert json to string, change the line to:
if json[i]["airportName"] as? String == nomeApt {

Swift Fatal error: Array index is out of range when inserting an element

I'm trying to sort this array of dictionaries by age.
When I try to iterate through the array of friends (last for in loop) and insert at a specific index, I get a fatal error:
Array index is out of range when inserting an element.
let friends = [
[
"name" : "Alex",
"age" : 23
],
[
"name" : "Massi",
"age" : 38
],
[
"name" : "Sara",
"age" : 16
],
[
"name" : "Leo",
"age" : 8
]
]
var friendsSortedByAge: [[String : Any]] = [[:]]
var tempArrayOfAges: [Int] = []
for friend in friends {
if let age = friend["age"] as? Int {
tempArrayOfAges.append(age)
}
}
tempArrayOfAges.sort()
for friend in friends {
for n in 0..<tempArrayOfAges.count {
if let age = friend["age"] as? Int {
if age == tempArrayOfAges[n] {
friendsSortedByAge.insert(friend, at: n)
}
}
}
}
print(tempArrayOfAges)
print(friendsSortedByAge)
You cannot insert objects at indices greater than the number of objects in the array. After sorting the ages array the indices aren't in sync anymore and this causes the exception.
However you can sort the array in a much easier (and error-free) way
let friends = [
[
"name" : "Alex",
"age" : 23
],
[
"name" : "Massi",
"age" : 38
],
[
"name" : "Sara",
"age" : 16
],
[
"name" : "Leo",
"age" : 8
]
]
let friendsSortedByAge = friends.sorted(by: {($0["age"] as! Int) < $1["age"] as! Int})
print(friendsSortedByAge)

Loop through Dictionary in Swift

I have a dictionary which I want to append some items.
**This is my dictionary which I want to achieve: **
let parameters: [String: Any] = [
{
"ResultsList": [{
"UserId": "b806e283-066f-4081-aafe-1fe216a57c35",
"FriendUserId": "7a2ec150-cdb3-4600-84f8-2dab970bfa0c",
"TransferDate": "2017-11-23",
"UserAnswers": [{
"AnswerId": "b7562603-614d-11e7-a7e0-484d7ee0cd26",
"LastAnsweredDate": "2017-11-23",
"QuestionId": "0b60f35e-5d80-11e7-a7e0-484d7ee0cd26"
},
{
"AnswerId": "b7562603-614d-11e7-a7e0-484d7ee0cd26",
"LastAnsweredDate": "2017-11-23",
"QuestionId": "0b60f35e-5d80-11e7-a7e0-484d7ee0cd26"
}
]
}]
}
]
And this is my current dictionary which I want to make the loop and add the items.
let parameters: [String: Any] = [
{
ResultsList: [
{
UserId: “b806e283-066f-4081-aafe-1fe216a57c35”
FriendUserId: “7a2ec150-cdb3-4600-84f8-2dab970bfa0c”
TransferDate: “2017-11-23”
UserAnswers: [
{
AnswerId: “b7562603-614d-11e7-a7e0-484d7ee0cd26"
LastAnsweredDate: “2017-11-23”
QuestionId : “0b60f35e-5d80-11e7-a7e0-484d7ee0cd26"
}
]
}
]
}
]
I have 3 arrays which I want to loop through and append to the dictionary
var AnswerId = [ “b7562603-614d-11e7-a7e0-484d7ee0cd26", “aasdaas-614d-11e7-a7e0-484d7ee0cd26", “b756asd03-614d-11e7-a7e0-484d7ee0cd26"]
var LastAnsweredDate = [“2017-11-23”, “2017-11-23”, “2017-11-22”]
var QuestionId = [“0b60f35e-5d80-11e7-a7e0-484d7ee0cd26",“asdasd-5d80-11e7-a7e0-484d7ee0cd26",“asdasd-5d80-11e7-a7e0-484d7ee0cd26"]
Can someone please help to achieve this result?

Swift 3 - Always get nil when cast values

I am currently having a bad time with type casting while fetching some data.
Here is the data I have in the debug console:
(7, ["name": Doe, "id": 2042, "website": http://somedomaine.com/, "logo": http://somedomaine.com/img/, "category_id": 33, "category": Institutional partners, "order": 7])
I am sure this is really obvious, but I can't figure out how to access to data like name or id and it is giving me headache. This is what I have done:
let section = ( index as NSIndexPath ).section + 1 as Int
let row = ( index as NSIndexPath ).row as Int
let sectionContent = posts![ section ] as? Array< Any >
let entry = ( sectionContent?[ row ] as AnyObject )
After that, the best I can get is nil!
Here is a little more details: the posts variable is initiated at the top of the class like so:
internal var posts: [ Int: AnyObject ]?
The data are parsed like this (the original data come from a json feed which is fine):
func parsePosts( posts: [ Dictionary< String, AnyObject > ] ) -> ( [ Int: AnyObject ], Int ) {
var theCategories = [ Int : AnyObject ]()
var theSponsors = [ Int : AnyObject ]()
var theDict = [ Int : Array< Any > ]()
for item in posts {
let itemID = item[ "id" ] as! Int
let sponsorMeta = item[ "sponsor_meta" ]
let category = sponsorMeta?[ "category" ] as? String
let title = item[ "title" ]
let name = title?[ "rendered" ] as? String
if !( category ?? "" ).isEmpty {
let order = Int( ( sponsorMeta?[ "order" ] as? String )! )
let categoryID = sponsorMeta?[ "category_id" ] as! Int
let categoryOrder = sponsorMeta?[ "category_order" ] as! Int
let website = sponsorMeta?[ "url" ] as? String
let logo = sponsorMeta?[ "logo" ] as? [ String: Any ]
let logoSizes = logo?[ "sizes" ] as? [ String: Any ]
let imgUrl = logoSizes?[ "medium_large" ] as? String
let sponsor = [ "id": itemID, "name": ( name )! as String, "logo": imgUrl! as String, "website": ( website )! as String, "category": category!, "order": order!, "category_id": categoryID ] as [ String : Any ]
let category = [ "name": category!, "order": categoryOrder ] as [ String : Any ]
theCategories[ categoryID ] = category as AnyObject
theSponsors[ itemID ] = sponsor as AnyObject
}
}
for ( k, value ) in theCategories {
let categoryOrder = value[ "order" ] as! Int
var catDict = [ Int : [ String: AnyObject ] ]()
for ( _, element ) in theSponsors {
let sponsorCategoryID = element[ "category_id" ] as! Int
if sponsorCategoryID == k {
let sponsorOrder = element[ "order" ] as! Int
catDict[ sponsorOrder ] = element as? [ String : AnyObject ]
}
}
let sortedCat = catDict.sorted( by: { $0.0 < $1.0 } )
theDict[ categoryOrder ] = sortedCat
}
let sortedDict = theDict.sorted( by: { $0.0 < $1.0 } )
var finalDict = [ Int: AnyObject ]()
for ( t, v ) in sortedDict {
finalDict[ t ] = v as AnyObject?
}
return ( finalDict, theCategories.count )
}
I am sure it is just a small thing but I have been playing for hours with casting types and I haven't found a solution.
Does anybody have a suggestion? It will be much appreciated. Thanks!
I see that you have created a tuple and in order to access that data from that tuple I would suggest this approach
let posts = (7, dataDictioanry: ["name": "Doe", "id": 2042, "website": "http://somedomaine.com/", "logo": "http://somedomaine.com/img/", "category_id": 33, "category": "Institutional partners", "order": 7])
posts.dataDictioanry["name"]

Define datatype for Multidimensional Array

How do i declare the datatype for the below multidimensional array
settings = [
“person" : [
“name”:"bing",
"status”:"done",
],
“flags" : [
“moved" :true
]
]
tried with var settings = [String](), var settings = [String[String:String] but did not work
After correcting all the small mistakes (you're using “ instead of ")
let settings = ["person": ["name": "bing", "status": "done"], "flags": ["moved": true]]
Alt clicking settings is showing:
let settings: [String : Dictionary<String, NSObject>]
But you could also declare it as [String: [String: AnyObject]]

Resources