Display the users reviews in a tableView
You just need to research JSON parsing in Swift. This article would be a good read.
JSON is quite easy to read once you understand how it is structured. You just need to map each type properly. Swift 4 Introduced the Codable protocol which when combined with JSONDecoder give you a much better way of parsing and using this data.
struct Response: Codable {
var reviews: [Review]
}
struct Review: Codable {
var authorName: String
var authorUrl: String
var rating: Int
var text: String
enum CodingKeys: String, CodingKey {
case authorName = "author_name"
case authorUrl = "author_url"
case rating
case text
}
}
let data = """
{
"reviews" : [{
"author_name" : "Robert Ardill",
"author_url" : "https://www.google.com/maps/contrib/106422854611155436041/reviews",
"language" : "en",
"profile_photo_url" : "https://lh3.googleusercontent.com/-T47KxWuAoJU/AAAAAAAAAAI/AAAAAAAAAZo/BDmyI12BZAs/s128-c0x00000000-cc-rp-mo-ba1/photo.jpg",
"rating" : 5,
"relative_time_description" : "a month ago",
"text" : "Awesome offices. Great facilities, location and views. Staff are great hosts",
"time" : 1491144016
}]
}
""".data(using: .utf8)
guard let data = data else { throw NSError() }
let response = try? JSONDecoder().decode(Response.self, from: data)
let reviews = response?.reviews // array of reviews
let review = reviews?.first // first one from the list (if any)
print(review?.authorName)
print(review?.rating)
So using the example above, I have created a Review type and mapped the properties of this type to the types in the JSON response. Then we can use JSONDecoder to do the rest of the work for us.
OUTPUT:
Optional("Robert Ardill")
Optional(5)
UPDATE:
You need to do something like this, but you may need to change the structs structure based on the response values.
Alamofire.request(googlePlaceDetailsHost, parameters: params, encoding: URLEncoding(destination: .queryString)).responseJSON { response in
guard let data = response.data else { throw NSError() }
let response = try? JSONDecoder().decode(Response.self, from: data)
let reviews = response?.reviews // array of reviews
completion(reviews?.first)
}
How to send Json Data to Table View Array? Swift
First you have an empty function showTable
inside your viewDidLoad
- This does nothing. Presumably it is something hanging around from your various attempts. Delete that.
As you have probably worked out, your network fetch operation is going to occur asynchronously and you need to reload the table view once the data has been fetched.
You have some code in viewDidLoad
that kind of tries to do this, but it isn't related to the fetch operation. It is just dispatched asynchronously on the next run loop cycle; This is probably still before the data has been fetched.
However, even if the data has been fetched, it won't show up because you are assigning userFeedPosts
from a second instance of your API object to AA
at initialisation time. This array is empty and will remain empty since Swift arrays are value types, not reference types. When userFeedPosts
is updated, AA
will hold the original empty array.
To load the data you need to
- Start a load operation when the view loads
- Pass a completion handler to that load operation to be invoked when the load is complete
- Reload your table view with the new data
class EntertainmentViewController: UIViewController, UITableViewDelegate, UITableViewDataSource {
var data = [EntertainmentPageData]()
@IBOutlet weak var entPostTableView: UITableView!
override func viewDidLoad() {
entPostTableView.register(EntertainmentViewrTableViewCell.nib(), forCellReuseIdentifier: EntertainmentViewrTableViewCell.identifier)
entPostTableView.delegate = self
entPostTableView.dataSource = self
super.viewDidLoad()
EntertainmentAPI.getFeedPosts { result in
DispatchQueue.main.async { // Ensure UI updates on main queue
switch result {
case .error(let error):
print("There was an error: \(error)")
case .success(let data):
self.data = data
self.entPostTableView.reloadData
}
}
}
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let customCell1 = tableView.dequeueReusableCell(withIdentifier: EntertainmentViewrTableViewCell.identifier, for: indexPath) as! EntertainmentViewrTableViewCell
let post = data[indexPath.row)
customCell1.profileDisplayName.text = data[indexPath.row].postDisplayName
customCell1.configure(with: post.postDisplayName, PostImage: post.imageURLString, PostDescription: post.postDescription)
return customCell1
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return data.count
}
func numberOfSections(in tableView: UITableView) -> Int {
return 1
}
}
public class EntertainmentAPI {
static func getFeedPosts(completion: @escaping ((Result<[EntertainmentPageData],Error>) -> Void) ) {
guard let apiURL = URL(string: "https://api.quickques.com/....") else {
return
}
let task = URLSession.shared.dataTask(with: apiURL) { data, apiResponse, error in
if let error = error {
completion(.failure(error))
return
}
guard let data = data else {
/// TODO - Invoke the completion handler with a .failure case
return
}
do {
let entPostData = try JSONDecoder().decode([EntertainmentPageData].self, from: Data)
completion(.success(entPostData))
}
catch {
completion(.failure(error))
}
}.resume()
}
}
how to get number from json and show that number in dial pad when user tab call button in my custom table view cell
Have a variable in premiumUsercell
like as follows,
class premiumUsercell: UITableViewCell {
var phoneNumber = ""
}
in cellForRowAtIndexPath
add this code,
cell1.phoneNumber = arrDict[indexPath.section] .valueForKey("phone") as? String
in premiumUsercell
, CallbuttonTap
method
@IBAction func CallbuttonTap(sender: AnyObject) {
var phoneString = "tel://\(phoneNumber)"
let openURL = NSURL(string:phoneString)
if openURL == nil {
return
}
let application:UIApplication = UIApplication.sharedApplication()
if (application.canOpenURL(openURL!)) {
application.openURL(openURL!)
}
}
Swift UITableView: How to Load data from JSON
First of all, don't use multiple arrays for the data source. They are quite error-prone because you are responsible to keep the number of items in sync.
Since Swift is an object-oriented language use a custom struct as model
struct Fruit {
let name : String
let imageURL : NSURL
let description : String
}Declare an empty Swift array of
Fruit
as data source array. Basically use always Swift native collection types (rather thanNSArray
andNSDictionary
) because they contain the type information.var fruits = [Fruit]()
Create a function to parse the JSON and reload the table view. The code assumes that the JSON file is named
jsonFile.json
and is located in the application bundle. Further it uses theSwiftyJSON
library.func parseFruits() {
guard let url = NSBundle.mainBundle().URLForResource("jsonFile", withExtension: "json"), jsonData = NSData(contentsOfURL: url) else {
print("Error finding JSON File")
return
}
let jsonObject = JSON(data: jsonData)
let fruitArray = jsonObject["fruits"].arrayValue
for aFruit in fruitArray {
let name = aFruit["Name"].stringValue
let imageURL = aFruit["Picture"].stringValue
let description = aFruit["Description"].stringValue
let fruit = Fruit(name: name, imageURL: NSURL(string:imageURL)!, description:description)
fruits.append(fruit)
}
self.tableView.reloadData()
}in
viewWillAppear
call the parse functionoverride func viewWillAppear() {
super.viewWillAppear()
parseFruits()
}These are the table view data source delegate methods assuming the identifier of the cell is
Cell
and the style of the cell isRight Detail
orSubtitle
override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return fruits.count
}
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCellWithIdentifier("Cell", forIndexPath: indexPath)
let fruit = fruits[indexPath.row]
cell.textLabel!.text = fruit.name
cell.detailTextLabel?.text = fruit.description
// add code to download the image from fruit.imageURL
return cell
}
Edit:
In Swift 4 everything became much shorter and more convenient. The most significant change is to drop SwiftyJSON
and use Decodable
struct Fruit : Decodable {
let name : String
let imageURL : URL
let description : String
}
func parseFruits() {
let url = Bundle.main.url(forResource:"jsonFile", withExtension: "json")!
let jsonData = try! Data(contentsOfURL: url)
self.fruits = try! JSONDecoder().decode([Fruit].self, from: jsonData)
self.tableView.reloadData()
}
Swift how to show rating value in star rating
I have seen HCSStarRatingView, there are property given to display accurate rating. So change you code:
if let review = review{
review.appointment?.scheduled = dateValue
let formatter = DateFormatter()
formatter.dateFormat = "mm-dd-YYYY"
let formattedDate = formatter.string(from: dateValue)
dateLabel.text = formattedDate
// You need to change code like this.
rating.accurateHalfStars = true
rating.value = <YourAverageRating>
pastRating = 0.0 // I don't know about this, So can maintain it.
}
I hope this will help you.
Related Topics
Audiokit - How to Get Real Time Floatchanneldata from Microphone
What Are the First Two Columns in Scnmatrix4
Swift: Bring View from Stack View to Front
Change Ncwidgetdisplaymode Programmatically in iOS10 Widget
Swift Check If 3D Touch Is Possible
How to Auto Call an @Ibaction Function
Swiftui Tabbedview Only Shows First Tab's Content
How to Use a Generic Class Without the Type Argument in Swift
Firebase Dynamic Link Doesnt Work in Safari Swift
Swift 2 Unused Constant Warning
Programmatically Set Uipageviewcontroller Transition Style to Scroll
iOS - Uinavigationcontroller, Hide Navigationbar
Objective-C Call Swift Function
Receipt Validation on iOS In-App-Purchase Returns Multiple Transaction