Swift - Why fetching data from JSON have a blank TableView delay before data get displayed? - json

Edit: Please ignore the old answers. I can't create a new question my accunt was blocked. So I edited this one with a new question in the title.
How can i have my data result as soon as i viewDidLoad my tableView ?
Here is a snippet of my code. Can anyone help me to understand the asynchronous part that make my code fetch data and bring me back the result late.
`
let apiUrl = "https://shopicruit.myshopify.com/admin/products.json?
page=1&access_token=c32313df0d0ef512ca64d5b336a0d7c6"
var myRowProduct : String = ""
var productArrayName : [String] = []
var productsPassedOver : [String] = []
override func viewDidLoad() {
super.viewDidLoad()
getFullProductsJson(url: apiUrl, tag1: myRowProduct){array, err in
if err != nil {
print("ERROR 2")
}else{
self.productsPassedOver = array
self.tableView.reloadData()
print("productsPassedOver \(self.productsPassedOver)")
}
}
}
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return productsPassedOver.count
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "ProductCell", for: indexPath)
cell.selectionStyle = .none
cell.textLabel?.text = "\(indexPath.row + 1). " + productsPassedOver[indexPath.row] + "\n" //label are in every single cell. The current text that is displayed by the label
cell.textLabel?.numberOfLines = 0; //removes any limitations on the number of lines displayed
return cell
}
//Networking JSON
func getFullProductsJson(url: String, tag1: String, completion: #escaping ([String], Error?) -> ()) {
Alamofire.request(url, method: .get).responseJSON {
response in
//response.result.value comes back as an optional so use ! to use it. Also value have datatype of Any? thats why we JSON casting
if response.result.isSuccess{
let fullJSON : JSON = JSON(response.result.value!)
let finalArrayOfProductS = self.updateTagProductData(json: fullJSON, tag2: tag1)
completion(finalArrayOfProductS, nil)
}
else{
print("Error JSON")
}
}
}
//JSON parsing, deal with formatting here
func updateTagProductData(json : JSON, tag2: String) -> [String]{
let tagClicked = tag2
var nbOfProducts : Int = 0
nbOfProducts = json["products"].count
var inventoryAvailableTotal : Int = 0
var nbOfVariants : Int = 0
for i in 0..<nbOfProducts {
let tagsGroup : String = json["products"][i]["tags"].stringValue
let productName : String = json["products"][i]["product_type"].stringValue
nbOfVariants = json["products"][i]["variants"].count
if tagsGroup.contains(tagClicked){
for j in 0..<nbOfVariants{
inventoryAvailableTotal += json["products"][i]["variants"][j]["inventory_quantity"].int!
}
print("\(tagClicked) tag exist in the product \(i): \(productName)")
print("inventorytotal \(inventoryAvailableTotal)")
productArrayName.append("\(productName): \(inventoryAvailableTotal) available")
}
}
return productArrayName
}
}
`

This is a function that does something in the background and return immediately, and when it finishes, it calls your completion handler.
So it is natural for this function to go directly to the return finaleNbOfRowsInProductsListPage.
Your solution is that the function shouldn't return the value, but it should
accept a completion handler, and call it when ended. This is the continuation passing style.
func getFullProductsJson(url: String, tag1: String, completion: #escaping (Int?, Error?) -> ()) {
Alamofire.request(url, method: .get).responseJSON {
response in
...
// When you are done
completion(finaleNbOfRowsInProductsListPage, nil)
}
}
Also please note to try avoiding setting a lot of variables, try to make everything a parameter or a return value from a function, this is easier to debug. For example, try to make the list as a parameter that is passed to the completion handler, not as a member variable of your view controller, make this member variable only for the list that is ready to be displayed.
func getFullProductsJson(url: String, tag1: String, completion: #escaping (Products?, Error?) -> ()) {
Alamofire.request(url, method: .get).responseJSON {
response in
...
// When you are done
completion(products, nil)
}
}
var products: [Product] = []
func refreshData() {
getFullProductsJson(url: "YOUR_URL_HERE", tag1: "TAG") {
// Try to use [weak self], also, read about Automatic Reference Counting
productsNullable, error in
if let products = productsNullable {
// Alamofire calls your callback on a background thread
// So you must return to the main thread first when you want
// to pass the result to any UI component.
DispatchQueue.main.async {
self?.products = products
self?.tableView.reloadData()
}
}
}
}

Related

My object array is nil while my data are correct

