reload UICollectionview using swiftyJSON & TRON - json

i am having trouble to reload my UICollectionview after i got my json data using TRON pod (it is like alamofire but in different structure i think)
and i parsed it using swiftyJSON
i am searching for the answer about three days and i dont know what i am missing
...
import UIKit
import SwiftyJSON
import TRON
class FeaturedAppViewController: UICollectionViewController ,
UICollectionViewDelegateFlowLayout {
private let cellID = "cellId"
var appCategories : [AppCategory]?
override func viewDidLoad() {
super.viewDidLoad()
fetchHomeApps()
collectionView?.backgroundColor = .white
collectionView?.register(CategoryCell.self, forCellWithReuseIdentifier: cellID)
}
class Home : JSONDecodable{
var apps : [App]
required init(json: JSON) throws {
print("now ready to parse :\n", json)
var apps = [App]()
let catJSON = json["categories"]
let array = json["categories"].array
for app in array!{
for index in 0...catJSON.count - 1 {
let name = app["apps"][index]["Name"].stringValue
let id = app["apps"][index]["Id"].intValue
let imageName = app["apps"][index]["ImageName"].stringValue
let category = app["apps"][index]["Category"].stringValue
let price = app["apps"][index]["Price"].doubleValue
let appsIdentification = App(iD: id, name: name, category: category, price: price, imageName: imageName)
apps.append(appsIdentification)
}
}
self.apps = apps
}
}
class JSONError : JSONDecodable {
required init(json: JSON) throws {
print("josn Error")
}
}
fileprivate func fetchHomeApps() {
print("123")
let request : APIRequest<AppCategory , JSONError> = tron.request("/appstore/featured")
request.perform(withSuccess: { (AppCategory) in
print("Successfully Fetched")
print(AppCategory.apps.count)
self.collectionview.reloaddata()
}) { (err) in
print("couldnt Fetch babe \n" , err)
}
}
override func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
if let count = appCategories?.count {
return count
}else{
return 0
}
}
override func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: cellID, for: indexPath) as! CategoryCell
cell.appCategory = appCategories?[indexPath.item]
return cell
}
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
return CGSize(width: view.frame.width , height: 230)
}
let tron = TRON(baseURL: "http://www.statsallday.com")
}
this is my view controller and there is a models page
import UIKit
import SwiftyJSON
import TRON
class AppCategory : NSObject , JSONDecodable {
var name : String?
var type : String?
let Url = "http://www.statsallday.com/appstore/featured"
var apps : [App]
required init(json: JSON) throws {
print("now ready to parse :\n", json)
var apps = [App]()
let catJSON = json["categories"]
let array = json["categories"].array
for app in array!{
for index in 0...catJSON.count - 1 {
let name = app["apps"][index]["Name"].stringValue
let id = app["apps"][index]["Id"].intValue
let imageName = app["apps"][index]["ImageName"].stringValue
let category = app["apps"][index]["Category"].stringValue
let price = app["apps"][index]["Price"].doubleValue
let appsIdentification = App(iD: id, name: name, category: category, price: price, imageName: imageName)
apps.append(appsIdentification)
}
}
self.apps = apps
}
}
struct App {
let iD : Int
let name : String
let category : String
let price : Double
let imageName : String
}
i think i should add something in fetchHomeApps function but i dont know what...
actually i started programming since 34 days age and sorry if i my code is silly.

You should call self.yourCollectionView.reloadData() when you fetched data from API and parse with swiftyJson. Only when appCategories have data not empty array object.

Related

different access to json data and showing to collection view swift 5

