In this video, we go over how to pull JSON data from the internet to build out our dynamic home feed. First, I'll show you how to execute an NSURLSession task to complete a fetch request. Next, we iterate through all the objects in this JSON dictionary and construct all of our video objects. Finally, we update our cell images based on the image urls returned.
!codebreak
<div class='filename'>HomeController.swift</div>
!codebreak
!syntax-highlight
func fetchVideos() {
let url = NSURL(string: "https://s3-us-west-2.amazonaws.com/youtubeassets/home.json")
NSURLSession.sharedSession().dataTaskWithURL(url!) { (data, response, error) in
if error != nil {
print(error)
return
}
do {
let json = try NSJSONSerialization.JSONObjectWithData(data!, options: .MutableContainers)
self.videos = [Video]()
for dictionary in json as! [[String: AnyObject]] {
let video = Video()
video.title = dictionary["title"] as? String
video.thumbnailImageName = dictionary["thumbnail_image_name"] as? String
let channelDictionary = dictionary["channel"] as! [String: AnyObject]
let channel = Channel()
channel.name = channelDictionary["name"] as? String
channel.profileImageName = channelDictionary["profile_image_name"] as? String
video.channel = channel
self.videos?.append(video)
}
self.collectionView?.reloadData()
} catch let jsonError {
print(jsonError)
}
}.resume()
}
!codebreak
<div class='filename'>VideoCell.swift</div>
!codebreak
!syntax-highlight
class VideoCell: BaseCell {
var video: Video? {
didSet {
titleLabel.text = video?.title
setupThumbnailImage()
setupProfileImage()
if let channelName = video?.channel?.name, numberOfViews = video?.numberOfViews {
let numberFormatter = NSNumberFormatter()
numberFormatter.numberStyle = .DecimalStyle
let subtitleText = "\(channelName) • \(numberFormatter.stringFromNumber(numberOfViews)!) • 2 years ago "
subtitleTextView.text = subtitleText
}
//measure title text
if let title = video?.title {
let size = CGSizeMake(frame.width - 16 - 44 - 8 - 16, 1000)
let options = NSStringDrawingOptions.UsesFontLeading.union(.UsesLineFragmentOrigin)
let estimatedRect = NSString(string: title).boundingRectWithSize(size, options: options, attributes: [NSFontAttributeName: UIFont.systemFontOfSize(14)], context: nil)
if estimatedRect.size.height > 20 {
titleLabelHeightConstraint?.constant = 44
} else {
titleLabelHeightConstraint?.constant = 20
}
}
}
}
func setupProfileImage() {
if let profileImageUrl = video?.channel?.profileImageName {
userProfileImageView.loadImageUsingUrlString(profileImageUrl)
}
}
func setupThumbnailImage() {
if let thumbnailImageUrl = video?.thumbnailImageName {
thumbnailImageView.loadImageUsingUrlString(thumbnailImageUrl)
}
}
//...
}
!codebreak
<div class='filename'>UIImageView</div>
!codebreak
!syntax-highlight
extension UIImageView {
func loadImageUsingUrlString(urlString: String) {
let url = NSURL(string: urlString)
NSURLSession.sharedSession().dataTaskWithURL(url!, completionHandler: { (data, respones, error) in
if error != nil {
print(error)
return
}
dispatch_async(dispatch_get_main_queue(), {
self.image = UIImage(data: data!)
})
}).resume()
}
}