So far I only had to deal with simple JSON arrays with only a single array. I have now combined 2 arrays together so I can get my user data and all the reviews for that user:
[
{
"user_id": "16",
"name": "Jonh",
"lastName": "appleseed",
"username": "jonh#me.com",
"sex": "male",
"image_url": "",
"review": [
{
"reviewID": "4",
"merchant_id": "17",
"rating": "5",
"user_id": "16",
"comments": "Very good customer. Strongly suggested",
"date": "0000-00-00",
"reviewYear": "",
"publish": "1"
},
{
"reviewID": "8",
"merchant_id": "16",
"rating": "2",
"user_id": "16",
"comments": "Automatic review due to "NO SHOW" without informing the merchant",
"date": "0000-00-00",
"reviewYear": "",
"publish": "1"
}
]
}
]
before I added the reviews my model looked like this:
import Foundation
class Users {
let userImage:String?
let name:String?
let sex:String?
let image_url:String?
init(dictionary:NSDictionary) {
userImage = dictionary["userImage"] as? String
name = dictionary["name"] as? String
sex = dictionary["sex"] as? String
image_url = dictionary["image_url"] as? String
}
}
func loadUser(completion:(([Users])-> Void), userId: String){
let myUrl = NSURL(string: "http://www.myWebSite.com/api/v1.0/users.php")
let request = NSMutableURLRequest(URL: myUrl!)
request.HTTPMethod = "POST"
let postString = "user_id=\(userId)"
request.HTTPBody = postString.dataUsingEncoding(NSUTF8StringEncoding, allowLossyConversion: true)
let task = NSURLSession.sharedSession().dataTaskWithRequest(request)
{ data, response, error in
if error != nil {
print("error\(error)")
} else {
do {
let json = try NSJSONSerialization.JSONObjectWithData(data!, options: .MutableContainers) as! NSArray
print(json)
var users = [Users]()
for user in json{
let user = Users(dictionary: user as! NSDictionary)
users.append(user)
let priority = DISPATCH_QUEUE_PRIORITY_DEFAULT
dispatch_async(dispatch_get_global_queue(priority, 0 )){
dispatch_async(dispatch_get_main_queue()){
completion(users)
}
}
}
} catch{
}
}
}
task.resume()
}
which I could then used in my viewController:
func loadModel() {
let loadingNotification = MBProgressHUD.showHUDAddedTo(self.view, animated: true)
loadingNotification.mode = MBProgressHUDMode.Indeterminate
loadingNotification.labelText = "updating your deals..."
users = [Users]()
let api = Api()
api.loadUser(didLoadUsers , userId: "16")
}
func didLoadUsers(users:[Users]){
self.users = users
self.tableView.reloadData()
MBProgressHUD.hideAllHUDsForView(self.view, animated: true)
}
Can I get the review field so I can present it in a table view controller?
I added to your Users class an array of reviews that will be populated in your user init() method. I recommend you to take look at struct Review and make your user class a struct, and change your NSDictionary to swift Dictionary.
struct Review {
let reviewID:String?
let merchant_id:String?
let user_id:String?
//to be continued with your own implementation...
init(dictionary:[String:String]) {
reviewID = dictionary["reviewID"]
merchant_id = dictionary["merchant_id"]
user_id = dictionary["user_id"]
//to be continued with your own implementation...
}
}
class Users {
let userImage:String?
let name:String?
let sex:String?
let image_url:String?
var reviews:[Review]
init(dictionary:[String:AnyObject]) {
userImage = dictionary["userImage"] as? String
name = dictionary["name"] as? String
sex = dictionary["sex"] as? String
image_url = dictionary["image_url"] as? String
reviews = [Review]()
if let userReviews = dictionary["review"] as? [[String:AnyObject]] {
for review in userReviews {
if let unwrapedReview = review as? [String:String] {
let r = Review(dictionary: unwrapedReview)
reviews.append(r)
}
}
}
}
}
Also I recommend you in the future to use SwiftyJSON for parsing JSON and also Alamofire for networking requests.
Done. It was easier than what I thought. I just had to add a UserReview class and change the signature of loadUser function:
func loadUser(completion:((user: [Users], review: [UserReview])-> Void), userId: String){
let myUrl = NSURL(string: "http://www.myWebsite.com/api/v1.0/users.php")
let request = NSMutableURLRequest(URL: myUrl!)
request.HTTPMethod = "POST"
let postString = "user_id=\(userId)"
request.HTTPBody = postString.dataUsingEncoding(NSUTF8StringEncoding, allowLossyConversion: true)
let task = NSURLSession.sharedSession().dataTaskWithRequest(request)
{ data, response, error in
if error != nil {
print("error\(error)")
}else{
do{
let json = try NSJSONSerialization.JSONObjectWithData(data!, options: .MutableContainers) as! NSArray
var users = [Users]()
for user in json{
let user = Users(dictionary: user as! NSDictionary as! [String : AnyObject])
users.append(user)
//*********** now I can access the reviews from my son***************
let reviewArray = json[0]["review"] as! NSArray
var reviews = [UserReview]()
for review in reviewArray{
let review = UserReview(dictionary: review as! NSDictionary as! [String : AnyObject])
reviews.append(review)
}
let priority = DISPATCH_QUEUE_PRIORITY_DEFAULT
dispatch_async(dispatch_get_global_queue(priority, 0 )){
dispatch_async(dispatch_get_main_queue()){
completion(user: users, review: reviews)
}
}
}
} catch{
}
}
}
task.resume()
}
So I can use it in my tableViewController
var users: [Users]?
var reviews: [UserReview]?
func loadModel() {
let loadingNotification = MBProgressHUD.showHUDAddedTo(self.view, animated: true)
loadingNotification.mode = MBProgressHUDMode.Indeterminate
loadingNotification.labelText = "updating..."
users = [Users]()
reviews = [UserReview]()
let api = Api()
api.loadUser(didLoadUsers , userId: "16")
}
func didLoadUsers(users:[Users], reviews:[UserReview] ){
self.users = users
self.reviews = reviews
self.tableView.reloadData()
MBProgressHUD.hideAllHUDsForView(self.view, animated: true)
}
override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
if section == 0 {
return users!.count
}
if section == 1 {
return 1
}
if section == 2 {
return reviews!.count
}
return 0
}
So in my cellForRowAtIndexPath I can now load all the reviews
if indexPath.section == 2 {
let review = reviews![indexPath.row]
let reviewCell = tableView.dequeueReusableCellWithIdentifier("reviewCell", forIndexPath: indexPath) as! UserReviewsTableViewCell
reviewCell.useReview(review)
return reviewCell
}
Related
I have a following sample json file I want to do it with modal classes but am not sure how to do this in code.
{
"countryCodes": [{
"country_code": "AF",
"country_name": "Afghanistan",
"dialling_code": "+93"
},
{
"country_code": "AL",
"country_name": "Albania",
"dialling_code": "+355"
},
{
"country_code": "DZ",
"country_name": "Algeria",
"dialling_code": "+213"
},
{
"country_code": "AS",
"country_name": "American Samoa",
"dialling_code": "+1"
}
]
}
My modal class is as follows
import Foundation
class CountryModal : NSObject, NSCoding{
var countryCodes : [CountryCode]!
/**
* Instantiate the instance using the passed dictionary values to set the properties values
*/
init(fromDictionary dictionary: [String:Any]){
countryCodes = [CountryCode]()
if let countryCodesArray = dictionary["countryCodes"] as? [[String:Any]]{
for dic in countryCodesArray{
let value = CountryCode(fromDictionary: dic)
countryCodes.append(value)
}
}
}
/**
* Returns all the available property values in the form of [String:Any] object where the key is the approperiate json key and the value is the value of the corresponding property
*/
func toDictionary() -> [String:Any]
{
var dictionary = [String:Any]()
if countryCodes != nil{
var dictionaryElements = [[String:Any]]()
for countryCodesElement in countryCodes {
dictionaryElements.append(countryCodesElement.toDictionary())
}
dictionary["countryCodes"] = dictionaryElements
}
return dictionary
}
/**
* NSCoding required initializer.
* Fills the data from the passed decoder
*/
#objc required init(coder aDecoder: NSCoder)
{
countryCodes = aDecoder.decodeObject(forKey: "countryCodes") as? [CountryCode]
}
/**
* NSCoding required method.
* Encodes mode properties into the decoder
*/
#objc func encode(with aCoder: NSCoder)
{
if countryCodes != nil{
aCoder.encode(countryCodes, forKey: "countryCodes")
}
}
}
and
import Foundation
class CountryCode : NSObject, NSCoding{
var countryCode : String!
var countryName : String!
var diallingCode : String!
/**
* Instantiate the instance using the passed dictionary values to set the properties values
*/
init(fromDictionary dictionary: [String:Any]){
countryCode = dictionary["country_code"] as? String
countryName = dictionary["country_name"] as? String
diallingCode = dictionary["dialling_code"] as? String
}
/**
* Returns all the available property values in the form of [String:Any] object where the key is the approperiate json key and the value is the value of the corresponding property
*/
func toDictionary() -> [String:Any]
{
var dictionary = [String:Any]()
if countryCode != nil{
dictionary["country_code"] = countryCode
}
if countryName != nil{
dictionary["country_name"] = countryName
}
if diallingCode != nil{
dictionary["dialling_code"] = diallingCode
}
return dictionary
}
/**
* NSCoding required initializer.
* Fills the data from the passed decoder
*/
#objc required init(coder aDecoder: NSCoder)
{
countryCode = aDecoder.decodeObject(forKey: "country_code") as? String
countryName = aDecoder.decodeObject(forKey: "country_name") as? String
diallingCode = aDecoder.decodeObject(forKey: "dialling_code") as? String
}
/**
* NSCoding required method.
* Encodes mode properties into the decoder
*/
#objc func encode(with aCoder: NSCoder)
{
if countryCode != nil{
aCoder.encode(countryCode, forKey: "country_code")
}
if countryName != nil{
aCoder.encode(countryName, forKey: "country_name")
}
if diallingCode != nil{
aCoder.encode(diallingCode, forKey: "dialling_code")
}
}
}
How do I use these models to get the value of to say India +91 code? I am new to swift so I am clueless as to how to use these models.
the method I know is simple method of ditionary
fileprivate func loadNames(Country: String ) {
// //var countryCodes : [CountryCode]!
// var dict = [Coordinator]?.self
if let filePath = Bundle.main.path(forResource: "CountryCode", ofType: "json") {
if let jsonData = NSData(contentsOfFile: filePath) {
do {
// countryCodes = try? JSONDecoder().decode(CountryCode.self, from: jsonData as Data)
var countryCodes = try JSONSerialization.jsonObject(with: jsonData as Data, options: []) as? [String: Any]
// let countryCodes = try? JSONDecoder().decode(Welcome.self, from: jsonData as Data)
print ("country d ",countryCodes!)
let countryArray = countryCodes!["countryCodes"] as? NSArray
if countryArray!.count > 0
{
for countryElement in countryArray!
{
let dict = countryElement as! NSDictionary
if (dict["country_code"] as! String).description == countryCodeLocale
{
print("found ",(dict["dialling_code"] as! String ).description)
country_codeText.text = (dict["dialling_code"] as! String ).description
phone_NumberText.text = "99133131602"
return
}
}
}
} catch {
print(error.localizedDescription)
}
}
}
}
func fetchValues()
{
let appDelegate = UIApplication.shared.delegate as! AppDelegate
let context = appDelegate.persistentContainer.viewContext
let request = NSFetchRequest<NSFetchRequestResult>(entityName: "Testing")
request.returnsObjectsAsFaults = false
do
{
let result = try context.fetch(request)
for data in result as! [NSManagedObject]
{
self.nameArr.append(data.value(forKey: "name") as! String)
self.lastNameArr.append(data.value(forKey: "lastname") as! String)
}
self.tableView.reloadData()
} catch {
print("Failed")
}
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int
{
return self.nameArr.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell
{
let cell = tableView.dequeueReusableCell(withIdentifier: "cell") as? testTVCell
cell?.nameLbl.text = self.nameArr[indexPath.row]
cell?.lastNameLbl.text = self.lastNameArr[indexPath.row]
cell?.deleteBtn.tag = indexPath.row
return cell!
}
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat
{
return UITableView.automaticDimension
}
func tableView(_ tableView: UITableView, canEditRowAt indexPath: IndexPath) -> Bool {
return true
}
#IBAction func deleteAction(_ sender: UIButton) {
// self.nameArr.remove(at: sender.tag)
// self.lastNameArr.remove(at: sender.tag)
// self.tableView.reloadData()
let appDelegate = UIApplication.shared.delegate as! AppDelegate
let context = appDelegate.persistentContainer.viewContext
let fetchRequest = NSFetchRequest<NSFetchRequestResult>(entityName: "Testing")
fetchRequest.returnsObjectsAsFaults = false
let index = sender.tag
do
{
if let result = try? context.fetch(fetchRequest)
{
for object in result as! [NSManagedObject]
{
print(object.value(forKey: "name") as! String)
if ((object).value(forKey: "name") as! String).description == nameArr[index]
{
print(object.value(forKey: "name") as! String)
context.delete(object )
self.lastNameArr.remove(at: index)
self.nameArr.remove(at: index)
DispatchQueue.main.async
{
self.tableView.reloadData()
}
break
}
}
}
}
catch
{
print("error")
}
let _ : NSError! = nil
do {
try context.save()
self.tableView.reloadData()
} catch {
print("error : \(error)")
}
}
func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCell.EditingStyle, forRowAt indexPath: IndexPath) {
if editingStyle == .delete {
print("Deleted")
let appDelegate = UIApplication.shared.delegate as! AppDelegate
let context = appDelegate.persistentContainer.viewContext
let fetchRequest = NSFetchRequest<NSFetchRequestResult>(entityName: "Testing")
fetchRequest.returnsObjectsAsFaults = false
let index = indexPath.row
do
{
if let result = try? context.fetch(fetchRequest)
{
for object in result as! [NSManagedObject]
{
print(object.value(forKey: "name") as! String)
if ((object).value(forKey: "name") as! String).description == nameArr[index]
{
print(object.value(forKey: "name") as! String)
context.delete(object )
DispatchQueue.main.async
{
}
}
}
}
}
catch
{
print("error")
}
let _ : NSError! = nil
do {
try context.save()
} catch {
print("error : \(error)")
}
self.lastNameArr.remove(at: index)
self.nameArr.remove(at: index)
self.tableView.deleteRows(at: [indexPath], with: .automatic)
}
#IBAction func submitTapped(_ sender: Any)
{
let appDelegate = UIApplication.shared.delegate as! AppDelegate
let context = appDelegate.persistentContainer.viewContext
let entity = NSEntityDescription.entity(forEntityName: "Testing", in: context)
let newUser = NSManagedObject(entity: entity!, insertInto: context)
newUser.setValue(self.nameTxt.text, forKey: "name")
newUser.setValue(self.lastNameTxt.text, forKey: "lastname")
do
{
try context.save()
}
catch
{
print("Failed saving")
}
}
func apiCall()
{
let urlString = "https://example.org"
let url = NSURL(string: urlString)
let request = NSMutableURLRequest(url: url! as URL)
activityView.startAnimating()
self.view.addSubview(activityView)
request.httpMethod = "GET"
let task = URLSession.shared.dataTask(with: request as URLRequest) { data,response,error in
if error != nil
{
DispatchQueue.main.async
{
let alert = UIAlertController(title: "Network Connection Lost", message: "Please try again", preferredStyle: .alert)
let ok = UIAlertAction(title: "OK", style: .cancel, handler: { Void in
self.activityView.stopAnimating()
})
alert.addAction(ok)
self.present(alert, animated: true, completion: nil)
}
return
}
do
{
let result = try JSONSerialization.jsonObject(with: data!, options: .allowFragments) as AnyObject
print(" JSON : ", result)
let a = result as! NSArray
let b = a[0] as! NSDictionary
print("name ", (b["Name"] as! String).description)
var nameArray = [String]()
for element in a
{
nameArray.append(((element as! NSDictionary)["Name"] as! String).description)
}
print("nameArray ", nameArray)
DispatchQueue.main.async
{
self.activityView.stopAnimating()
self.activityView.isHidden = true
}
}
catch
{
print("Error -> \(error)")
DispatchQueue.main.async
{
self.activityView.stopAnimating()
let alert = UIAlertController(title: "Alert?", message: error as? String,preferredStyle: .alert)
let ok = UIAlertAction(title: "OK", style: .cancel, handler: nil)
alert.addAction(ok)
self.present(alert, animated: true, completion: nil)
return
}
}
}
task.resume()
}
}
let indexpath = NSIndexPath(row: sender.tag, section: 0)
let cell = tableView.cellForRow(at: indexpath as IndexPath) as? testTVCell
if (self.tableView.isEditing) {
cell?.deleteBtn.setTitle("Edit", for: .normal)
self.tableView.setEditing(false, animated: true)
} else {
cell?.deleteBtn.setTitle("Done", for: .normal)
self.tableView.setEditing(true, animated: true)
}
{
let appDelegate = UIApplication.shared.delegate as! AppDelegate
let urlString = appDelegate.serverUrl + "queryClassifiedList"
let url = NSURL(string: urlString)
let request = NSMutableURLRequest(url: url! as URL)
let spinner = JHSpinnerView.showDeterminiteSpinnerOnView(self.view)
spinner.progress = 0.0
self.view.addSubview(spinner)
request.httpMethod = "POST"
request.setValue("application/json; charset=utf-8", forHTTPHeaderField: "Content-Type")
request.setValue("application/json; charset=utf-8", forHTTPHeaderField: "Accept")
var dict : [AnyHashable: Any] = [
"channel" : appDelegate.channel,
"device" : appDelegate.deviceId,
"classifiedtype" : self.classifiedType,
"startnum" : startNum,
"endnum" : endNum
]
if UserDefaults.standard.value(forKey: "categoryClassifiedFilter") as? Int != nil && UserDefaults.standard.value(forKey: "categoryClassifiedFilter") as? Int != -1
{
let categoryRow = (UserDefaults.standard.value(forKey: "categoryClassifiedFilter") as? Int)!
dict["categoryid"] = categoryRow
}
if UserDefaults.standard.value(forKey: "cityRowFilter") as? Int != nil && UserDefaults.standard.value(forKey: "cityRowFilter") as? Int != -1
{
let cityId = (UserDefaults.standard.value(forKey: "cityRowFilter") as? Int)!
dict["city"] = cityId
}
let jsonData: Data? = try? JSONSerialization.data(withJSONObject: dict, options: [])
request.httpBody = jsonData
let appDelegate = UIApplication.shared.delegate as! AppDelegate
let urlString = appDelegate.serverUrl + "queryClassifiedList"
let url = NSURL(string: urlString)
let request = NSMutableURLRequest(url: url! as URL)
let spinner = JHSpinnerView.showDeterminiteSpinnerOnView(self.view)
spinner.progress = 0.0
self.view.addSubview(spinner)
request.httpMethod = "POST"
var bodyData : String!
bodyData = "channel=" + appDelegate.channel + "&device=" + appDelegate.deviceId + "&Classifiedtype=" + self.classifiedType.description + "&Startnum=" + startNum.description + "&Endnum=" + endNum.description
if UserDefaults.standard.value(forKey: "categoryClassifiedFilter") as? Int != nil && UserDefaults.standard.value(forKey: "categoryClassifiedFilter") as? Int != -1
{
let categoryRow = (UserDefaults.standard.value(forKey: "categoryClassifiedFilter") as? Int)!
bodyData = bodyData + "&Categoryid=" + categoryRow.description
}
if UserDefaults.standard.value(forKey: "cityRowFilter") as? Int != nil && UserDefaults.standard.value(forKey: "cityRowFilter") as? Int != -1
{
let cityId = (UserDefaults.standard.value(forKey: "cityRowFilter") as? Int)!
bodyData = bodyData + "&city=" + cityId.description
}
print("bodyData : ", bodyData)
request.httpBody = bodyData.data(using: String.Encoding.utf8)
}
but I want modal class method implementation. Can someone help?
You can try
struct Root: Codable {
let countryCodes: [CountryCode]
}
struct CountryCode: Codable {
let countryCode, countryName, diallingCode: String
enum CodingKeys: String, CodingKey {
case countryCode = "country_code"
case countryName = "country_name"
case diallingCode = "dialling_code"
}
}
let res = try? JSONDecoder().decode(Root.self,from:jsonData)
print(res.countryCodes)
res.countryCodes.forEach {
if $0.countryCode == "DZ" {
print($0.diallingCode)
}
}
I have two data's
1. From json
2. From json.file
Tha data format is below:-
{
"data": [
{
"question": "Gender",
"options": [
"Male",
"Female"
],
"button_type": "2"
},
{
"question": "How old are you",
"options": [
"Under 18",
"Age 18 to 24",
"Age 25 to 40",
"Age 41 to 60",
"Above 60"
],
"button_type": "2"
},
{
"button_type": "2",
"question": "I am filling the Questionnaire for?",
"options": [
"Myself",
"Mychild",
"Partner",
"Others"
]
}
]
}
This is my model:-
enum NHAnswerType:Int
{
case NHAnswerCheckboxButton = 1
case NHAnswerRadioButton
case NHAnswerSmileyButton
case NHAnswerStarRatingButton
case NHAnswerTextButton
}
class NH_QuestionListModel: NSObject {
var dataListArray33:[NH_OptionsModel] = []
var id:Int!
var question:String!
var buttontype:String!
var options:[String]?
var v:String?
var answerType:NHAnswerType?
var optionsModelArray:[NH_OptionsModel] = []
init(dictionary :JSONDictionary) {
guard let question = dictionary["question"] as? String,
let typebutton = dictionary["button_type"] as? String,
let id = dictionary["id"] as? Int
else {
return
}
// (myString as NSString).integerValue
self.answerType = NHAnswerType(rawValue: Int(typebutton)!)
if let options = dictionary["options"] as? [String]{
print(options)
for values in options{
print(values)
let optionmodel = NH_OptionsModel(values: values)
self.optionsModelArray.append(optionmodel)
}
}
self.buttontype = typebutton
self.question = question
self.id = id
}
}
optionmodel:-
class NH_OptionsModel: NSObject {
var isSelected:Bool? = false
var textIndexPath :IndexPath?
var dummyisSelected:Bool? = false
var v:String?
var values:String?
init(values:String) {
self.values = values
print( self.values)
}
}
Viewmodel in questionviewmodel:-
func loadData(completion :#escaping (_ isSucess:Bool) -> ()){
loadFromWebserviceData { (newDataSourceModel) in
if(newDataSourceModel != nil)
{
self.datasourceModel = newDataSourceModel!
completion(true)
}
else{
completion(false)
}
}
}
func loadFromWebserviceData(completion :#escaping (NH_QuestionDataSourceModel?) -> ()){
//with using Alamofire ..............
// http://localhost/json_data/vendorlist.php
Alamofire.request("http://www.example.com").validate(statusCode: 200..<300).validate(contentType: ["application/json"]).responseJSON{ response in
let status = response.response?.statusCode
print("STATUS \(status)")
print(response)
switch response.result{
case .success(let data):
print("success",data)
let result = response.result
print(result)
if let wholedata = result.value as? [String:Any]{
print(wholedata)
// let data2 = wholedata["data"] as? [String:Any]
self.datasection1 = wholedata
if let data1 = wholedata["data"] as? Array<[String:Any]>{
print(data)
print(response)
for question in data1 {
let typebutton = question["button_type"] as? String
print(typebutton)
self.type = typebutton
let options = question["options"] as! [String]
// self.dataListArray1 = [options]
self.tableArray.append(options)
// self.savedataforoptions(completion: <#T##(NH_OptionslistDataSourceModel?) -> ()#>)
self.no = options.count
}
print(self.tableArray)
let newDataSource:NH_QuestionDataSourceModel = NH_QuestionDataSourceModel(array: data1)
completion(newDataSource)
}
}
case .failure(let encodingError ):
print(encodingError)
// if response.response?.statusCode == 404{
print(encodingError.localizedDescription)
completion(nil)
}
}}
dummy data viewmodel:-
func loadFromDummyData(completion :#escaping (NH_DummyDataSourceModel?) -> ()){
if let path = Bundle.main.path(forResource: "jsonData", ofType: "json") {
do {
let jsonData = try NSData(contentsOfFile: path, options: NSData.ReadingOptions.mappedIfSafe)
do {
let jsonResult: NSDictionary = try JSONSerialization.jsonObject(with: jsonData as Data, options: JSONSerialization.ReadingOptions.mutableContainers) as! NSDictionary
// self.datasection2 = jsonResult as! [String : Any]
let people1 = jsonResult["data"] as? [String:Any]
self.datasection2 = jsonResult as! [String : Any]
if let people = jsonResult["data"] as? Array<[String:Any]> {
// self.dict = people
for person in people {
let options = person["options"] as! [String]
self.tableArray.append(options)
let name = person ["question"] as! String
self.tableArray.append(options)
}
let newDataSource:NH_DummyDataSourceModel = NH_DummyDataSourceModel(array: people)
completion(newDataSource)
}
} catch {}
} catch {}
}
}
func loadData1(completion :#escaping (_ isSucess:Bool) -> ()){
loadFromDummyData{ (newDataSourceModel) in
if(newDataSourceModel != nil)
{
self.datasourceModel = newDataSourceModel!
completion(true)
}
else{
completion(false)
}
}
}
finally in the viewcontroller:-
in viewDidLoad:-
questionViewModel.loadData { (isSuccess) in
if(isSuccess == true)
{
let sec = self.questionViewModel.numberOfSections()
for _ in 0..<sec
{
self.questionViewModel.answers1.add("")
self.questionViewModel.questions1.add("")
self.questionViewModel.questionlist1.add("")
}
self.item1 = [self.questionViewModel.datasection1]
self.activityindicator.stopAnimating()
self.activityindicator.isHidden = true
self.tableview.refreshControl = refreshControl
self.tableview .allowsMultipleSelection = false
self.tableview.reloadData()
self.dummyDataViewModel.loadData1{ (isSuccess) in
if(isSuccess == true)
{
}
else{
self.viewDidLoad()
}
}
}
else{
self.activityindicator.stopAnimating()
self.activityindicator.isHidden = true
let controller = UIAlertController(title: "No Internet Detected", message: "This app requires an Internet connection", preferredStyle: .alert)
// Create the actions
let okAction = UIAlertAction(title: "OK", style: UIAlertActionStyle.default) {
UIAlertAction in
NSLog("OK Pressed")
self.viewDidLoad()
}
controller.addAction(okAction)
self.present(controller, animated: true, completion: nil)
}
self.sections = [Category(name:"A",items:self.item1),
Category(name:"B",items:self.item2),
]
print(self.sections)
self.tableview.reloadData()
}
This is the format from json.file and also from the api.
I have used tableview.
So i need to list the header title from the key "question"
And the cell for row should display from the option keys.
So how to add this two data from the Json and Json.file?
You can create your models which represents your model. Preferably like
struct ResponseModel: Codable {
var data: [Question]?
}
struct QuestionModel{
var question: String?
var options: [String]?
}
Then after your Ajax post use
let responseData = try JSONDecoder().decode(AjaxResponse<ResponseModel>.self, from: data!)
Now you have your data.
You can then do in your UITableViewDeleates
//number of sections
resposnseData.data.count
//number of rows in section
responseData.data[section].options.count
//cell for index modify your cell using
response.data[indexPath.section].options[indexPath.row]
Hope it helps.
I have function for loop data(title, price, drug) JSON But I can't loop imageUrl to show in imageview on this function please help see my code.
This function barcodeReaded
func barcodeReaded(barcode: String) {
print("Barcode is: \(barcode)")
showCodeLabel.text = barcode
let data = NSData(contentsOfURL: episode.thumbnailURL!)
let image = UIImage(data: data!)
self.thumbnailImageView.image = image
let episodes = Episode.downloadAllEpisodes()
var filteredEpisodes = episodes.filter({ $0.testCode == barcode })
if filteredEpisodes.count > 0 {
titleLabel.text = filteredEpisodes[0].title
drugLabel.text = filteredEpisodes[0].drug
priceLabel.text = filteredEpisodes[0].price
//thumbnailImageView.image = filteredEpisodes[0].thumnailURL
}
}
This JSON file
{
"episode": [
{
"testCode": "11111111",
"title": "Stomachic mixture 180 ml",
"drug": "AAAAA",
"thumbnailURL": "https://firebasestorage.googleapis.com/v0/b/rxscan-a14ee.appspot.com/o/j01.jpg?alt=media&token=5718797b-fc9c-416e-9394-b544c2880dc9",
"price": "100"
},
{
"testCode": "22222222",
"title": "Parasetamol 200 ml",
"drug": "BBBBB",
"thumbnailURL": "urlImage",
"price": "150"
},
{
"testCode": "33333333",
"title": "Beramol 300 ml",
"drug": "CCCCC",
"thumbnailURL": "urlImage",
"price": "120"
}
]
}
This some code
import Foundation
class Episode
{
var title: String?
var thumbnailURL: NSURL?
var drug: String?
var price: String?
var testCode: String?
init(title: String, thumbnailURL: NSURL, drug: String, price: String, testCode: String)
{
self.title = title
self.thumbnailURL = thumbnailURL
self.drug = drug
self.price = price
self.testCode = testCode
}
typealias EpisodeDictionary = [String : AnyObject]
init(espDictionary: EpisodeDictionary)
{
self.title = espDictionary["title"] as? String
self.thumbnailURL = NSURL(string: espDictionary["thumbnailURL"] as! String)
self.drug = espDictionary["drug"] as? String
self.price = espDictionary["price"] as? String
self.testCode = espDictionary["testCode"] as? String
}
static func downloadAllEpisodes() -> [Episode]
{
var episodes = [Episode]()
let jsonFile = NSBundle.mainBundle().pathForResource("testJson3edit6", ofType: "json")
let jsonData = NSData(contentsOfFile: jsonFile!)
if let jsonDictionary = NetworkService.parseJSONFromData(jsonData) {
let espDictionaries = jsonDictionary["episodes"] as! [EpisodeDictionary]
for dict in espDictionaries {
let episode = Episode(espDictionary: dict)
episodes.append(episode)
}
}
return episodes
}
}
NetworkService.swift
import Foundation
class NetworkService
{
// TODO: Make this class be able to download images from a URL
lazy var configuration: NSURLSessionConfiguration = NSURLSessionConfiguration.defaultSessionConfiguration()
lazy var session: NSURLSession = NSURLSession(configuration: self.configuration)
let url: NSURL
init(url: NSURL)
{
self.url = url
}
func downloadImage(completion: (NSData -> Void))
{
let request = NSURLRequest(URL: self.url)
let dataTask = session.dataTaskWithRequest(request) { (data, response, error) in
if error == nil {
if let httpResponse = response as? NSHTTPURLResponse {
switch (httpResponse.statusCode) {
case 200:
if let data = data {
completion(data)
}
default:
print(httpResponse.statusCode)
}
}
} else {
print("Error download data: \(error?.localizedDescription)")
}
}
dataTask.resume()
}
}
extension NetworkService
{
static func parseJSONFromData(jsonData: NSData?) -> [String : AnyObject]?
{
if let data = jsonData {
do {
let jsonDictionary = try NSJSONSerialization.JSONObjectWithData(data, options: .MutableContainers) as? [String : AnyObject]
return jsonDictionary
} catch let error as NSError {
print("Error processing json data: \(error.localizedDescription)")
}
}
return nil
}
}
This code for get image that use in detailViewController Which I don't know how to apply with function barcodeReaded.
if episode.thumbnailURL != nil {
if let thumbnailURL = episode.thumbnailURL {
let networkService = NetworkService(url: thumbnailURL)
networkService.downloadImage({ (data) in
//thumbnailImageView.image = episode.thumbnailURL
let image = UIImage(data: data)
dispatch_async(dispatch_get_main_queue(), {
self.thumbnailImageView.image = image
})
})
}
}
Basically with thumbnailImageView.image = episode.thumbnailURL your are trying to assign a String to an object of type UIImage.
You should do it:
1. Get NSURL from your json string
let url = NSURL(string: episode.thumbnailURL)!
2. Get the NSData of that NSURL
let data = NSData(contentsOfURL: url)!
3. Assign the UIImage from NSData
let image = UIImage(data: data)
self.thumbnailImageView.image = image
how can I get authors from a google's book with JSON in Swift? This code works but I have a problem with authors.
This is an example of JSON:
{
"kind": "books#volume",
"id": "17BYrgEACAAJ",
"etag": "snlcLszwWRo",
"selfLink": "https://www.googleapis.com/books/v1/volumes/17BYrgEACAAJ",
"volumeInfo": {
"title": "Scomparso. Dave Brandstetter mysteries",
"authors": [
"Joseph Hansen"
],
"publisher": "Elliot",
"publishedDate": "2012-01",
func getBookInfo:
func getBookInfo(isbn: String) {
let url_book = "https://www.googleapis.com/books/v1/volumes?q=isbn:" + isbn
if let url = NSURL(string: url_book) {
NSURLSession.sharedSession().dataTaskWithURL(url, completionHandler: {data, _, error -> Void in
if let error = error {
print(error.localizedDescription)
} else {
let data = data,
jsonResult = try? NSJSONSerialization.JSONObjectWithData(data!, options: []),
arrayOfTitles = jsonResult!.valueForKeyPath("items.volumeInfo.title") as? [String],
arrayOfAuthors = jsonResult!.valueForKeyPath("items.volumeInfo.authors") as? [String],
arrayOfPublishers = jsonResult!.valueForKeyPath("items.volumeInfo.publisher") as? [String],
arrayUrlImageBook = jsonResult!.valueForKeyPath("items.volumeInfo.imageLinks.smallThumbnail") as? [String]
self.titles = arrayOfTitles!.joinWithSeparator(", ")
self.authors = arrayOfAuthors!.joinWithSeparator(", ")
self.publishers = arrayOfPublishers!.joinWithSeparator(", ")
let url_image_book: String! = arrayUrlImageBook!.joinWithSeparator(", ")
self.title_label.text = self.titles
self.author_label.text = self.authors
if self.publishers != nil{
self.publisher_label.text = self.publishers
}
self.book_image.downloadedFrom(url_image_book!)
}
}).resume()
}
}
Thanks in advance.
So in order to retrieve the authors, I do something similar but a little bit different.
First, I just create an array of all the books that are returned by the API for the URL that I send to it...
if let volumeInfo = jsonResult.valueForKeyPath("items.volumeInfo") as? [AnyObject] {
if volumeInfo.count != 0 {
self.volumeInfo = volumeInfo
self.translateJSONData() //here is where I then translate the data
}
}
Then in my data translation function, I loop through all the results, and get the values I want.
for apiResponse in self.volumeInfo {
if let singleVolumeInfo = apiResponse as? [String : AnyObject] {
let bookCategory = singleVolumeInfo["categories"] as? [String]
let bookAuthors = singleVolumeInfo["authors"] as? [String]
//more information here
}
}
But that code to get the authors will give you an array of all the author's names.
while parsing collection of dictionary array json thats look like below
{
"responsecode": "200",
"responsemsg": "Product List",
"total_pages_count": "35",
"data": [
{
"pk_productid": 412,
"fk_userid": 59,
"productname": "Cerulean",
"sku": "man-cerulean412",
"description": "",
"shortdescription": "",
"prodsaletype": 1,
"prodprice": 156000,
"is_approve": 1,
"issold": false,
"issoldprice": 0,
"isbid": 0,
"lastbidprice": 156000,
"isdiscount": false,
"isfixeddiscount": false,
"discountamt": 0,
"ispromocode": false,
"isonline": false,
"iscash": true,
"images": [
{
"imagepath": "http://www.artively.com/Upload/ProdColorThumbImage/270120161832_Cerulean_Fotor.jpg",
"imgvideotype": 1
}
],
"videos": [],
"first_name": "Manhar ",
"last_name": "Kapadiya",
"totalhour": 0,
"totalminute": 0,
"totalsecond": 0,
"is_auction_onhold": "1",
"bid_user_id": 0,
"bid_first_name": "",
"bid_last_name": "",
"bid_user_image": "Upload/ThubUserProfile/noimage.jpg",
"is_fav": 0,
"share_url": "http://www.artively.com/url/5dd129",
"share_count": 0,
"category_id": 0,
"category_name": "",
"issubmited": false
},
....
..
.
I am able to get the value of image url and other details but while showing it on UITableview it does not appear on a proper index for example
Tableview index 1 - it shows the product name and prod.price but the image url is shown in the next tableview index ie -2
Tableview index 2 - it show the image url of first index were as the product name and price are nil
Tableview index 3 - it shows the product name and prod.price but the image url is shown in the next tableview index ie -4
and continue like this...
Here is my code
func parseJSONData(data: NSData) -> [ProductDetails] {
var product_Detail = [ProductDetails]()
do {
let jsonResult = try NSJSONSerialization.JSONObjectWithData(data, options: NSJSONReadingOptions.MutableContainers) as? NSDictionary
let jsonProductDetails = jsonResult?["data"] as! [AnyObject]
print("the json response is",jsonProductDetails)
for jsonproductDetail in jsonProductDetails{
let productDetail = ProductDetails()
productDetail.productAuthor = jsonproductDetail["first_name"]as! String
productDetail.productPrice = jsonproductDetail["prodprice"]as! Int
product_Detail.append(productDetail)
let jsonResult = try NSJSONSerialization.JSONObjectWithData(data, options: NSJSONReadingOptions.MutableContainers) as? NSArray
let jsonProductImageDetails = jsonproductDetail["images"] as! [AnyObject]
print("the json response is",jsonProductImageDetails)
//Where to make a loop to get the desired result
for jsonproductImage in jsonProductImageDetails{
let product_Image = ProductDetails()
product_Image.productImages = jsonproductImage["imagepath"] as! String
product_Detail.append(product_Image)
}
}
}
catch {
print (error)
}
self.parseJSONImage(data)
return product_Detail
}
Model
class ProductDetails {
var productAuthor: String!
var productPrice: Int!
var artImages: String!
}
Displaying cell images
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cellIdentifier = "Cell"
let cell = tableView.dequeueReusableCellWithIdentifier(cellIdentifier, forIndexPath: indexPath) as! UserHomeScreenTableViewCell
// Configure the cell...
cell.artsAuthorName.text = globalArr[indexPath.row].productAuthor
cell.priceLabel.text = "\(globalArr[indexPath.row].productPrice)" //to convert string value to interger
let productDetailsObject = globalArr[indexPath.row].artImages
print("#################",productDetailsObject)
dispatch_async(dispatch_get_global_queue( DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), {
if let url = NSURL(string: self.globalArr[indexPath.row].artImages.imagepath) {
if let data = NSData(contentsOfURL: url) {
if let image = UIImage(data: data) {
dispatch_async(dispatch_get_main_queue()) { () -> Void in
cell.artImageView.image = image
}
}
}
}
})
return cell
}
Model Classes.
class ProductDetails {
var productAuthor: String!
var productPrice: Int!
var artImages: [ArtImage]!
}
class ArtImage {
var imagepath: String!
var imgvideotype: Int!
}
we will store the array of ArtImage as property of ProductDetails.
Simillarly you can create other class for videos also
So you can use it as below.
let productDetailsObject = //value of your ProductDetails object
let imagePath = productDetailsObject.artImages[0].imagepath
Rewrite the function as follow.
func parseJSONData(data: NSData) -> [ProductDetails] {
var product_Detail = [ProductDetails]()
do {
let jsonResult = try NSJSONSerialization.JSONObjectWithData(data, options: NSJSONReadingOptions.MutableContainers) as? NSDictionary
let jsonProductDetails = jsonResult?["data"] as! [AnyObject]
print("the json response is",jsonProductDetails)
for jsonproductDetail in jsonProductDetails{
let productDetail = ProductDetails()
productDetail.productAuthor = jsonproductDetail["first_name"]as! String
productDetail.productPrice = jsonproductDetail["prodprice"]as! Int
//we will fetch the images from first object, i.e. from the jsonproductDetail
let jsonProductImageDetails = jsonproductDetail["images"] as! [AnyObject]
var artImagesModelArray = [ArtImage]()
for image in jsonProductImageDetails {
let artImage = ArtImage();
artImage.imagepath = image["imagepath"] as! String
artImage.imgvideotype = image["imgvideotype"] as! Int
artImagesModelArray.append(artImage)
}
productDetail.artImages = artImagesModelArray;
product_Detail.append(productDetail)
}
}
catch {
print (error)
}
return product_Detail
}
Change your code with func parseJSONData(data: NSData) ->
[ProductDetails] {
var product_Detail = ProductDetails
do {
let jsonResult = try NSJSONSerialization.JSONObjectWithData(data, options:
NSJSONReadingOptions.MutableContainers) as? NSDictionary
let jsonProductDetails = jsonResult?["data"] as! [AnyObject]
for jsonproductDetail in jsonProductDetails {
let productDetail = ProductDetails()`
let jsonProductImageDetails = jsonProductDetails["images"] as! [AnyObject]
productDetail.productAuthor = jsonproductDetail["first_name"]as! String
product.Detail.productImages = jsonProductImageDetails["imagepath"] as! String
productDetail.productPrice = jsonproductDetail["prodprice"]as! Int
product_Detail.append(productDetail)
}
}
catch {
print (error)
}
self.parseJSONImage(data)
return product_Detail }