How to use a struct with a library in a tableview - ios

I have created a struct with a library and have initialised that struct in another struct. Now I want to use the resulting struct in a Table View. However, the struct currently doesn't work properly. I've tried to find out why, but seem to be stuck.
It looks like the issue is that the library doesn't get translated properly to the struct. For in instance, when I do a count on an instance of the struct, using the following code:
var personalDetailsStructExtra: [PersonalDetailsStruct] = []
personalDetailsStructExtra.count
It returns 0, while it should be 5 (See code below, there are 5 entries into the dictionary):
struct PersonalDetailsStructLibrary {
let library = [
[
"title": "Country",
"icon": "country.pdf",
"questions": ["Belgium", "France", "Germany", "Netherlands", "Sweden", "UK", "USA"]
],
[
"title": "Age",
"icon": "age.pdf",
"questions": ["1", "2", "3", "4", "5", "6", "7"]
],
[
"title": "Gender",
"icon": "gender.pdf",
"questions": ["Male", "Female", "Other"]
],
[
"title": "Height",
"icon": "height.pdf",
"questions": ["1", "2", "3", "4", "5", "6", "7"]
],
[
"title": "Weight",
"icon": "weight.pdf",
"questions": ["1", "2", "3", "4", "5", "6", "7"]
],
] }
And
struct PersonalDetailsStruct {
var title: String?
var icon: UIImage?
var questions: [String] = []
init(index: Int) {
let personalDetailsStructLibrary = PersonalDetailsStructLibrary().library
let personalDetailsDictionary = personalDetailsStructLibrary[index]
title = personalDetailsDictionary["title"] as! String!
let iconNamePD = personalDetailsDictionary["icon"] as! String!
icon = UIImage(named: iconNamePD!)
questions += personalDetailsDictionary["artists"] as! [String]
} }
As you can see in the code I want use the struct to fill up a label (title), image (icon) and UITextView with UIPickerView (questions) in my table view.
Since it doesn't work, I'm looking for either:
A: Feedback on how to make this code work in a tableview
B: Whether I should use another method to populate the dynamic cells in my tableview

You have to initialize the personalDetailsStructExtra array, only then you would see the required count.
var personalDetailsStructExtra = [PersonalDetailsStruct]()
PersonalDetailsStructLibrary().library.count
let count = PersonalDetailsStructLibrary().library.count
for i in 0..<count {
personalDetailsStructExtra.append(PersonalDetailsStruct(index: i))
}
personalDetailsStructExtra.count // 5
A better option is to use the Library struct to construct and maintain all model objects.
struct PersonalDetailDataSource {
let library = [
[
"title": "Country",
"icon": "country.pdf",
"questions": ["Belgium", "France", "Germany", "Netherlands", "Sweden", "UK", "USA"]
],
[
"title": "Age",
"icon": "age.pdf",
"questions": ["1", "2", "3", "4", "5", "6", "7"]
],
[
"title": "Gender",
"icon": "gender.pdf",
"questions": ["Male", "Female", "Other"]
],
[
"title": "Height",
"icon": "height.pdf",
"questions": ["1", "2", "3", "4", "5", "6", "7"]
],
[
"title": "Weight",
"icon": "weight.pdf",
"questions": ["1", "2", "3", "4", "5", "6", "7"]
],
]
var personalDetails = [PersonalDetail]()
init() {
loadData()
}
mutating private func loadData() {
for i in 0..<library.count {
let personalDetailsDictionary = library[i]
let title = personalDetailsDictionary["title"] as! String!
let iconName = personalDetailsDictionary["icon"] as! String!
let questions = personalDetailsDictionary["questions"] as! [String]
personalDetails.append(PersonalDetail(title: title, iconName: iconName, questions: questions))
}
}
}
struct PersonalDetail {
var title: String?
var icon: UIImage?
var questions: [String] = []
init(title: String, iconName: String, questions: [String]) {
self.title = title
if let icon = UIImage(named: iconName) {
self.icon = icon
}
self.questions = questions
}
}
PersonalDetailDataSource().personalDetails.count // count: 5