hello programmers and engineers , basically I want to access and show every title item in json file into collection View (that have a cell contains an image view and label ). I mean every title and image should arrange in collectionView , thanks for attention, here is my json data :
{"end":1,"data":[{"userId":{"Id":"608e3f16adb3d241e83b7e91","name":"maryam","userName":"maryam","email":"mmmaryam#gmail.com","phone":"0921984512"},"isoGld":false,"image":["images/product/2021-05-02T09-40-55.719Z-images.jpg"],"check":false,"date":"2021-05-02T05:49:42.854Z","_id":"608e73a7adb3d241e83b7e97","title":"ytrfds","about":"\n music moein","country":"60895361d3dc582b43f1c4d9","city":"60895370d3dc582b43f1c4da","telePhone":"562866567897654897","countryText":"gtfrd","cityText":"lklk","category":"6067fe1df420e0042cb93209","address":"\n arabic","dateOfEx":"2021-05-09T00:00:00.000Z","dateOfStart":"2021-05-26T00:00:00.000Z","offer":"20","createdAt":"2021-05-02T09:40:55.744Z","updatedAt":"2021-05-02T09:40:55.744Z","__v":0},{"userId":{"Id":"608e3f16adb3d241e83b7e91","name":"maryam","userName":"maryam","email":"mmmaryam#gmail.com","phone":"0921984512"},"isoGld":false,"image":["images/product/2021-05-02T09-47-17.699Z-download (2).jpg"],"check":false,"date":"2021-05-02T05:49:42.854Z","_id":"608e7525adb3d241e83b7e99","title":"abbass fgaderi","about":"\n abass ghaderee","country":"60895361d3dc582b43f1c4d9","city":"60895370d3dc582b43f1c4da","telePhone":"444444444444444","countryText":"gtfrd","cityText":"gfdsxz","category":"6067fe1df420e0042cb93209","address":"\n karaj","dateOfEx":"2021-05-12T00:00:00.000Z","dateOfStart":"2021-05-30T00:00:00.000Z","offer":"25","createdAt":"2021-05-02T09:47:17.740Z","updatedAt":"2021-05-02T09:47:17.740Z","__v":0}]}
and also here is my code :
lass HomeViewController: UIViewController, UICollectionViewDataSource {
#IBOutlet weak var collectionView: UICollectionView!
let collectionOffer = OfferCollectionViewCell()
var txt : String = " "
var cid : String = " "
var numberOfItem : Int = 0
var titleArray : [String] = []
var imageArray : [String] = []
var offerImage : [UIImage] = []
override func viewDidLoad() {
super.viewDidLoad()
print("\n iiiiiiiiiid is \(cid)")
//HomeViewController.shared.fetchOffer()
fetchOffer()
collectionView.dataSource = self
// print("aksha hast : \(imageArray)")
}
struct welcomeJson: Codable { // this is where i have this error
let userId : UserID
let isoGld , check : Bool
let image : [String]
let v : Int
let date, id , title,countryid,about , cityid, telePhone, countryText,cityText, category, address, dateOfExpire , dateOfStart , offer , createdAt, updatedAt : String
enum CodingKeys : String , CodingKey {
case userId
case isoGld
case image
case check
case date
case id = "_id"
case title
case countryid = "country"
case cityid = "city"
case telePhone
case countryText
case cityText
case category
case address
case dateOfExpire = "dateOfEx"
case dateOfStart
case offer
case about
case createdAt
case updatedAt
case v = "__v"
}
}
struct UserID : Codable {
let ID, name, userName , email, phone : String
enum CodingKeys : String , CodingKey {
case ID = "Id"
case name
case userName
case email
case phone
}
}
struct Data1: Codable {
var data: [welcomeJson]
enum Codingkeys : CodingKey {
case data
}
}
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return numberOfItem
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cellol = collectionView.dequeueReusableCell(withReuseIdentifier: "OfferCollectionViewCell", for: indexPath) as! OfferCollectionViewCell
// cellol.offerImageView.image = UIImage(imageLiteralResourceName: imageArray[0])
cellol.offerImageView.image = UIImage(named: imageArray[0])
cellol.titleLabel.text = titleArray[0]
return cellol
}
func fetchOffer() {
if let url = URL(string: "http://5.63.13.16:8080/api/product/search/getByquerys?page=1&limit=10&city=\(cid)") {
print("url is : \(url)")
URLSession.shared.dataTask(with: url) {data,response,error in
if let data = data {
let jsondec = JSONDecoder()
do {
let parsedJS = try jsondec.decode(Data1.self, from: data)
for element in parsedJS.data {
self.numberOfItem = element.title.count
self.titleArray.append(element.title)
// self.imageArray.append(UIImage(element.image))
print("akse ma midoni ine : \(element.image)")
self.imageArray.append(element.image[0])
print("kole aksa ine : \(self.imageArray)")
//self.imageArray.append(contentsOf: element.image[0...])
// print("deghat kon : \(self.imageArray)")
}
}
catch {
print("error is : \(error) ")
}
DispatchQueue.main.async {
self.collectionView.reloadData()
}
}
}.resume()
}
and also here is my result with this code on simulator :
Your approach cannot work.
You assign the length of a string to numberOfItems which has nothing to do with the expected number.
Always return the number of items in the data source array dynamically in numberOfItems
Never split a struct into multiple arrays for the data source.
Use one data source array so replace
var numberOfItem : Int = 0
var titleArray : [String] = []
var imageArray : [String] = []
var offerImage : [UIImage] = []
with
var userData = [welcomeJson]() // please name structs with starting uppercase letter
In fetchOffer() replace
let jsondec = JSONDecoder()
do {
let parsedJS = try jsondec.decode(Data1.self, from: data)
for element in parsedJS.data {
self.numberOfItem = element.title.count
self.titleArray.append(element.title)
// self.imageArray.append(UIImage(element.image))
print("akse ma midoni ine : \(element.image)")
self.imageArray.append(element.image[0])
print("kole aksa ine : \(self.imageArray)")
//self.imageArray.append(contentsOf: element.image[0...])
// print("deghat kon : \(self.imageArray)")
}
}
with
let jsondec = JSONDecoder()
do {
let parsedJS = try jsondec.decode(Data1.self, from: data)
self.userData = parsedJS.data
}
Replace numberOfItems with
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return userData.count
}
and replace cellForItem with
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cellol = collectionView.dequeueReusableCell(withReuseIdentifier: "OfferCollectionViewCell", for: indexPath) as! OfferCollectionViewCell
let item = userData[indexPath.item]
if let image = item.image.first {
print(item.title, image)
// cellol.offerImageView.image = UIImage(
}
cellol.titleLabel.text = item.title
return cellol
}
Important note:
The value of image is a string representing a partial URL. It cannot be converted to an UIImage. You have to download the image separately.

