Adding items into Objects - arrays

I'm looking to be able to append a personal location into the MKLocationSearchCompletion array that will can be found when the user searches through the search bar. However, I am having trouble understanding how items are stored into objects and whether I can add a placemark object (or location information) into the MKLocationSearch object. What I've been able to garner from the documentation is that the MKLocalSearchCompleter object stores strings that are accessed when the user types in partial strings into the search bar. But I am not sure where I can access this array and add new locations.
Here is how the code is structured to display search completion results:
var searchCompleter = MKLocalSearchCompleter()
var searchResults = [MKLocalSearchCompletion]()
#IBOutlet weak var searchBar: UISearchBar!
override func viewDidLoad() {
searchCompleter.delegate = self
searchBar.delegate = self
}
extension ViewController: MKLocalSearchCompleterDelegate {
func completerDidUpdateResults(_ completer: MKLocalSearchCompleter) {
searchResults = completer.results
searchResultsTableView.reloadData()
}
func completer(_ completer: MKLocalSearchCompleter, didFailWithError error: Error) {
// handle error
}
}
extension ViewController: UITableViewDataSource {
func numberOfSections(in tableView: UITableView) -> Int {
return 1
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return searchResults.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let searchResult = searchResults[indexPath.row]
let cell = UITableViewCell(style: .subtitle, reuseIdentifier: nil)
cell.textLabel?.attributedText = highlightedText(searchResult.title, inRanges: searchResult.titleHighlightRanges, size: 17.0)
cell.detailTextLabel?.attributedText = highlightedText(searchResult.subtitle, inRanges: searchResult.subtitleHighlightRanges, size: 12.0)
return cell
}
}
extension ViewController: UISearchBarDelegate {
func searchBar(_ searchBar: UISearchBar, textDidChange searchText: String) {
searchCompleter.queryFragment = searchText
}
func searchBarShouldEndEditing(_ searchBar: UISearchBar) -> Bool {
self.searchBar.endEditing(true)
searchBar.resignFirstResponder()
return true
}
}

I don't think that you can add your own locations and POIs to MapKit, but:
1) I would suggest you create an own enum
class CustomSearchResult {
let title: String
...
}
enum SearchResultType {
case localSearchResult(result: MKLocalSearchCompletion)
case customResult(result: CustomSearchResult)
}
2) And you have your array of results:
var searchResults = [SearchResultType]()
3) In completerDidUpdateResults you can add your personal results and the MapKit results into your searchResults array:
searchResults = completer.results.map {
SearchResultType.localSearchResult(result: $0) }
// Add here custom results
searchResults.append(SearchResultType.customResult(result:
CustomSearchResult(title: "test")))
4) ..and in cellForRowAtIndexPath you can decide whether you have custom or MapKit result:
let searchResult = searchResults[indexPath.row]
switch searchResult {
case .customResult(let result):
cell.textLabel.text = result.title
case .localSearchResult(let result):
cell.textLabel.text = result.title
}

Related

Swift - Tableview not updating properly with search queries