Related

Return specific object in JSON array using swift

Using a struct I am getting data from JSON via a web API and I would like to print all of the data for a specific object e.g I would like to print all Product Id's from the response.
Here is my code:
struct Varients: Decodable {
let ProductId: String
let Colour: String
let name: String
}
struct varientsResponse: Decodable {
let varients: [Varients]
}
View Controller:
let url = URL(string: "http://192.168.1.113:8000/getvarient/?url=https://www.prettylittlething.com/stone-abstract-marble-print-structured-corset.html")
guard let requestUrl = url else { fatalError() }
// Create URL Request
var request = URLRequest(url: requestUrl)
// Specify HTTP Method to use
request.httpMethod = "GET"
let task = URLSession.shared.dataTask(with: request) { (data, response, error) in
// Check if Error took place
if let error = error {
print("Error took place \(error)")
return
}
// Read HTTP Response Status code
if let response = response as? HTTPURLResponse {
print("Response HTTP Status code: \(response.statusCode)")
}
// Convert HTTP Response Data to a simple String
if let data = data, let dataString = String(data: data, encoding: .utf8) {
let varientResponse = try? JSONDecoder().decode(varientsResponse.self, from: data)
print(varientResponse)
}
}
task.resume()
JSON Response Example:
"varients": [
{
"ProductId": "1703412",
"Colour": "Stone",
"Sizes": [
"4",
"6",
"8",
"10",
"12",
"14",
"16"
],
"image": "https://cdn-img.prettylittlething.com/2/7/f/4/27f4825ee181668f1e8e5797478607b505dbee1c_cmt4421_1.jpg?imwidth=1024",
"name": "Stone Abstract Marble Print Structured Corset"
},
{
"ProductId": "865801",
"Colour": "Pastel Orange",
"Sizes": [
"4",
"6",
"8",
"10",
"12",
"14",
"16"
],
"image": "https://cdn-img.prettylittlething.com/e/b/e/6/ebe60bba9afe0fc20fabbb5db34494dcd688dc4b_CMF1440_1.jpg?imwidth=1024",
"name": "Orange Tie Dye Print Structured Corset Top"
},
{
"ProductId": "867743",
"Colour": "Purple",
"Sizes": [
"4",
"6",
"8",
"10",
"12",
"14",
"16"
],
"image": "https://cdn-img.prettylittlething.com/d/a/8/3/da83149d0c6e00e094e417f3ed2d4b15927d15a9_CMF1829_1.jpg?imwidth=1024",
"name": "Purple Tie Dye Print Structured Corset Top"
},
{
"ProductId": "979950",
"Colour": "Fuchsia",
"Sizes": [
"4",
"6",
"8",
"10",
"12",
"14",
"16"
],
"image": "https://cdn-img.prettylittlething.com/a/0/e/2/a0e2d0847f64ee961388272009203461ee7028ee_cmg7868_1.jpg?imwidth=1024",
"name": "Fuschia Tie Dye Print Structured Corset Top"
},
{
"ProductId": "1083745",
"Colour": "Acid Blue Wash",
"Sizes": [
"4",
"6",
"8",
"10",
"12",
"14",
"16"
],
"image": "https://cdn-img.prettylittlething.com/b/e/7/4/be744c7f8fef860182ea730572c3f1dfb8b4820e_cmk5407_1.jpg?imwidth=1024",
"name": "Blue Tie Dye Print Structured Corset Top"
},
{
"ProductId": "1083753",
"Colour": "Light Pink",
"Sizes": [
"4",
"6",
"8",
"10",
"12",
"14",
"16"
],
"image": "https://cdn-img.prettylittlething.com/f/c/8/7/fc8700bbd28684d418f4ed49b638bda9112b1aca_cmk5405_1.jpg?imwidth=1024",
"name": "Light Pink Tie Dye Print Structured Corset Top"
},
{
"ProductId": "1450163",
"Colour": "Turquoise",
"Sizes": [
"4",
"6",
"8",
"10",
"12",
"14",
"16"
],
"image": "https://cdn-img.prettylittlething.com/6/6/6/f/666fc73c32602aa964f69d65fee2e3f77198448d_cmp4910_1.jpg?imwidth=1024",
"name": "Turquoise Marble Print Structured Corset Top"
},
{
"ProductId": "1667090",
"Colour": "Pink",
"Sizes": [
"4",
"6",
"8",
"10",
"12",
"14",
"16"
],
"image": "https://cdn-img.prettylittlething.com/f/8/a/8/f8a85d97fe670e37ec5903d435e1ac44ecad8fd7_cms8800_1.jpg?imwidth=1024",
"name": "Pink Abstract Renaissance Print Structured Corset"
},
{
"ProductId": "1698866",
"Colour": "Monochrome",
"Sizes": [
"4",
"6",
"8",
"10",
"12",
"14",
"16"
],
"image": "https://cdn-img.prettylittlething.com/f/7/a/a/f7aa8247197d6dcfc8f8bd270d7b50626e857d62_cmt3674_1.jpg?imwidth=1024",
"name": "Black Zebra Print Structured Corset Top"
},
{
"ProductId": "1703508",
"Colour": "Green",
"Sizes": [
"4",
"6",
"8",
"10",
"12",
"14",
"16"
],
"image": "https://cdn-img.prettylittlething.com/c/b/d/f/cbdf70eaa970a1ffaa3f3b54e9b7c4173ee0c560_cmt4422_1.jpg?imwidth=1024",
"name": "Green Abstract Marble Print Structured Corset"
}
]
}
I can return the varientsResponse but I obviously get the full JSON response, I can also return the varientsResponse.varients[0].productId but I would like to be able to get a full array of all productID's in the JSON
To answer your initial question and then also your follow up question in the comments.
You can access the Colour and the ID for a specific item like this:
varientResponse.variants.map { varient in
// Save to database by accessing like this:
// Colour - varient.Colour
// ID - varient.ProductID
}
Unrelated to your question, but normally Structs are named as singular. Which makes sense as each instance of your struct will be a singular Varient.