UITableView with Sections as Date from Json Data

I am working on table view to render some data received after JSON parsing. I want my table view to have sections based on different dates. Each record in JSON is an event and multiple events can take place on single date.
Here is my JSON data
https://get.rosterbuster.com/wp-content/uploads/dummy-response.json
I want to render my table view like this
Table View with Sections as Date
What I have done sofar:
I have parsed the data in following Structure
struct Roster : Codable {
let flightnr: String?
let date: String?
let aircraftType: String?
let tail: String?
let departure: String?
let destination: String?
let departTime: String?
let arrivalTime: String?
let dutyID: String?
let dutyCode: String?
let captain: String?
let firstOfficer: String?
let flightAttendant: String?
enum CodingKeys: String, CodingKey {
case flightnr = "Flightnr"
case date = "Date"
case aircraftType = "Aircraft Type"
case tail = "Tail"
case departure = "Departure"
case destination = "Destination"
case departTime = "Time_Depart"
case arrivalTime = "Time_Arrive"
case dutyID = "DutyID"
case dutyCode = "DutyCode"
case captain = "Captain"
case firstOfficer = "First Officer"
case flightAttendant = "Flight Attendant"
}
}
I have also setup basic table view but don't know how to group the retrieved data into different sections as per the image I have attached above.
Any help would be appreciated.
This is the approach I'd suggest:
1) get number of sections by mapping the API JSON response in a set based on the date property. Here's something you could use (maybe you don't need to cast it in Array as well and you want to check if date is not nil)
self.sections = Array(Set(self.dataModel.map({ (roster) -> String in
roster.date!
})))
2) set your rowsPerSection data model by creating an array of Roster for each section.
//first set the array of sections.count dimension and empty array for each item
self.sections.forEach({ (string) in
self.rowsPerSection.append([])
})
//then set each array
for index in 0..<self.sections.count {
self.dataModel.forEach({ (roster) in
if roster.date == self.sections[index] {
self.rowsPerSection[index].append(roster)
}
})
}
This is my dummy code, I tested it with your URL and it works:
class ViewController: UIViewController {
#IBOutlet weak var tableView: UITableView!
var dataModel = [Roster]()
var sections = [String]()
var rowsPerSection = [[Roster]]()
override func viewDidLoad() {
super.viewDidLoad()
tableView.delegate = self
tableView.dataSource = self
APICall { (rosters) in
DispatchQueue.main.async {
self.dataModel = rosters!
self.sections = Array(Set(self.dataModel.map({ (roster) -> String in
roster.date!
})))
//first set the array of sections.count dimension and empty array for each item
self.sections.forEach({ (string) in
self.rowsPerSection.append([])
})
//then set each array
for index in 0..<self.sections.count {
self.dataModel.forEach({ (roster) in
if roster.date == self.sections[index] {
self.rowsPerSection[index].append(roster)
}
})
}
self.tableView.reloadData()
}
}
}
func APICall(onSuccess: #escaping(_ response: [Roster]?) -> Void) {
let group = DispatchGroup()
group.enter()
DispatchQueue.global(qos: .default).async {
let url = URL(string: "https://get.rosterbuster.com/wp-content/uploads/dummy-response.json")!
let requestURL = URLRequest(url: url)
let session = URLSession.shared
session.dataTask(with: requestURL) { (data, response, error) in
let decoder = JSONDecoder()
let responseJson = try! decoder.decode([Roster].self, from: data!)
onSuccess(responseJson)
group.leave()
}.resume()
group.wait()
return
}
}
}
extension ViewController: UITableViewDelegate, UITableViewDataSource {
func numberOfSections(in tableView: UITableView) -> Int {
return sections.count
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
for index in 0..<sections.count {
if index == section {
return rowsPerSection[index].count
}
}
return 1
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = UITableViewCell()
cell.textLabel?.text = rowsPerSection[indexPath.section] [indexPath.row].destination
return cell
}
func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? {
return sections[section]
}
}
Here's the screenshot -> screenshot