I try to display my data in a tableView using no framework to parse my data, but when I add my data to my table and debug it, it is nil at the output while my data I retrieve are well parses, have I forgotten something to do?
I use a structure for my parameters as this :
enum Types {
case School
case Hospital
case Station_Essence
case Restaurant
}
struct Adresse {
public var title: String
public var details: String?
public var type: Types
public var coordinate: [String: Any]
}
and in my ViewController, i proced as this :
class ListMapViewController: UIViewController {
#IBOutlet var TitleTableView: UITableView!
#IBOutlet var MapView: MKMapView!
var adresse: [Adresse]?
override func viewDidLoad() {
super.viewDidLoad()
self.TitleTableView.register(UINib(nibName: "ListMapTableViewCell", bundle: nil), forCellReuseIdentifier: "Adresse")
self.TitleTableView.delegate = self
self.TitleTableView.dataSource = self
guard let POI = URL(string: "https://moc4a-poi.herokuapp.com/") else {
return
}
let task = URLSession.shared.dataTask(with: POI) { (data, response, error) in
guard let dataResponse = data else { return }
if let json = try! JSONSerialization.jsonObject(with: dataResponse, options:[]) as? [[String: Any]] {
for data in json {
let title = data["title"] as! String
let details = data["details"] as? String
guard let type = data["type"] as? Int else { return }
let valueType = self.valueType(dataType: type)
guard let coordinates = data["coordinates"] as? [String: Any] else { return }
self.adresse?.append(Adresse(title: title, details: details, type: valueType, coordinate: coordinates))
}
}
print(self.adresse)
}
self.TitleTableView.reloadData()
task.resume()
}
private func valueType(dataType: Int) -> Types {
if(dataType == 1) {
return Types.School
} else if (dataType == 2) {
return Types.Hospital
} else if (dataType == 3) {
return Types.Station_Essence
} else {
return Types.Restaurant
}
}
}
extension ListMapViewController: UITableViewDataSource {
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return self.adresse?.count ?? 0
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "Adresse", for: indexPath) as! ListMapTableViewCell
if let adresse = self.adresse?[indexPath.row] {
cell.draw(adresse: adresse)
}
return cell
}
}
extension ListMapViewController: UITableViewDelegate {
}
You have two big problems.
self.adresse is nil. You never assign it a value. So all of the self.adresse?... do nothing.
You call reloadData too soon. It needs to be done inside the completion block, after you update the data. And it needs to be on the main queue.
To fix #1, change var adresse: [Adresse]? to var adresse = [Adresse](). Then you can get rid of all the ? after uses of adresse.
To fix #2, add:
DispatchQueue.main.async {
self.TitleTableView.reloadData()
}
just after the print at the end of the completion block. Don't forget to remove the current call to reloadData.

Search Bar with JSON Objects in TableView - Swift

class ViewController: UIViewController,UITableViewDelegate,UITableViewDataSource,UISearchBarDelegate,UISearchDisplayDelegate{
#IBOutlet weak var recipeTable: UITableView!
#IBOutlet weak var searchbarValue: UISearchBar!
// search functionality
var filteredAnswers: [JSON]?
func searchBarSearchButtonClicked(_ searchBar: UISearchBar){
self.filteredAnswers?.removeAll()
if (searchBar.text?.isEmpty)! {
self.filteredAnswers = self.recipes } else {
if self.recipes.count > 0 {
for i in 0...self.recipes.count - 1 {
let answer = self.recipes[i] as [Dictionary<String, AnyObject>]
if answer.title.range(of: searchBar.text!, options: .caseInsensitive) != nil {
self.filteredAnswers.append(answer)
}
}
}
}
recipeTable.reloadData();
recipeTable.reloadInputViews();
searchBar.resignFirstResponder()
}
//end search parameters
// tableview functionionalitys
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return recipes.count
}
// tableview functionalities
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath) as! RecipeTableViewCell
cell.recipeLabel.text = recipes[indexPath.row].title
//cell.textLabel?.text = recipe.title
//cell.imageView?.image = recipe.imageUrl
return cell
}
// structs for json
struct Root : Decodable {
let count : Int
let recipes : [Recipe]
}
struct Recipe : Decodable { // It's highly recommended to declare Recipe in singular form
let recipeId : String
let imageUrl, sourceUrl, f2fUrl : URL
let title : String
let publisher : String
let socialRank : Double
let page : Int?
let ingredients : [String]?
}
//recipes is array of Recipes
var recipes = [Recipe]() // array of recipes
//unfiltered recipes to put into search
var filteredRecipes = [Recipe]()
fileprivate func getRecipes() {
let jsonURL = "http://food2fork.com/api/search?key=264045e3ff7b84ee346eb20e1642d9d9"
//.data(using: .utf8)!
//let somedata = Data(jsonURL.utf8)
guard let url = URL(string: jsonURL) else{return}
URLSession.shared.dataTask(with: url) {(data, response , err) in
if let response = response as? HTTPURLResponse, response.statusCode != 200 {
print(response.statusCode)
return
}
DispatchQueue.main.async {
if let err = err{
print("failed to get data from URL",err)
return
}
guard let data = data else{return}
//print(String(data: data, encoding: .utf8))
do {
let decoder = JSONDecoder()
decoder.keyDecodingStrategy = .convertFromSnakeCase
let result = try decoder.decode(Root.self, from: data)
self.recipes = result.recipes
//print(result.recipes)
self.recipeTable.reloadData()
}catch let jsonERR {
print("Failed to decode",jsonERR)
}
}
}.resume()
}
override func viewDidLoad() {
super.viewDidLoad()
//search functionalities
self.searchbarValue.delegate = self
//call json object
getRecipes()
}
}
I am trying to implement a search bar that takes ingredients from the JSON Object and shows the recipes that contain those ingredients in my table view. I am hoping for some best practices and help with this. I have tried a couple different strategies and none seem to be working.
This is the last one I have tried to implement, but I am getting errors in the search functionality.
self.recipes.count in searchBarSearchButtonClicked Cannot assign value
of type '[ViewController.Recipe]' to type '[JSON]?
But I'm also getting an assertion failure in -
[UISearchResultsTableView
_dequeueReusableCellWithIdentifier:forIndexPath:usingPresentationValues:]
I would like to get help but also improve and find the best way to do this. Thanks.
First of all your logic to filter the recipes cannot work and is very, very inefficient. It seems you copied and pasted the code from a completely unrelated source.
Basically the type of the data source array and the type of the filtered array must be the same, so you have to use filteredRecipes rather than filteredAnswers.
To filter the recipes with matching ingredients use filter and contains
func searchBarSearchButtonClicked(_ searchBar: UISearchBar){
filteredRecipes.removeAll()
if let searchText = searchBar.text, !searchText.isEmpty {
self.filteredRecipes = self.recipes.filter { recipe in
guard let ingredients = recipe.ingredients else { return false }
return ingredients.contains { $0.range(of: searchText, options: .caseInsensitive) != nil }
}
} else {
self.filteredRecipes = self.recipes
}
recipeTable.reloadData();
recipeTable.reloadInputViews();
searchBar.resignFirstResponder()
}
Actually this code is supposed to be executed in the delegate method
func searchBar(_ searchBar: UISearchBar, textDidChange searchText: String)
rather than in searchBarSearchButtonClicked
And – very important – you have to add a boolean property to indicate isSearching and in all related datasource and delegate methods you have to add a condition to show the data of filteredRecipes if isSearching is true.

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.