How to define structure in iOS XCode for JSON?

Being new to iOS, XCode I'm trying to create a structure to represent JSON data. However, regardless of what I try for defining "segments" (which consists of a int and an array of strings) XCode just errors out and when I try to follow suggested fixes it just generates other errors.
Anybody know how to actually define a structure for JSON that is named, e.g., not using "ANY", since all the name-value pairs and data types are known?
Example XCODE (one variation shown below, though dozens have been tried and generates errors):
struct Information: Decodable {
var entry: [Entry]
}
struct Entry: Decodable {
var section: Int
***ERROR HERE ->*** var segments: Array<var id: Int, var values: Array<String>>
}
Example JSON:
{
"entry": [
{
"section": 1,
"segments": [
{
"id": 1,
"values": ["1", "2", "3"]
},
{
"id": 2,
"values": [ "4", "5", "6" ]
}
]
},
{
"section": 2,
"segments": [
{
"id": 1,
"values": ["7", "8", "9"]
},
{
"id": 2,
"values": [ "a", "b", "c" ]
}
]
}
]
}
It's the same as on the top level: You have to create a struct for the lower level.
struct Information: Decodable {
let entry: [Entry]
}
struct Entry: Decodable {
let section: Int
let segments: [Segment]
}
struct Segment: Decodable {
let id: Int
let values: [String]
}