How to work with Core Data saving JSON response,Show data when internet is offline in Swift 3?

I have already parsed JSON and showing in tableView which is working fine. Now my question is how will i save data offline and show when internet is not available offline using Core Data. I am working in Swift 3. If anyone can help me with screenshot it will be great help.
Below is my Code for fetching json and showing on tableView :
import UIKit
import SystemConfiguration
struct CellData {
var name:String
var address:String
public init(name:String,address:String){
self.name = name
self.address = address
}
}
///ViewController
class ViewController: UIViewController,UITableViewDataSource,UITableViewDelegate {
#IBOutlet weak var tableViewData: UITableView!
var arrayData = [CellData]()
override func viewDidLoad() {
super.viewDidLoad()
if Reachability.isConnectedToNetwork(){
print("Internet Connection Available!")
fetchServerData()
}else{
let alert = UIAlertController(title: "No Internet connection", message: "Please ensure you are connected to the Internet", preferredStyle: UIAlertControllerStyle.alert)
alert.addAction(UIAlertAction(title: "OK", style: UIAlertActionStyle.default, handler: nil))
self.present(alert, animated: true, completion: nil)
print("Internet Connection not Available!")
}
}
func numberOfSections(in tableView: UITableView) -> Int {
return 1
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return arrayData.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "cell") as! MyCellData
cell.lblTop.text = "😀\(arrayData[indexPath.row].name)"
cell.lblBottom.text = arrayData[indexPath.row].address
return cell
}
func fetchServerData(){
let prs = [
"author_id": "1780",
"get_deals_author": "1" as String
]
Service.StartWithoutLoading(prs as [String : AnyObject]?, onCompletion: { result in
let json = result as? NSDictionary
if let data = json as? [String:Any]{
if let err = data["status"] as? String, err == "success"{
if let data = data["result"] as? [Any]{
var arrayData = [CellData]()
for sectionObj in data{
if let sectionObjVal = sectionObj as? [String:Any]{
if let name_deal = sectionObjVal["name"] as? String{
if let address_deal = sectionObjVal["address"] as? String{
let dataValue = CellData.init(name: name_deal, address: address_deal)
arrayData.append(dataValue)
}
}
}
}
DispatchQueue.main.async { () -> Void in
self.arrayData.removeAll()
self.arrayData = arrayData
self.tableViewData.reloadData()
}
}
}
}
})
}
}
For Core Data, you need to create the entities you need in CoreData model .xcdatamodeld. Click on Add Entity and name your entity. Then add attributes which you require to save.
You can see this link on how to create the entities and attributes. After creating everything, we can write a CoreDataStack and a manager class or we can directly use the code pre-written in AppDelegate when we check on Core Data when creating a project. I'll here use the CoreDataStack class.
Here is the class
import Foundation
import CoreData
class CoreDataStack: NSObject {
static let moduleName = "YourProject"
static let shared = CoreDataStack()
private override init() {
super.init()
_ = self.persistentContainer
}
func saveContext () {
let context = persistentContainer.viewContext
if context.hasChanges {
do {
try context.save()
} catch {
let nserror = error as NSError
fatalError("Unresolved error \(nserror), \(nserror.userInfo)")
}
}
}
lazy var persistentContainer: NSPersistentContainer = {
let container = NSPersistentContainer(name: CoreDataStack.moduleName)
container.loadPersistentStores(completionHandler: { (storeDescription, error) in
if let error = error as NSError? {
fatalError("Unresolved error \(error), \(error.userInfo)")
}
print("Coordinator URL - \(storeDescription)")
})
return container
}()
}
Now we can make a manager class to insert the data. Let's say your entity is Person and its attributes are name and address
Here is the CoreDataManager class to insert, update, fetch data.
import UIKit
import CoreData
class CoreDataManager: NSObject {
class func addRecord(object:[String:Any]) {
let person = NSEntityDescription.insertNewObject(forEntityName: "Person", into: CoreDataStack.shared.persistentContainer.viewContext) as! Person
person.name = object["name"] as? String
person.address = object["address"] as? String
CoreDataStack.shared.saveContext()
}
class func getRecords() -> [Person]? {
let request:NSFetchRequest<Person> = Person.fetchRequest()
do {
let results = try CoreDataStack.shared.persistentContainer.viewContext.fetch(request)
return results
} catch {
print(error.localizedDescription)
}
return nil
}
}
You can call addRecord method in your ViewController class and it will save your data. I recommend that you pass the complete array and then add in core data and finally call saveContext().
Finally you can use getRecords to get all records.