I'm using the search bar controller with a tableview. I'm fetching the contacts on my phone to populate the tableview. Here's my code for this part.
func fetchContacts(){
let key = [CNContactGivenNameKey, CNContactFamilyNameKey, CNContactPhoneNumbersKey] as [CNKeyDescriptor]
let request = CNContactFetchRequest(keysToFetch: key)
try! contactStore.enumerateContacts(with: request) {(contact, stoppingPointer) in
let name = "\(contact.givenName) \(contact.familyName)"
let number = contact.phoneNumbers.first?.value.stringValue
for numbero in contact.phoneNumbers {
if let number = numbero.value as? CNPhoneNumber,
let label = numbero.label {
var contactToAppend = ContractStruct(givenName: name, number: number.stringValue)
self.contacts.append(contactToAppend)
}
}
}
tableView.reloadData()
}
It retrieves the contact with different phone numbers properly and then displays in the tableview. I've also added multi selection on the tableview to be able to select multiple contacts to continue with my flow of the app.
My issue is when I'm searching for the contact in the search bar , it always gives me the wrong contacts in my tableview. It comes up with the same name always at the top. Returns wrong contact
Now if I print my filteredcontact list , it returns the proper contact that should have been displayed but it is not displayed on the tableview. Here's my code for the search
func searchBar(_ searchBar: UISearchBar, textDidChange searchText: String) {
if searchBar.text! == "" {
filteredContacts = contacts
} else {
// Filter the results
filteredContacts = contacts.filter { $0.givenName.lowercased().contains(searchBar.text!.lowercased())
}
}
print(filteredContacts)
tableView.reloadData()
}
And here's my full class:
class ContactsViewController: UIViewController, UITableViewDelegate, UITableViewDataSource, UISearchBarDelegate {
#IBOutlet weak var tableView: UITableView!
#IBOutlet weak var searchBar: UISearchBar!
var contactStore = CNContactStore()
var contacts = [ContractStruct]()
var filteredContacts = [ContractStruct]()
var setSelectedItems: Set<Int> = []
var searching = false
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
tableView.delegate = self
tableView.dataSource = self
searchBar.delegate = self
contactStore.requestAccess(for: .contacts) {(success, error) in
if success {
print("Authorisation Successful")
}
self.fetchContacts()
}
filteredContacts = contacts
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return filteredContacts.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = UITableViewCell(style: .subtitle, reuseIdentifier: nil)
if setSelectedItems.contains(indexPath.row) {
cell.accessoryType = .checkmark
}
else {
cell.accessoryType = .none
}
let contactToDisplay = contacts[indexPath.row]
cell.textLabel?.text = contactToDisplay.givenName
cell.detailTextLabel?.text = contactToDisplay.number
return cell
}
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
if setSelectedItems.contains(indexPath.row) {
setSelectedItems.remove(indexPath.row)
} else {
setSelectedItems.insert(indexPath.row)
}
tableView.reloadRows(at: [indexPath], with: .none)
print(setSelectedItems)
}
func searchBar(_ searchBar: UISearchBar, textDidChange searchText: String) {
if searchBar.text! == "" {
filteredContacts = contacts
} else {
// Filter the results
filteredContacts = contacts.filter { $0.givenName.lowercased().contains(searchBar.text!.lowercased())
}
}
print(filteredContacts)
tableView.reloadData()
}
func searchBarCancelButtonClicked(_ searchBar: UISearchBar) {
searching = false
searchBar.text = ""
tableView.reloadData()
}
func fetchContacts(){
let key = [CNContactGivenNameKey, CNContactFamilyNameKey, CNContactPhoneNumbersKey] as [CNKeyDescriptor]
let request = CNContactFetchRequest(keysToFetch: key)
try! contactStore.enumerateContacts(with: request) {(contact, stoppingPointer) in
let name = "\(contact.givenName) \(contact.familyName)"
let number = contact.phoneNumbers.first?.value.stringValue
for numbero in contact.phoneNumbers {
if let number = numbero.value as? CNPhoneNumber,
let label = numbero.label {
var contactToAppend = ContractStruct(givenName: name, number: number.stringValue)
self.contacts.append(contactToAppend)
}
}
}
tableView.reloadData()
}
/*
// MARK: - Navigation
// In a storyboard-based application, you will often want to do a little preparation before navigation
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
// Get the new view controller using segue.destination.
// Pass the selected object to the new view controller.
}
*/
}
Just replace contacts[indexPath.row] to filteredContacts[indexPath.row] in cellForRowAt function of tableView delegate.
Because your filtered results stored in filteredContacts and your tableView delegate functions use filteredContacts
I had to replace filteredContacts[indexPath.row] in cellForRowAt for it to work.

UISearchBar results stored in an Array and displayed in a UITableView are messing with my didSelectRowAt indexPath method (Swift)

