Welcome to the Treehouse Community

The Treehouse Community is a meeting place for developers, designers, and programmers of all backgrounds and skill levels to get support. Collaborate here on code errors or bugs that you need feedback on, or asking for an extra set of eyes on your latest project. Join thousands of Treehouse students and alumni in the community today. (Note: Only Treehouse students can comment or ask questions, but non-students are welcome to browse our conversations.)

Looking to learn something new?

Treehouse offers a seven day free trial for new students. Get access to thousands of hours of content and a supportive community. Start your free trial today.

iOS

Jorge Alvarez
Jorge Alvarez
9,330 Points

Blog Reader In Swift

Extracting and representing the json data works with the url provided by treehouse but I do not understand why it does not work with my schools newspaper website so just check out my code and maybe you can help me?

so heres the code!

MasterViewController.swift

 import UIKit

class MasterViewController: UITableViewController {

    var blogPosts = [BlogPost]()


    override func awakeFromNib() {
        super.awakeFromNib()
    }

    override func viewDidLoad() {
        super.viewDidLoad()

        let blogURL = NSURL(string: "http://whsappleleaf.com/?json=get_recent_posts")
        let jsonData = NSData(contentsOfURL: blogURL)

        var error: NSError?

        let dataDictionary = NSJSONSerialization.JSONObjectWithData(jsonData, options: nil, error: &error) as NSDictionary

        let blogPostArray: Array<NSDictionary> = dataDictionary.objectForKey("posts") as Array

        for bpDictionary:NSDictionary in blogPostArray {
            var blogPost = BlogPost(title: bpDictionary["title"] as String)
            blogPost.author = bpDictionary["author"] as String
            blogPost.thumbnail = bpDictionary["thumbnail"] as String
            blogPost.date = bpDictionary["date"] as String
            blogPost.url = NSURL(string: bpDictionary["url"] as String)
            blogPosts.append(blogPost)
        }
    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }

    // #pragma mark - Segues

    override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
        if segue.identifier == "showDetail" {
            let indexPath = self.tableView.indexPathForSelectedRow()
            let blogPost = blogPosts[indexPath!.row]
            (segue.destinationViewController as DetailViewController).blogPostUrl = blogPost.url
            (segue.destinationViewController as DetailViewController).blogPostTitle = blogPost.title
        }
    }

    // #pragma mark - Table View

    override func numberOfSectionsInTableView(tableView: UITableView) -> Int {
        return 1
    }

    override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return blogPosts.count
    }

    override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCellWithIdentifier("Cell", forIndexPath: indexPath) as UITableViewCell

        let blogPost: BlogPost = blogPosts[indexPath.row]

        if blogPost.thumbnail.isEmpty {
            let image = UIImage(named: "apple_leaf.png")
            cell.imageView?.image = image
        } else {
            let imageData = NSData(contentsOfURL: blogPost.thumbnailURL())
            let image = UIImage(data: imageData)
            cell.imageView?.image = image
        }

        cell.textLabel?.text = blogPost.title
        cell.detailTextLabel?.text = "\(blogPost.author) - \(blogPost.formattedDate())"
        return cell
    }

    override func tableView(tableView: UITableView, canEditRowAtIndexPath indexPath: NSIndexPath) -> Bool {
        // Return false if you do not want the specified item to be editable.
        return true
    }

}

DetailViewController.swift

import UIKit

class DetailViewController: UIViewController {

    @IBOutlet var webView : UIWebView! = nil

    var blogPostUrl:NSURL = NSURL()
    var blogPostTitle = ""

    func configureView() {
        // Update the user interface for the detail item.

    }

    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view, typically from a nib.
        self.navigationItem.title = blogPostTitle
        webView.loadRequest(NSURLRequest(URL: blogPostUrl))

    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }


}

BlogPost.swift

import UIKit

class BlogPost: NSObject {
    var title: String
    var author: String = ""
    var thumbnail: String = ""
    var date: String = ""
    var url: NSURL = NSURL()