How to place JSON data in a NScollectionview

I am grabbing data from a url which is a PHP script that is JSON encoding my data from a MySQL database. My data is coming into my app and I know how to parse it but I am unsure how to place my data inside of each item's textField.stringvalue in my Collection View. Most of the information I have found on this subject is all for iOS and I am making an app for OS X.
ViewController.swift
import Cocoa
class ViewController: NSViewController {
#IBOutlet weak var collectionView: NSCollectionView!
var productCategories: [ProductCategory]?
let baseURL = "http://myURL"
override func viewDidLoad() {
super.viewDidLoad()
getJSON()
self.collectionView.reloadData()
}
func getJSON(){
let url = NSURL(string: baseURL)
let request = NSURLRequest(url: url! as URL)
let session = URLSession(configuration: URLSessionConfiguration.default)
let task = session.dataTask(with: request as URLRequest) { (data,response,error) -> Void in
if error == nil {
let swiftyJSON = JSON(data:data!)
print(swiftyJSON)
let product = swiftyJSON[].arrayValue
for name in product{
let names = name["product_name"].stringValue
print(names)
}
} else{
print("Error")
}
}
task.resume()
}
override var representedObject: Any? {
didSet {
// Update the view, if already loaded.
}
}
}
extension ViewController: NSCollectionViewDataSource{
func collectionView(_ collectionView: NSCollectionView, numberOfItemsInSection section: Int) -> Int {
if let count = productCategories?.count {
return count
}
return 0
}
func collectionView(_ collectionView: NSCollectionView, itemForRepresentedObjectAt indexPath: IndexPath) -> NSCollectionViewItem {
let item = collectionView.makeItem(withIdentifier: "ImageCollectionViewItem", for: indexPath)
item.textField?.stringValue = Product.product_name
return item
}
}
Model.swift
import Foundation
class ProductCategory: NSObject {
var name: String?
var productss: [Product]?
var type: String?
}
class Product: NSObject {
var id: NSNumber?
var product_name: String?
var product_price: NSNumber?
var product_description: String?
var product_image: String?
var product_download: String?
var product_video: String?
var product_featured: Int?
}

populating Tableview with a function that uses SwiftyJSON

