Welcome to the Treehouse Community
Want to collaborate on code errors? Have bugs you need feedback on? Looking for an extra set of eyes on your latest project? Get support with fellow developers, designers, and programmers of all backgrounds and skill levels here with the Treehouse Community! While you're at it, check out some resources Treehouse students have shared here.
Looking to learn something new?
Treehouse offers a seven day free trial for new students. Get access to thousands of hours of content and join thousands of Treehouse students and alumni in the community today.
Start your free trial
Marlon Henry
6,885 PointsRedoing the blog reader app in Swift
Sooooo this is for Amit Bijlani and anyone else that might want to help. I was talking to Amit on twitter and told him I was going to redo his Blog reader course in Swift and he told me to post it on the forums, BUT I'm running into some trouble. I'm not getting any syntax errors, but the app is blank when I run it. Console shows that I'm downloading the JSON perfectly fine, I just have no idea why the app won't display it. Below is my code I wrote, any help would be welcomed.
//
// myTableViewController.swift
// Itzbizkit
//
// Created by Havic on 8/31/14.
// Copyright (c) 2014 Cre8tn Havic. All rights reserved.
//
import UIKit
class myTableViewController: UITableViewController {
var blogPosts = []
override func viewDidLoad() {
super.viewDidLoad()
let blogUrl:NSURL = NSURL.URLWithString("http://blog.teamtreehouse.com/api/get_recent_summary/")
let jsonData = NSData(contentsOfURL: blogUrl)
var error:NSError?
var dataDictionary = NSJSONSerialization.JSONObjectWithData(jsonData, options: nil, error: &error) as NSDictionary
println("This the dictionary \(dataDictionary)")
blogPosts = ["test", "test2", "test3"]
}
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 Potentially incomplete method implementation.
// Return the number of sections.
return self.blogPosts.count
}
override func tableView(tableView: UITableView!, numberOfRowsInSection section: Int) -> Int {
// #warning Incomplete method implementation.
// Return the number of rows in the section.
return 0
}
override func tableView(tableView: UITableView!, cellForRowAtIndexPath indexPath: NSIndexPath!) -> UITableViewCell! {
let cell = tableView.dequeueReusableCellWithIdentifier("Cell", forIndexPath: indexPath) as UITableViewCell
var blogPost:NSDictionary = self.blogPosts.objectAtIndex(indexPath.row) as NSDictionary
cell.textLabel.text = blogPosts[indexPath.row]["title"] as NSString
cell.detailTextLabel.text = blogPosts[indexPath.row]["author"] as NSString
return cell
}
}
22 Answers
Dimitris Sotiris Tsolis
28,141 PointsYou have to make a couple of changes.
- Your 'blogPosts' array doesn't contain any blogPost but "test", "test2", "test3". You have to fill it with the blog posts you downloaded before.
blogPosts = NSArray(array: dataDictionary["posts"] as NSArray)
You misplaced the "self.blogPosts.count". You actually need to place it inside "numberOfRowsInSection" and keep the "numberOfSectionsInTableView" to 1.
(This is optional, it should work without any change) Inside "cellForRowAtIndexPath", you already have the blog post as "blogPost" variable. So, you either delete this line of code (you don't need it) and keep the following lines as they are, either you keep it and change
cell.textLabel.text = blogPosts[indexPath.row]["title"] as NSString
cell.detailTextLabel.text = blogPosts[indexPath.row]["author"] as NSString
to
cell.textLabel.text = blogPost["title"] as NSString
cell.detailTextLabel.text = blogPost["author"] as NSString
Hope it helps!
Marlon Henry
6,885 PointsThank you Jack Leonard that actually makes me feel good. I thought you was talking to someone else and then I realized I actually started this thread LOL. I don't know about a video, I will try to see if I can make that happen, I hate how I sound lol.
Jack Leonard
2,894 PointsI Look forward to seeing more in any case! Keep us posted :)
Marlon Henry
6,885 PointsTHANK YOU!!!!
Hai Phung
5,079 PointsHi!
I think you may have the implementations for the numberOfSectionsInTableView and numberOfRowsInSection backwards. You currently have numberOfRowsInSection returning 0, so naturally, you wouldn't see any rows. Try this:
override func numberOfSectionsInTableView(tableView: UITableView!) -> Int {
// #warning Potentially incomplete method implementation.
// Return the number of sections.
return 1; // Remember that this method defaults to 1, so you can delete this bit if you only need 1 section
}
override func tableView(tableView: UITableView!, numberOfRowsInSection section: Int) -> Int {
// #warning Incomplete method implementation.
// Return the number of rows in the section.
return self.blogPosts.count;
}
Hope that helps!
Marlon Henry
6,885 PointsSo I can just delete
cell.textLabel.text = blogPosts[indexPath.row]["title"] as NSString
cell.detailTextLabel.text = blogPosts[indexPath.row]["author"] as NSString
'''
and it will work?
Dimitris Sotiris Tsolis
28,141 PointsActually you have to replace these lines with the lines i wrote you above and make the other changes to i and Hai Phung mentioned!
Marlon Henry
6,885 PointsYeah I made all the changes that you suggested Dimitris Sotiris Tsolis it atcually was working without the last changes, but I made those too as you suggested. Thanks again man.
Dimitris Sotiris Tsolis
28,141 PointsI'm glad it worked! :)
Marlon Henry
6,885 PointsMe too, now I can finish the project and post it up here for you guys.
Dimitris Sotiris Tsolis
28,141 PointsThat would be great! :)
Marlon Henry
6,885 PointsSo @dimitrissotiristsolis I did not even touch the code and now beta 7 saying that this code is not correct now, please help.
override func tableView(tableView: UITableView!, cellForRowAtIndexPath indexPath: NSIndexPath!) -> UITableViewCell! {
let cell = tableView.dequeueReusableCellWithIdentifier("Cell", forIndexPath: indexPath) as UITableViewCell
var blogPost:NSDictionary = self.blogPosts.objectAtIndex(indexPath.row) as NSDictionary
cell.textLabel.text = blogPost["title"] as NSString
cell.detailTextLabel.text = blogPost["author"] as NSString
return cell
}
}
'''
Dimitris Sotiris Tsolis
28,141 PointsYou need to update your code as follows
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCellWithIdentifier("Cell", forIndexPath: indexPath) as UITableViewCell
var blogPost:NSDictionary = self.blogPosts.objectAtIndex(indexPath.row) as NSDictionary
cell.textLabel?.text = blogPosts[indexPath.row]["title"] as NSString
cell.detailTextLabel?.text = blogPosts[indexPath.row]["author"] as NSString
return cell
}
Noticed that "textLabel" and "detailTextLabel" properties of the cell are optional and must use them with the ? at the end. Also, notice that the method have to return a UITableViewCell (that's why the ! symbol goes away). Lastly, if you want to get rid of the warnings, remove the ! symbol from "tableView" and "indexPath" parameters in cellForRowAtIndexPath method ("numberOfSectionsInTableView" and "numberOfRowsInSection" too).
Marlon Henry
6,885 PointsMay I ask why this worked before and I did not even touch anything and now I got errors? lol.
Dimitris Sotiris Tsolis
28,141 PointsIt's based on how UITableViewDataSource api is designed. I don't know the benefits of changing that but since it's still beta, Apple decided that this approach is better than the previous one.
Marlon Henry
6,885 PointsWell cheers to you Dimitris Sotiris Tsolis thanks again.
Dimitris Sotiris Tsolis
28,141 PointsNo problem :)
Marlon Henry
6,885 PointsI know I'm becoming more of a pain then anything with this, but Dimitris Sotiris Tsolis this is also getting annoying to me. It will work fine, I will close the app, then re open Xcode and I will have errors, even if I never touched the code that was working fine the night before. '''iOS required init(coder aDecoder: NSCoder) { fatalError("init(coder:) has not been implemented") } '''
I have NO idea what this means, but Xcode asks me to put it in, which fixes the errors but gives me a thread break. The language of Swish is not the pain it's Xcode right now, HELP!!! lol.
Dimitris Sotiris Tsolis
28,141 PointsDon't worry, no problem! This method "init(coder aDecoder: NSCoder)" is been called during the initialization of an archived object (e.g. a storyboard's nib files generated during the project's build) and it's been called before the "awakeFromNib" method.
Now, the reason your app crushes, is this line of code
fatalError("init(coder:) has not been implemented")
It basically forces your app to crush giving you a reason (the string parameter). I guess it's been auto generated by the Xcode to tell you "ok, don't forget me! initialize something here, else...i'll crush you!" :P
So, to fix this, just delete this line of code and replace it with the super view' initializer...
required init(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
}
...and i believe you're ok!
Marlon Henry
6,885 PointsI got rid of the lines of code that was making Xcode ask me to put that in there(probably for the best lol.) I'm trying to figure out how to pull the thumbnail images into the app, for each blog post to have a thumbnail for each.
And for some reason( I will say it's MY fault, I can't get the tableView to not overlap my status bar)
Dimitris Sotiris Tsolis
28,141 PointsI believe that if you follow the "objective-c style" pattern Amit showed it'll be easy to convert it into swift code. As for the status bar, don't you have tableViewController embedded in a Navigation Controller? If not, i'd suggest to do it. You will need it either way when if you push a new ViewController to display the blog post to the user.
Marlon Henry
6,885 PointsWhat do you mean by "I believe that if you follow the "objective-c style" pattern Amit showed it'll be easy to convert it into swift code."? I'm thinking about restarting this and just taking some of my code that already exists in this and pasting it over into a new project.
Dimitris Sotiris Tsolis
28,141 PointsIn this video, Amit shows how to handle image download by
- check whether the "thumbnail" key has a nil value
- fill a NSData object with the contents of a url
- convert this object to an UIImage object and set it as "image" property of the cell's imageView
if you follow this approach, you can just convert the objective-c code into swift code.
Marlon Henry
6,885 PointsI fixed the tableView issue, so yay lol.
Marlon Henry
6,885 PointsOkay I will re go over the video and try to do it objC style as best as possible, I will be back to bother you later Dimitris Sotiris Tsolis lol.
Jack Leonard
2,894 PointsI'd love to see a video tutorial on this, looks amazing so far :-)