swift 3.0: tableview cannot show data which received as JSON through web api

i started to learn IOS development using swift 3.0.i built a simple app to call web api to query data from server database. i can get the json data and parsed it into string array. the App can print the array, but it cannot show in the tableview. it confused me several days and i searched some examples and answers on internet but still couldn't work out it.
My codes as below:
class LocationTableViewController: UITableViewController {
var names: [String] = []
override func viewDidLoad() {
super.viewDidLoad()
//β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”get the data from web api and using json parsingβ€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”
let config = URLSessionConfiguration.default // Session Configuration
let session = URLSession(configuration: config) // Load configuration into Session
let url = URL(string: "http://XXXXXXX/api/mylocations")!
let task = session.dataTask(with: url, completionHandler: {
(data, response, error) in
if error != nil {
print(error!.localizedDescription)
} else {
do {
var jsonResult: NSMutableArray = NSMutableArray()
let jsonArray = try JSONSerialization.jsonObject(with: data!, options:JSONSerialization.ReadingOptions.allowFragments) as! NSArray
jsonResult = jsonArray.mutableCopy() as! NSMutableArray
var jsonElement: NSDictionary = NSDictionary()
for i in 0..<jsonResult.count {
jsonElement = jsonResult[i] as! NSDictionary
if let name = jsonElement["Name"] as? String
{
// print(id)
// print(name)
// print(address)
// print(latitude)
// print(longitude)
// print("-------")
self.names.append(name)
}
// self.tableView.reloadData()
// print(self.names)
}
print(self.names)
// can print the string array data like [β€œname1”,”name2”,”name3”]
} catch {
print("error in JSONSerialization")
}
}
})
task.resume()
//-------------- β€”β€”β€” result is [] it seems the above code didn't put the string array to names.β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”
print(self.names)
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
}
override func numberOfSections(in tableView: UITableView) -> Int {
return 1
}
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return names.count;
}
internal override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) ->
UITableViewCell {
let cellIdentifier = "cell"
let cell = tableView.dequeueReusableCell(withIdentifier: cellIdentifier, for:
indexPath as IndexPath) as UITableViewCell
// Configure the cell...
cell.textLabel?.text = names[indexPath.row]
return cell
}
}
Can anyone help me have a look?
Put self.tableView.reloadData() after print print(self.names).
At the point where you have commented...
result is [] it seems the above code didn't put the string array to
names
This line of code is being executed before the data has been downloaded within the completion handler, so we wouldn't expect to see anything here. You will note that it is working on the other print that you have within the completion handler.
The tableView.reloadData() at the end of the completion handler should be working.
Are you sure that you have the delegates set up correctly for the tableView? What do you see if you comment out the download task, and simply set
names = ["Tom", "Dick", "Harry"]
within viewDidLoad ? If that doesn't work, it's a problem with the delegates.

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
}