I have a function that returns parsed information out of a JSON string.
var info = [AppModel]()
func getEarthquakeInfo(completion: (results : NSArray?) ->Void ){
DataManager.getEarthquakeDataFromFileWithSuccess {
(data) -> Void in
let json = JSON(data: data)
if let JsonArray = json.array {
for appDict in JsonArray {
var ids: String? = appDict["id"].stringValue
var title: String? = appDict["title"].stringValue
var time: String? = appDict["time"].stringValue
var information = AppModel(idEarth: ids, title: title, time: time)
self.info.append(information)
completion(results: self.info)
}
}
}
}
This function uses SwiftyJSON and calls the web service using my DataManager class. When I print it out outside the function I get all the information I need. Now I want to use the title information to populate my TableView. Inside my cellForRowAtIndexPath I've tried filtering out my Earthinformation so that I could get just the title and put that into an array, and populate my tableView with that array. So far I've been unsuccessful, and I've been looking everywhere on how to do this and nothing I've tried or found worked. Can someone point me in the right direction on how to do this?
What I've done so far:
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCellWithIdentifier("reuseIdentifier", forIndexPath: indexPath) as UITableViewCell
getEarthquakeInfo( { (info) -> Void in
var Earthinformation = self.info as NSArray
let titleArray = Earthinformation["TITLE"] as NSArray // error: type int does not conform to protocol "StringLiteralConvertible"
cell.textLabel!.text = titleArray[indexPath.row]
})
return cell
}
3 records I get when I print out Earthinformation I get: ID: 146323, TITLE: M 1.6 - 27km E of Coso Junction, California, TIME: 2015-04-15 14:08:20 UTC,
, ID: 146346, TITLE: M 1.8 - 26km E of Coso Junction, California, TIME: 2015-04-15 14:08:20 UTC,
, ID: 146324, TITLE: M 2.4 - 26km NW of Anchor Point, Alaska, TIME: 2015-04-15 13:33:36 UTC,
Edit:
Sorry I should have included this before:
My AppModel.swift:
class AppModel: NSObject, Printable {
let idEarth: String
let title: String
let time: String
override var description: String {
return "ID: \(idEarth), TITLE: \(title), TIME: \(time), \n"
}
init(idEarth: String?, title: String?, time: String?) {
self.idEarth = idEarth ?? ""
self.title = title ?? ""
self.time = time ?? ""
}
}
And my DataManager.swift file:
let earthquakeURL = "http://www.kuakes.com/json/"
class DataManager {
class func getEarthquakeDataFromFileWithSuccess(success: ((websiteData: NSData) -> Void)) {
//1
loadDataFromURL(NSURL(string: earthquakeURL)!, completion:{(data, error) -> Void in
//2
if let urlData = data {
//3
success(websiteData: urlData)
}
})
}
class func loadDataFromURL(url: NSURL, completion:(data: NSData?, error: NSError?) -> Void) {
var session = NSURLSession.sharedSession()
// Use NSURLSession to get data from an NSURL
let loadDataTask = session.dataTaskWithURL(url, completionHandler: { (data: NSData!, response: NSURLResponse!, error: NSError!) -> Void in
if let responseError = error {
completion(data: nil, error: responseError)
} else if let httpResponse = response as? NSHTTPURLResponse {
if httpResponse.statusCode != 200 {
var statusError = NSError(domain:"com.kuakes", code:httpResponse.statusCode, userInfo:[NSLocalizedDescriptionKey : "HTTP status code has unexpected value."])
completion(data: nil, error: statusError)
} else {
completion(data: data, error: nil)
}
}
})
loadDataTask.resume()
}
}
You are calling your getEarthquakeInfo function every time a cell is to be created. This is very unnecessary and may cause unintentional behavior (seeing as the getEarthquakeInfo function is asynchronous). I recommend utilizing the fact that you have a model array info already to use to populate your tableview. In viewDidLoad call your asynchronous function to retrieve the data for the model array. Example:
override func viewDidLoad() {
super.viewDidLoad()
getEarthquakeInfo { (info) in
// Your model array is now populated so we should reload our data
self.tableView.reloadData()
}
}
Now, adjust your UITableViewDataSource functions to properly handle the model array. Note that I am assuming that your info array is a property of the UITableViewController that is populating the tableView. Example:
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCellWithIdentifier("reuseIdentifier",
forIndexPath: indexPath) as UITableViewCell
// Note that I have no idea how you access the title of your AppModel
// object so you may have to adjust the below code
cell.textLabel!.text = self.info[indexPath.row].title
return cell
}
override func numberOfSectionsInTableView() {
return 1
}
override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) {
return info.count
}