I have a UITableView that is populated with items from a titles array and I have it setup so that when didSelectRowAt indexPath is called, a variable called arrayIndex is changed to the indexPath and the content of the next VC is changed.
So if a user taps on:
Row 0 > VC will have Title 0, Definition 0 and Link 0
Row 12 > VC will have Title 12, Definition 12 and Link 12
I have a search bar however that stores the filtered results in a searchResults array and displays them in the tableView. When a search is performed, the array index will no longer correspond, so if the search query changes the tableview to
Title 4 on Row 0 > VC will have Title 0, Definition 0 and Link 0
Title 5 on Row 1 > VC will have Title 1, Definition 1 and Link 1
Title 18 on Row 2 > VC will have Title 2, Definition 2 and Link 2
I understand why it doesn't work as expected, but I am not sure how to update my logic to fix it. Thoughts? Here is my code:
ListController:
import UIKit
var arrayIndex = 0 // is used in DefinitionController to determine which title/definition/link to show.
var isSearching = false
class ListController: UIViewController, UITableViewDataSource, UITableViewDelegate, UISearchBarDelegate {
#IBOutlet var tableView: UITableView!
#IBOutlet var searchBar: UISearchBar!
// Search Delegate
func searchBar(_ searchBar: UISearchBar, textDidChange searchText: String) {
if searchText == "" {
isSearching = false
tableView.reloadData()
} else {
isSearching = true
searchResults = (titles.filter { $0.lowercased().contains(searchText.lowercased()) })
tableView.reloadData()
}
}
//Table Delegate
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
if isSearching == true {
// code to run if searching is true
} else {
arrayIndex = indexPath.row // assigns the value of the selected tow to arrayIndex
}
performSegue(withIdentifier: "segue", sender: self)
tableView.deselectRow(at: indexPath, animated: true)
}
// Table Data Source
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
if isSearching == true {
return searchResults.count
} else {
return titles.count
}
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
// Cell Data Source
let cell = UITableViewCell()
if isSearching == true {
cell.textLabel?.text = searchResults[indexPath.row]
} else {
cell.textLabel?.text = titles[indexPath.row]
}
// Cell Visual Formatting
cell.backgroundColor = UIColor(red:0.05, green:0.05, blue:0.07, alpha:0)
cell.textLabel?.textColor = UIColor.white
cell.textLabel?.font = UIFont(name: "Raleway", size: 18)
cell.accessoryType = UITableViewCellAccessoryType.disclosureIndicator
// if (cell.isSelected) {
// cell.backgroundColor = UIColor.cyan
// }else{
// cell.backgroundColor = UIColor.blue
// }
return cell
}
override func viewDidLoad() {
super.viewDidLoad()
self.title = "\(titles.count) Definitions"
// TextField Color Customization
let searchBarStyle = searchBar.value(forKey: "searchField") as? UITextField
searchBarStyle?.textColor = UIColor.white
searchBarStyle?.backgroundColor = UIColor(red:1.00, green:1.00, blue:1.00, alpha:0.05)
}
}
Definition Controller:
import UIKit
class DefinitionController: UIViewController {
#IBOutlet var definitionTitle: UILabel!
#IBOutlet var definitionBody: UILabel!
#IBOutlet var definitionSources: UILabel!
// Open link in Safari
#objc func tapFunction(sender:UITapGestureRecognizer) {
print("tap working")
if let url = URL(string: "\(links[arrayIndex])") {
UIApplication.shared.openURL(url)
}
}
override func viewDidLoad() {
super.viewDidLoad()
definitionTitle.text = titles[arrayIndex]
definitionBody.text = definitions[arrayIndex]
self.title = "" // Used to be \(titles[arrayIndex])
// Sources Link
let tap = UITapGestureRecognizer(target: self, action: #selector(DefinitionController.tapFunction))
definitionSources.addGestureRecognizer(tap)
}
}
Try using a dictionary where the key is your title and its value its a dictionary containing the definition and link, and an array where you will store the search results i.e the keys searched.
var dictionary = ["title 0":["definition 0", "Link 0"], "title 1": ["definition 1", "Link 1"]]
func searchBar(_ searchBar: UISearchBar, textDidChange searchText: String) {
if searchText == "" {
isSearching = false
tableView.reloadData()
} else {
isSearching = true
for (key, value) in dictionary {
if key==searchText{
resultsArray.append(key)
}
}
tableView.reloadData()
}
}
Now when you tap on a cell in the List Controller let it know which key's details you want to initialise and load in the next VC:
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
let DefinitionViewController = self.storyboard?.instantiateViewController(withIdentifier: "DefinitionViewController") as! DefinitionViewController
//initialise data for the view controller
ListViewController.initDetails(forKey: resultsArray[indexPath.row])
performSegue(withIdentifier: "segue", sender: self)
tableView.deselectRow(at: indexPath, animated: true)
}
In your Definition Controller initialise the details:
func initDetails(forKey key: String) {
definitionBody.text=dictionary[key]![0]
definitionSources.text=dictionary[key]![1]
}
I thought of what seems to me like a pretty dirty solution, because it requires keeping two sets of titles, so I'm still curious if anyone knows a better way, but this does work:
If searching (to avoid calling the switch if it's not needed), under didSelectRowAt indexPath, I created a switch that essentially checks the text of the selected cell and sets the value of arrayIndex accordingly.
let selectedCell = tableView.cellForRow(at: indexPath)?.textLabel!.text ?? "Undefined"
switch selectedCell {
case "Anger": arrayIndex = 0
case "Anguish": arrayIndex = 1
case "Anxiety": arrayIndex = 2
case "Annoyance": arrayIndex = 3
case "Apathy": arrayIndex = 4
default: print("Undefined Search Query")
}
The titles array will eventually have some 55 elements and I had hoped to keep all the data in a separate Data.swift file, but this is the only solution I have so far.

Cannot assign value of type '[[String : AnyObject]]' to type '[[String : AnyObject?]]'

I'm getting the following error:
Cannot assign value of type '[[String : AnyObject]]' to type '[[String : AnyObject?]]'
It's strange this assignment was working before then when I restarted my Xcode, I started to get this error. From what I have read online, this should not give the error.
Here is my code:
import UIKit
import Alamofire
import SwiftyJSON
class Signal Condo TableViewController: UITableViewController {
#IBOutlet var tableview: UITableView!
var singleCondoData = [[String:AnyObject]]()
var CondoIndivi = [[String:AnyObject]]()
override func viewDidLoad() {
super.viewDidLoad()
// Uncomment the following line to preserve selection between presentations
// self.clearsSelectionOnViewWillAppear = false
// Uncomment the following line to display an Edit button in the navigation bar for this view controller.
// self.navigationItem.rightBarButtonItem = self.editButtonItem()
self.tableView.delegate = self
self.tableView.dataSource = self
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
// MARK: - Table view data source
override func numberOfSectionsInTableView(tableView: UITableView) -> Int {
// #warning Incomplete implementation, return the number of sections
return 1
}
override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
// #warning Incomplete implementation, return the number of rows
return singleCondoData.count
}
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCellWithIdentifier("Cell", forIndexPath: indexPath) as! SignleTableTableViewCell
if singleCondoData.count != 0 {
let dict = singleCondoData[indexPath.row] as NSDictionary
//cell.label1.text? = (dict["name"] as? String)!
if let nullcheck = (dict["address"] as? String) {
cell.label2.text? = nullcheck
}
}
return cell
}
override func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
let dict = singleCondoData[indexPath.row] as NSDictionary
if let unitNullCheck = (dict["mls_number"] as? String) {
let item_id = unitNullCheck
getCondoUnits(item_id)
print(item_id)
}
}
//get the individual condo id
func getCondoUnits(condo_id : String){
Alamofire.request(.GET, "http://android.goidx.com/search/?mls_number=" + String(condo_id)).validate().responseJSON { response in
if let value = response.result.value {
let json = JSON(value)
if let resData = json.arrayObject {
self.CondoIndivi = (resData as? [[String:AnyObject]])!
print(self.CondoIndivi)
}
if self.CondoIndivi.count > 0 {
self.tableview.reloadData()
}
}
}
}
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
if let identifier = segue.identifier {
switch identifier {
case "details" :
let buildingdDetailVC = segue.destinationViewController as! DetailsViewController
buildingdDetailVC.CondoIndivi2 = self.CondoIndivi // line of the error
default:
break
}
}
}
}
The type of CondoIndivi2 variable is [[String: AnyObject?]] but you are passing an array of type [[String: AnyObject]] where the dictionary values are non-optional.
Since any non-optional value with same type can be safely converted to its optional corresponding, you can do the following:
buildingdDetailVC.CondoIndivi2 = self.CondoIndivi.map { $0 as [String: AnyObject?] }