how to set json data in table view [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 3 years ago.
Improve this question
I want to get data from Json and put it in the table and display it from the API via Alamofire through the 'Post' process that has parameters containing the page number
I want get "results" ..
{
"responseCode": 200,
"message": null,
"status": true,
"results": [
{
"id": 971,
"title": "ST201972362",
"cdate": "07/31/2019",
"summary": "test",
"address": "",
"timer": "77876203",
"lat": "31.515934",
"lng": "34.4494066",
"source": "2",
"CreatedOn": "2019-07-31T13:38:46.927",
"done_940": null
},
{
"id": 970,
"title": "ST201972356",
"cdate": "07/30/2019",
"summary": "ov",
"address": "",
"timer": "0",
"lat": "31.5159315",
"lng": "34.4493925",
"source": "2",
"CreatedOn": "2019-07-30T15:26:00.077",
"done_940": null
},
{
"id": 964,
"title": "ST201972341",
"cdate": "07/29/2019",
"summary": "تجربة بلاغ ",
"address": "",
"timer": "0",
"lat": "21.5066086",
"lng": "39.1758587",
"source": "2",
"CreatedOn": "2019-07-29T19:06:58.817",
"done_940": null
},
{
"id": 959,
"title": "ST201972820252314",
"cdate": "07/28/2019",
"summary": "اااااا",
"address": "",
"timer": "0",
"lat": "21.5066716",
"lng": "39.1758483",
"source": "1",
"CreatedOn": "2019-07-28T11:45:02.493",
"done_940": null
},
{
"id": 957,
"title": "ST201972312",
"cdate": "07/28/2019",
"summary": "تمتمتم",
"address": "",
"timer": "0",
"lat": "31.5397884",
"lng": "34.4544891",
"source": "2",
"CreatedOn": "2019-07-28T08:56:43.577",
"done_940": null
},
{
"id": 956,
"title": "ST201972312",
"cdate": "07/28/2019",
"summary": "لا تنام",
"address": "",
"timer": "0",
"lat": "31.5397238",
"lng": "34.4540829",
"source": "2",
"CreatedOn": "2019-07-28T08:56:00.15",
"done_940": null
},
{
"id": 955,
"title": "ST201972311",
"cdate": "07/28/2019",
"summary": "تجربه جديد",
"address": "",
"timer": "0",
"lat": "31.5395001",
"lng": "34.4542211",
"source": "2",
"CreatedOn": "2019-07-28T08:52:09.81",
"done_940": null
},
{
"id": 953,
"title": "ST201972309",
"cdate": "07/28/2019",
"summary": "يلا",
"address": "",
"timer": "0",
"lat": "31.5110196",
"lng": "34.4784933",
"source": "2",
"CreatedOn": "2019-07-28T05:30:29.647",
"done_940": null
},
{
"id": 952,
"title": "ST201972309",
"cdate": "07/28/2019",
"summary": "ماك ١",
"address": "",
"timer": "0",
"lat": "31.5110291",
"lng": "34.4785841",
"source": "2",
"CreatedOn": "2019-07-28T05:29:09.943",
"done_940": null
},
{
"id": 949,
"title": "ST201972307",
"cdate": "07/28/2019",
"summary": "مرحبا",
"address": "",
"timer": "0",
"lat": "31.5443154",
"lng": "34.4585304",
"source": "2",
"CreatedOn": "2019-07-28T00:20:42.753",
"done_940": null
}
],
"done_940": "2/811"
}
You can follow some steps:
Step 1: need to create model
struct ResultObject {
var responseCode: Int?
var message: String?
var status: Bool?
var result: [Result]
public init(response: [String: Any]) {
self.responseCode = response["responseCode"] as? Int
self.message = response["message"] as? String
self.status = response["status"] as? Bool
let results = response["result"] as! [[String: Any]]
self.result = []
for item in results {
let result = Result(result: item)
self.result.append(result)
}
}
struct Result {
var id: String?
var title: String?
var cdate: String?
var summary: String?
var address: String?
var timer: String?
var lat: String?
var lng: String?
var source: String?
var CreatedOn: String?
var done_940: String?
public init(result: [String: Any]) {
self.id = result["id"] as? String
self.title = result["title"] as? String
self.cdate = result["cdate"] as? String
self.summary = result["summary"] as? String
self.address = result["address"] as? String
self.timer = result["timer"] as? String
self.lat = result["lat"] as? String
self.lng = result["lng"] as? String
self.source = result["source"] as? String
self.CreatedOn = result["CreatedOn"] as? String
self.done_940 = result["done_940"] as? String
}
}
}
Step 2: You check response from Alamofile
if you get json then
let test = ResultObject(response: responseJson)
print(test)
incase you get response is type Response you must convert into json
let responseJSON = try? JSONSerialization.jsonObject(with: response.data, options: [])
if let responseJSON = responseJSON as? [String: Any] {
let test = ResultObject(response: responseJSON)
print(test)
}
Let me know when you have some other problems.

swift 4 split array and filter

i will build a UICollectionView with sections.
The sections are based on the return value from json.category.
the json format is like:
[{"id":"1",
"name":"Apple",
"category":"Fruits"},
{"id":"2",
"name":"Pie",
"category":"Fruits"},
{"id":"3",
"name":"Tomato",
"category":"Vegetable"}]
I need a array filter hat the array is something like: (for sectionsItems and sectionNames)
CategorieNames[STRING] = ["Fruits","Vegetable"] // the section names from json.category
Fruits = [STRING] = ["Apple","Pie"]
Vegetables = [STRING] = ["Tomato"]
Categories.append[Fruits]
Categories.append[Vegetables]
Categories[[STRING]] = [[Fruits],[Vegetable]]
Try bellow code.
let arrData = [["id": "1",
"name": "Apple",
"category": "Fruit"],
["id": "2",
"name": "Pie",
"category": "Fruit"],
["id": "3",
"name": "Tomato",
"category": "Vegetable"]]
let categorieNames = Array(Set(arrData.map({$0["category"]!})))
var arrResult:[[String]] = []
for i in 0..<categorieNames.count {
let categories = arrData.filter({$0["category"] == categorieNames[i]}).map({$0["name"]!})
arrResult.append(categories)
}
print("result : \(arrResult)")
result : [["Apple", "Pie"], ["Tomato"]]
you can do it as follows:
let arrData = [["id": "1",
"name": "Apple",
"category": "Fruit"],
["id": "2",
"name": "Pie",
"category": "Fruit"],
["id": "3",
"name": "Tomato",
"category": "Vegetable"]]
var categorys = [[String]]()
var fruits = [String]()
var vegetable = [String]()
for data in arrData {
if let category = data["category"] {
if category == "Fruit"{
if let aFruit = data["name"] {
fruits.append(aFruit)
}
}
else if category == "Vegetable" {
if let aVeggeie = data["name"] {
vegetable.append(aVeggeie)
}
}
}
}
categorys.append(fruits)
categorys.append(vegetable)

how to add sub array in main array in swift

{
"firstName": "AA",
"lastName": "BB,
"shortName": "CC",
"nric": "12/AAA(N)123456",
"gender": "F",
"dob": "1.1.2000",
"password": "admin123",
"photo": {
"image": "hello",
"thumb": "world"
}
}
Is there anyway how to add photo array in main array? I've done as follow
let photoArray = [
"image": imageBase64,
"thumb": imageBase64
]
let param = [
"firstName": txtFirstName.text as! AnyObject,
"lastName": txtLastName.text as! AnyObject,
"shortName": txtShortName.text as! AnyObject,
"nric":"",
"gender": genderCode,
"dob":txtDOB.text as! AnyObject,
"photo": photoArray
]
but output is awful. Please let me how to do it.
Instead of making the param let make it var and do the following. You do need to specify the dictionary type as below
let photoArray : [String : AnyObject] = [
"pic" : "myPhoto"
]
var param : [String : AnyObject] = [
"name" : "UserName"
]
param["photo"] = photoArray
let photoArray = [[
"image": "a",
"thumb": "b"],[
"image": "a",
"thumb": "b"]
]
let param = [
"firstName": txtFirstName.text as! AnyObject,
"lastName": txtLastName.text as! AnyObject,
"shortName": txtShortName.text as! AnyObject,
"nric":"",
"gender": genderCode,
"dob":txtDOB.text as! AnyObject,
"photo": photoArray
]
Hope you want like this.
let photoArray:[String:UIImage] = [
"image": UIImage.init(named: "a.png")!,
"thumb": UIImage.init(named: "b.png")!
]
let param:[String:AnyObject] = [
"firstName": "AA",
"lastName": "BB",
"shortName": "CC",
"nric": "",
"gender": 0,
"dob": "DD",
"photo": photoArray
]
You can do it like this

Resources