    init(title: String) {
        self.title = title
        super.init()
    }

    func thumbnailURL() -> NSURL {
        return NSURL.URLWithString(thumbnail)
    }

    func formattedDate() -> String {
        let dateFormatter = NSDateFormatter()
        dateFormatter.dateFormat = "yyyy-MM-dd HH:mm:ss"
        let tempDate = dateFormatter.dateFromString(date)
        dateFormatter.dateFormat = "EE MMM, dd"
        return dateFormatter.stringFromDate(tempDate!)
    }
}

This is the error I am getting

libswiftCore.dylib`swift_dynamicCastObjCClassUnconditional:
0x201ffa0:  pushl  %ebp
0x201ffa1:  movl   %esp, %ebp
0x201ffa3:  pushl  %edi
0x201ffa4:  pushl  %esi
0x201ffa5:  subl   $0x10, %esp
0x201ffa8:  calll  0x201ffad                 ; swift_dynamicCastObjCClassUnconditional + 13
0x201ffad:  popl   %esi
0x201ffae:  movl   0x8(%ebp), %edi
0x201ffb1:  xorl   %eax, %eax
0x201ffb3:  testl  %edi, %edi
0x201ffb5:  je     0x201ffd6                 ; swift_dynamicCastObjCClassUnconditional + 54
0x201ffb7:  movl   0xc(%ebp), %eax
0x201ffba:  movl   0x5587f(%esi), %ecx
0x201ffc0:  movl   %eax, 0x8(%esp)
0x201ffc4:  movl   %ecx, 0x4(%esp)
0x201ffc8:  movl   %edi, (%esp)
0x201ffcb:  calll  0x2022c6a                 ; symbol stub for: objc_msgSend
0x201ffd0:  testb  %al, %al
0x201ffd2:  movl   %edi, %eax
0x201ffd4:  je     0x201ffdd                 ; swift_dynamicCastObjCClassUnconditional + 61
0x201ffd6:  addl   $0x10, %esp
0x201ffd9:  popl   %esi
0x201ffda:  popl   %edi
0x201ffdb:  popl   %ebp
0x201ffdc:  retl   
0x201ffdd:  leal   0xbe05(%esi), %eax
0x201ffe3:  movl   0x490a3(%esi), %ecx
0x201ffe9:  movl   %eax, 0x8(%ecx)
0x201ffec:  movl   $0x0, 0xc(%ecx)
0x201fff3:  int3   
0x201fff4:  nopw   %cs:(%eax,%eax)
Walter Somerville
Walter Somerville
20,698 Points

I may be wrong, but could it have something to do with NSJSONSerialization returning optionals? I could be wrong about that, but since the casting you do should take care of the "anyobject" return type, it's the only thing I saw that might be a problem.

Jorge Alvarez
Jorge Alvarez
9,330 Points

Walter Somerville

So you think it might be because of NSJSONSerialization returning optionals I think you might be right because as I was debugging I realized that _owner = (AnyObject?)nil and that could be a problem

I just got out of school that is why I took so long to reply

3 Answers

Ravi Shankar
PLUS
Ravi Shankar
Courses Plus Student 7,823 Points

The author information is of type dictionary and in the code you are trying to convert a dictionary to string.

blogPost.author = bpDictionary["author"] as String

Try to retrieve the dictionary first then use firstname and lastname to populate the author name. Try println(bpDictionary["author"]) to get some idea on the content.

Hope this helps

Jorge Alvarez
Jorge Alvarez
9,330 Points

when you say that the author is of type dictionary you mean the author information that is retrieved as json if so are you suggesting to further break down that dictionary to then set it as a string?

Ravi Shankar
PLUS
Ravi Shankar
Courses Plus Student 7,823 Points

Yes if further breakdown the dictionary, you will find string attributes with name as first name and last name.

Jorge Alvarez
Jorge Alvarez
9,330 Points

Alright man I will give it a try