Fatal error : Index out of range

I m getting this error :fatal error: Index out of range .I can't get what i m doing wrong .What i'm trying to do is , access an array dictionary by using an integer index than pass a string to get the value mapped to it .The sample works fine on playground but not excode why ? (The array dictionary is not empty)
Here is my code
var CondoIndivi2 = [[String:AnyObject]]()
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
scrollView.contentSize.height = 1500
print(CondoIndivi2)
if let description_Condo = self.CondoIndivi2[0]["description"] as? String {
print(description_Condo)
}
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
}
This is the view that sends data to CondoIndivi2
import UIKit
import Alamofire
import SwiftyJSON
class SignleCondoTableViewController: UITableViewController {
#IBOutlet var tableview: UITableView!
var singleCondoData = [[String:AnyObject]]()
var CondoIndivi = [[String:AnyObject]]()
override func viewDidLoad() {
super.viewDidLoad()
// Uncomment the following line to preserve selection between presentations
// self.clearsSelectionOnViewWillAppear = false
// Uncomment the following line to display an Edit button in the navigation bar for this view controller.
// self.navigationItem.rightBarButtonItem = self.editButtonItem()
self.tableView.delegate = self
self.tableView.dataSource = self
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
// MARK: - Table view data source
override func numberOfSectionsInTableView(tableView: UITableView) -> Int {
// #warning Incomplete implementation, return the number of sections
return 1
}
override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
// #warning Incomplete implementation, return the number of rows
return singleCondoData.count
}
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCellWithIdentifier("Cell", forIndexPath: indexPath) as! SignleTableTableViewCell
if singleCondoData.count != 0 {
let dict = singleCondoData[indexPath.row] as NSDictionary
//cell.label1.text? = (dict["name"] as? String)!
if let nullcheck = (dict["address"] as? String) {
cell.label2.text? = nullcheck
}
}
return cell
}
override func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
let dict = singleCondoData[indexPath.row] as NSDictionary
if let unitNullCheck = (dict["mls_number"] as? String) {
let item_id = unitNullCheck
getCondoUnits(item_id)
print(item_id)
}
}
//get the individual condo id
func getCondoUnits(condo_id : String){
Alamofire.request(.GET, "http://android.goidx.com/search/?mls_number=" + String(condo_id)).validate().responseJSON { response in
if let value = response.result.value {
let json = JSON(value)
if let resData = json.arrayObject {
self.CondoIndivi = resData as! [[String:AnyObject]]
print(self.CondoIndivi)
}
if self.CondoIndivi.count > 0 {
self.tableview.reloadData()
}
}
}
}
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
if let identifier = segue.identifier {
switch identifier {
case "details" :
let buildingdDetailVC = segue.destinationViewController as! DetailsViewController
buildingdDetailVC.CondoIndivi2 = self.CondoIndivi
default:
break
}
}
}
/*
// Override to support conditional editing of the table view.
override func tableView(tableView: UITableView, canEditRowAtIndexPath indexPath: NSIndexPath) -> Bool {
// Return false if you do not want the specified item to be editable.
As #James put in his comment, you're creating an empty array in your code:
var CondoIndivi2 = [[String:AnyObject]]()
And then you're trying to access indexing in the position 0:
if let description_Condo = self.CondoIndivi2[0]["description"] as? String {
print(description_Condo)
}
And of course, you will have a runtime error of Index of out Range because your array it's empty, you always need to be sure before index an array that the index is greater than zero, less than equal to the size of the array and the array is not empty.
I hope this help you.
Inside your getCondoUnits(condo_id : String) is an asynchronous block(Alamofire.request), the CondoIndivi2 is received later than the viewDidLoad is executed. You should just pass condo_id to next viewController and do the request in it.

How to transfer data from NSArray to String in Swift?

I have to put data in tableview, but even tough I get info from JSON, I can't pass data to postTitle variable. Why is that? Here is my code:
import UIKit
class ViewController: UIViewController, UITableViewDelegate, UITableViewDataSource {
var postTitle = [AnyObject]()
override func viewDidLoad() {
super.viewDidLoad()
var baseURL = "https://hacker-news.firebaseio.com/v0/topstories.json"
// https://hacker-news.firebaseio.com/v0/item/9324191.json
if let url = NSURL(string: baseURL) {
var taskURL = NSURLSession.sharedSession().dataTaskWithURL(url, completionHandler: { (data: NSData!, response: NSURLResponse!, error: NSError!) -> Void in
if error != nil {
println("Error: \(error.localizedDescription)")
} else {
var jsonError: NSError?
if let topStories = NSJSONSerialization.JSONObjectWithData(data, options: NSJSONReadingOptions.MutableContainers, error: &jsonError) as? NSArray {
self.postTitle.append(topStories)
}
}
})
taskURL.resume()
}
}
func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
println(postTitle.count)
return postTitle.count
}
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
var cell = UITableViewCell()
println(self.postTitle)
// cell.textLabel?.text = postTitle[indexPath.row]
return cell
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
}
topStories is an NSArray, but you are appending it to the postTitle array (which is of type [AnyObject]). Array.append adds a single item to the array. So you will have added one entry, an NSArray of a bunch of post IDs, to your postTitle array.
I am guessing what you want is to add the contents of topStories to postTitle? In which case you want to use the extend rather than the append method:
self.postTitle.extend(topStories)
Given that you apparently reload ALL the titles with each request, you could just as easily do this: self.titles = topStories
I just built a test app this way and it worked perfectly fine.
PS: self.postTitle.append would have yielded the wrong result anyway, as it would also append titles you already have in your array. The method you probably should be using would be self.postTitle.join as it uses intersection.
So the other guy from Reddit help me out. I was missing few things. First was data type Int, which needs to be passed to instance variable, and second was UITableView: here is working solution. Hope this will help someone.
import UIKit
class ViewController: UITableViewController, UITableViewDelegate, UITableViewDataSource {
var postTitles = [Int]()
override func viewDidLoad() {
super.viewDidLoad()
var baseURL = "https://hacker-news.firebaseio.com/v0/topstories.json"
if let url = NSURL(string: baseURL) {
var taskURL = NSURLSession.sharedSession().dataTaskWithURL(url, completionHandler: { (data: NSData!, response: NSURLResponse!, error: NSError!) -> Void in
if error != nil {
println("Error: \(error.localizedDescription)")
} else {
var jsonError: NSError?
if let topStories = NSJSONSerialization.JSONObjectWithData(data, options: NSJSONReadingOptions.MutableContainers, error: &jsonError) as? [Int] {
self.postTitles = Array(topStories[0...9])
// Reload the table with our new results!
self.tableView.reloadData()
}
}
})
taskURL.resume()
}
}
override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return postTitles.count
}
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCellWithIdentifier("Cell") as UITableViewCell
let postTitle = String(self.postTitles[indexPath.row])
cell.textLabel?.text = postTitle
return cell
}
}

Resources