import UIKit
import Alamofire
protocol VideoModelDelegate{
func dataReady()
}
class VideoModel: NSObject {
let API_KEY = ""
let UPLOADS_PLAYLIST_ID = ""
var videoArray = [Video]()
var delegate:VideoModelDelegate?
func getFeedVideos() -> [Video] {
Alamofire.request(.GET, "",parameters: ["part":"snippet", "playlistId":UPLOADS_PLAYLIST_ID ,"key":API_KEY],
encoding: ParameterEncoding.URL, headers: nil).responseJSON {(response) -> Void in
if let JSON = response.result.value{
var arrayOfVideos = [Video]()
for video in JSON["items"] as! NSArray {
print(video)
let videoObj = Video()
videoObj.videoId = video.valueForKeyPath("snippet,resourceId, videoId")
String
videoObj.videoTitle = video.valueForKeyPath("snippet.title") as! String
videoObj.videoDescription = video.valueForKeyPath("snippet.description") as!
String
videoObj.videoThumbnailUrl = video.valueForKeyPath("snippet.thumbnails.maxres.url") as! String
arrayOfVideos.append(videoObj)
}
self.videoArray = arrayOfVideos
if self.delegate != nil {
self.delegate!.dataReady()
}
}
}
}
func getVideos() -> [Video] {
var videos = [Video]()
let video1 = Video()
video1.videoId = ""
video1.videoTitle = ""
videos.append(video1)
return videos
}
}
[Additional Errors][Error]1How to make my viewcontroller conform to protocol "UITableViewDataSource, and Video Mode Delegate"?
I have tried a number of suggested changes in the previous threads, but nothing got me through, Please help me out.
Thanks in advance
import UIKit
import Alamofire
class tab: UIViewController, UITableViewDataSource,
UITableViewDelegate, VideoModelDelegate ERROR- Type 'tab' does not conform to protocol 'UITableViewDataSource'
{
#IBOutlet weak var table: UITableView!
#IBOutlet weak var name: UILabel!
var videos : [Video] = [Video]()
var selectedVideo:Video?
let model:VideoModel = VideoModel()
var arrRes = [[String:AnyObject]]() //Array of dictionary
override func viewDidLoad() {
super.viewDidLoad()
self.model.delegate = self
//self.videos = model.getVideos()
model.getFeedVideos()
self.table.dataSource = self
self.table.delegate = self
/*Alamofire.request(.GET, "http://online.m-tutor.com/mtutor/gateway/mtutorAPI_1.php?type=university").response { (req, res, data, error) -> Void in
print(res)
let outputString = NSString(data: data!, encoding:NSUTF8StringEncoding)
print(outputString)
}
Alamofire.request(.GET, "http://online.m-tutor.com/mtutor/gateway/mtutorAPI_1.php?type=university").responseJSON { response in
if let swiftyJsonVar = response.data
{
print("swiftyJsonvar:\(swiftyJsonVar)")
}
}*/
Alamofire.request(.GET, "http://online.m-tutor.com/mtutor/gateway/mtutorAPI_1.php?type=university").responseJSON { (responseData) -> Void in
let swiftyJsonVar = JSON(responseData.result.value!)
if let resData = swiftyJsonVar["contacts"].arrayObject {
self.arrRes = resData as! [[String:AnyObject]]
}
if self.arrRes.count > 0 {
self.table.reloadData()
}
}
// Do any additional setup after loading the view.
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
func dataReady(){
self.videos = self.model.videoArray
self.table.reloadData()
}
func tableView(table: UITableView, heightForRowAtIndexPath indexPath: NSIndexPath) ->
CGFloat {
return(self.view.frame.size.width / 320) * 180
}
func tableview(table:UITableView, numberOfRowsInSection section: Int ) ->Int{
return videos.count
}
func tableVie(table: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) ->
UITableViewCell{
let cell = table.dequeueReusableCellWithIdentifier("jsonCell")!
let videoTitle = videos[indexPath.row].videoTitle
let label = cell.viewWithTag(2) as! UILabel
label.text = videoTitle
//cell.textLabel?.text = videoTitle
let videoThumbnailUrlString =
videos[indexPath.row].videoThumbnailUrlString;)ERROR:Expected Expression
let videoThumbnailUrl != nil ERROR-'!= is not a prefix unary operator'
and 'Type annotation missing in pattern'
{
let request = NSURLRequest(URL: videoThumbnailUrl!)
let session = NSURLSession.sharedSession()
let dataTask = session.dataTaskWithRequest(request, completionHandler: {(data:NSData?, response:NSURLResponse?, error:NSError) -> Void in
dispatch_async(dispatch_get_main_queue(), { () -> Void in
let imageView = cell.viewWithTag(1) as! UIImageView
imageView.image = UIImage(data: data!)
})
})
dataTask.resume()
}
return cell
func tableView(table: UITableView, didSelectRowAtIndexPath indexpath: NSIndexPath){
self.selectedVideo = self.videos[indexpath.row]
self.performSegueWithIdentifier("toVDVC", sender: self)
}
func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?){
let detailViewController = segue.destinationViewController as! VDViewController
detailViewController.selectedVideo = self.selectedVideo
}
}
}
}
re
It looks as though you haven't closed the method didReceivedMemoryWarning: and the tableview delegate methods are then effectively inside this method causing your issue. Add a closing bracket and it should be fine:
Update: Here is the updated code. There was some more formatting issues with brackets and an error with your if statement in the cellForRowAtIndex:
import UIKit
import Alamofire
class tab: UIViewController, UITableViewDataSource, UITableViewDelegate, VideoModelDelegate {
#IBOutlet weak var table: UITableView!
#IBOutlet weak var name: UILabel!
var videos : [Video] = [Video]()
var selectedVideo:Video?
let model:VideoModel = VideoModel()
var arrRes = [[String:AnyObject]]() //Array of dictionary
override func viewDidLoad() {
super.viewDidLoad()
self.model.delegate = self
//self.videos = model.getVideos()
model.getFeedVideos()
self.table.dataSource = self
self.table.delegate = self
/*Alamofire.request(.GET, "http://online.m-tutor.com/mtutor/gateway/mtutorAPI_1.php?type=university").response { (req, res, data, error) -> Void in
print(res)
let outputString = NSString(data: data!, encoding:NSUTF8StringEncoding)
print(outputString)
}
Alamofire.request(.GET, "http://online.m-tutor.com/mtutor/gateway/mtutorAPI_1.php?type=university").responseJSON { response in
if let swiftyJsonVar = response.data
{
print("swiftyJsonvar:\(swiftyJsonVar)")
}
}*/
Alamofire.request(.GET, "http://online.m-tutor.com/mtutor/gateway/mtutorAPI_1.php?type=university").responseJSON { (responseData) -> Void in
let swiftyJsonVar = JSON(responseData.result.value!)
if let resData = swiftyJsonVar["contacts"].arrayObject {
self.arrRes = resData as! [[String:AnyObject]]
}
if self.arrRes.count > 0 {
self.table.reloadData()
}
}
// Do any additional setup after loading the view.
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
} //ADDED CLOSING BRACKET HERE
func dataReady(){
self.videos = self.model.videoArray
self.table.reloadData()
}
func tableView(table: UITableView, heightForRowAtIndexPath indexPath: NSIndexPath) ->
CGFloat {
return(self.view.frame.size.width / 320) * 180
}
func tableview(table:UITableView, numberOfRowsInSection section: Int ) ->Int{
return videos.count
}
func tableVie(table: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) ->
UITableViewCell{
let cell = table.dequeueReusableCellWithIdentifier("jsonCell")!
let videoTitle = videos[indexPath.row].videoTitle
let label = cell.viewWithTag(2) as! UILabel
label.text = videoTitle
//cell.textLabel?.text = videoTitle
//CHANGE THESE TWO LINES:
//let videoThumbnailUrlString = videos[indexPath.row].videoThumbnailUrlString;)
//if let videoThumbnailUrl != nil {
//TO THIS:
if let videoThumbnailUrl = videos[indexPath.row].videoThumbnailUrlString {
let request = NSURLRequest(URL: videoThumbnailUrl!)
let session = NSURLSession.sharedSession()
let dataTask = session.dataTaskWithRequest(request, completionHandler: {(data:NSData?, response:NSURLResponse?, error:NSError) -> Void in
dispatch_async(dispatch_get_main_queue(), { () -> Void in
let imageView = cell.viewWithTag(1) as! UIImageView
imageView.image = UIImage(data: data!)
})
})
dataTask.resume()
}
return cell
}
func tableView(table: UITableView, didSelectRowAtIndexPath indexpath: NSIndexPath){
self.selectedVideo = self.videos[indexpath.row]
self.performSegueWithIdentifier("toVDVC", sender: self)
}
func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?){
let detailViewController = segue.destinationViewController as! VDViewController
detailViewController.selectedVideo = self.selectedVideo
}
}
Related
I have a UITableView where the data is coming from a Firebase RealtimeDatabase. Once the user selects the row, the data from the row i.e: Title, Description and an Image will be taken to the next ViewController.
I'm able to pass the Title and Description but I'm unable to pass the Image.
Here is my code for the UITableView:
import UIKit
import Firebase
class PostTable: UIViewController, UITableViewDelegate, UITableViewDataSource {
var tableView:UITableView!
var posts = [Post]()
override func viewDidLoad() {
super.viewDidLoad()
tableView = UITableView(frame: view.bounds, style: .plain)
view.addSubview(tableView)
let cellNib = UINib(nibName: "PostTableViewCell", bundle: nil)
tableView.register(cellNib, forCellReuseIdentifier: "postCell")
var layoutGuide:UILayoutGuide!
layoutGuide = view.safeAreaLayoutGuide
tableView.leadingAnchor.constraint(equalTo: layoutGuide.leadingAnchor).isActive = true
tableView.topAnchor.constraint(equalTo: layoutGuide.topAnchor).isActive = true
tableView.trailingAnchor.constraint(equalTo: layoutGuide.trailingAnchor).isActive = true
tableView.bottomAnchor.constraint(equalTo: layoutGuide.bottomAnchor).isActive = true
tableView.delegate = self
tableView.dataSource = self
tableView.tableFooterView = UIView()
tableView.reloadData()
observePosts()
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
func observePosts() {
let postsRef = Database.database().reference().child("Data")
print(postsRef)
postsRef.observe(.value, with: { snapshot in
var tempPosts = [Post]()
for child in snapshot.children{
if let childSnapshot = child as? DataSnapshot,
let dict = childSnapshot.value as? [String:Any],
let title = dict["title"] as? String,
let logoImage = dict["image"] as? String,
let url = URL(string:logoImage),
let description = dict["description"] as? String{
let userProfile = UserProfile(title: title, photoURL: url)
let post = Post(id: childSnapshot.key, title: userProfile, description: description, image: userProfile)
print(post)
tempPosts.append(post)
}
}
self.posts = tempPosts
self.tableView.reloadData()
})
}
func getImage(url: String, completion: #escaping (UIImage?) -> ()) {
URLSession.shared.dataTask(with: URL(string: url)!) { data, response, error in
if error == nil {
completion(UIImage(data: data!))
} else {
completion(nil)
}
}.resume()
}
func numberOfSections(in tableView: UITableView) -> Int {
return 1
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
print(posts.count)
return posts.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell{
let cell = tableView.dequeueReusableCell(withIdentifier: "postCell", for: indexPath) as! PostTableViewCell
cell.set(post: posts[indexPath.row])
return cell
}
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
let postsInfo = posts[indexPath.row]
print(postsInfo)
let Storyboard = UIStoryboard(name: "Main", bundle: nil)
let DvC = Storyboard.instantiateViewController(withIdentifier: "PostTableDetailed") as! PostTableDetailed
DvC.getName = postsInfo.title.title
DvC.getDesc = postsInfo.description
// DvC.getImg = postsInfo.title.photoURL
self.navigationController?.pushViewController(DvC, animated: true)
}
}
Here is the second ViewControler which has the post details:
import UIKit
class PostTableDetailed: UIViewController {
var getName = String()
var getDesc = String()
#IBOutlet weak var Name: UILabel!
#IBOutlet weak var Description: UILabel!
override func viewDidLoad() {
super.viewDidLoad()
Name.text! = getName
Description.text! = getDesc
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
}
I also have a few Models (Post, UserProfile) and Services (UserService and ImageService), please let me know if that is required to break down this problem.
if you have the imageUrl, all you need is to pass it from PostTable to PostTableDetailed and download the image.
// PostTable
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
let postsInfo = posts[indexPath.row]
print(postsInfo)
let Storyboard = UIStoryboard(name: "Main", bundle: nil)
let DvC = Storyboard.instantiateViewController(withIdentifier: "PostTableDetailed") as! PostTableDetailed
DvC.getName = postsInfo.title.title
DvC.getDesc = postsInfo.description
DvC.getImg = postsInfo.photoURL
self.navigationController?.pushViewController(DvC, animated: true)
}
// PostTableDetailed
class PostTableDetailed: UIViewController {
var getName = String()
var getDesc = String()
var imageUrl = ""
#IBOutlet weak var Name: UILabel!
#IBOutlet weak var Description: UILabel!
#IBOutlet weak var imageView: UIImageView!
override func viewDidLoad() {
super.viewDidLoad()
Name.text! = getName
Description.text! = getDesc
updayeImage()
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
private func updateImage() {
URLSession.shared.dataTask(with: URL(string: self.imageUrl)!) { data, response, error in
if error == nil, let data = data {
imageView.image = UIImage(data: data)
}
}.resume()
}
}
The image will be shown when the task will complete.
so I suggest for you to add a spinner to the imageView.
In PostDetail ViewController do like this
import UIKit
class PostTableDetailed: UIViewController {
var getName = String()
var getDesc = String()
var getImg = String()
#IBOutlet weak var Name: UILabel!
#IBOutlet weak var Description: UILabel!
#IBOutlet weak var ImageContainer: UIImageView!
override func viewDidLoad() {
super.viewDidLoad()
Name.text! = getName
Description.text! = getDesc
if let image = getImage(url: getImg) { (image)
ImageContainer.image = image
}
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
func getImage(url: String, completion: #escaping (UIImage?) -> ()) {
URLSession.shared.dataTask(with: URL(string: url)!) { data, response, error in
if error == nil {
completion(UIImage(data: data!))
} else {
completion(nil)
}
}.resume()
}
}
First of all, you can use this code to download the image:
let imageCache = NSCache<AnyObject, AnyObject>()
extension UIImageView {
func downloadImageWithUrlString(urlString: String) -> Void {
if urlString.count == 0 {
print("Image Url is not found")
return
}
self.image = nil
if let cachedImage = imageCache.object(forKey: urlString as AnyObject) as? UIImage {
self.image = cachedImage
return
}
let request = URLRequest(url: URL(string: urlString)!)
let dataTask = URLSession.shared.dataTask(with: request) {data, response, error in
if error != nil { return }
DispatchQueue.main.async {
let downloadedImage = UIImage(data: data!)
if let image = downloadedImage {
imageCache.setObject(image, forKey: urlString as AnyObject)
self.image = UIImage(data: data!)
}
}
}
dataTask.resume()
}
}
Now, if you are using the model that contains Title, Description, and ImageUrlString, then simply pass the selected model object to the next viewController.
In next ViewController, just simply call the same method to download the image which you are using on first ViewController. You don't need to pass the image from VC1 to VC2 because it might be the possible image is not downloaded yet and you select a row to move on next VC.
So here simple thing that pass the model object and calls the image downloading method.
I have this problem (Type any has no subscript members) in this line `
import Foundation
import UIKit
import WebKit
import GoogleMobileAds
class HomeViewController: UIViewController, UITableViewDelegate, UITableViewDataSource,GADBannerViewDelegate {
#IBOutlet weak var BannerView: GADBannerView!
#IBOutlet var tableView: UITableView!
#IBAction func refresh(_ sender: AnyObject) {
get()
}
var values:NSArray = []
override func viewDidLoad() {
super.viewDidLoad();
let request = GADRequest()
request.testDevices = [kGADSimulatorID]
BannerView.delegate = self
BannerView.adUnitID = ""
BannerView.rootViewController = self
BannerView.load(request)
get();
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
func get(){
let url = URL(string: "http://www.X.php")
let data = try? Data(contentsOf: url!)
values = try! JSONSerialization.jsonObject(with: data!, options: JSONSerialization.ReadingOptions.mutableContainers) as! NSArray
tableView.reloadData()
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return values.count;
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath) as! SpecialCell
let maindata = values[(indexPath as NSIndexPath).row]
cell.info!.text = maindata ["Info"] as String?
return cell;
}
}
image
thank you all..
First of all declare the data source array as Swift Array. Foundation NSArray has no type information and doesn't help Swift's strong type system at all.
var values = [[String:Any]]()
Then load the data asynchronously(!) and reload the table view on the main thread
func get() {
let url = URL(string: "http://www.X.php")!
let task = URLSession.shared.dataTask(with: url) { (data, response, error) in
if error != nil {
print(error!)
} else {
do {
self.values = try JSONSerialization.jsonObject(with: data!, options: []) as! [[String:Any]]
DispatchQueue.main.async {
self.tableView.reloadData()
}
} catch {
print(error)
}
}
}
task.resume()
}
Then in cellForRow assign the value
let maindata = values[indexPath.row]
cell.info!.text = maindata["Info"] as? String
Now the compiler knows all subscripted types and the error goes away.
I believe you have to give mainData a type like this:
let maindata = values[(indexPath as NSIndexPath).row] as? [String:Any]
and then make sure mainData actually contains a value
if let info = mainData?["Info"] as? String {
cell.info!.text = info
}
swift 3 json from url can't problem to get cell uitableview
Episode.swift
import Foundation
class Episode
{
var title: String?
var description: String?
var thumbnailURL: URL?
var createdAt: String?
var author: String?
var url: URL?
var episodes = [Episode]()
init(title: String, description: String, thumbnailURL: URL, createdAt: String, author: String)
{
self.title = title
self.description = description
self.thumbnailURL = thumbnailURL
self.createdAt = createdAt
self.author = author
}
init(espDictionary: [String : AnyObject])
{
self.title = espDictionary["title"] as? String
description = espDictionary["description"] as? String
thumbnailURL = URL(string: espDictionary["thumbnailURL"] as! String)
self.createdAt = espDictionary["pubDate"] as? String
self.author = espDictionary["author"] as? String
self.url = URL(string: espDictionary["link"] as! String)
}
static func downloadAllEpisodes() -> [Episode]
{
var episodes = [Episode]()
let url = URL(string:"http://pallive.xp3.biz/DucBlog.json")
URLSession.shared.dataTask(with: url!) { (data, response, error) in
if error != nil {
print(error)
return
}
else {
if let jsonData = data ,let jsonDictionary = NetworkService.parseJSONFromData(jsonData) {
let espDictionaries = jsonDictionary["episodes"] as! [[String : AnyObject]]
for espDictionary in espDictionaries {
let newEpisode = Episode(espDictionary: espDictionary)
episodes.append(newEpisode)
}
}
}
}
.resume()
return episodes
}
}
EpisodeTableViewCell.swift
import UIKit
class EpisodeTableViewCell: UITableViewCell
{
var episode: Episode! {
didSet {
self.updateUI()
print(episode)
}
}
func updateUI()
{
titleLabel.text = episode.title
print(episode.title)
authorImageView.image = UIImage(named: "duc")
descriptionLabel.text = episode.description
createdAtLabel.text = "yosri hadi | \(episode.createdAt!)"
let thumbnailURL = episode.thumbnailURL
let networkService = NetworkService(url: thumbnailURL!)
networkService.downloadImage { (imageData) in
let image = UIImage(data: imageData as Data)
DispatchQueue.main.async(execute: {
self.thumbnailImageView.image = image
})
}
authorImageView.layer.cornerRadius = authorImageView.bounds.width / 2.0
authorImageView.layer.masksToBounds = true
authorImageView.layer.borderColor = UIColor.white.cgColor
authorImageView.layer.borderWidth = 1.0
}
#IBOutlet weak var thumbnailImageView: UIImageView!
#IBOutlet weak var descriptionLabel: UILabel!
#IBOutlet weak var titleLabel: UILabel!
#IBOutlet weak var createdAtLabel: UILabel!
#IBOutlet weak var authorImageView: UIImageView!
}
EpisodesTableViewController.swift
import UIKit
import SafariServices
class EpisodesTableViewController: UITableViewController
{
var episodes = [Episode]()
override func viewDidLoad()
{
super.viewDidLoad()
episodes = Episode.downloadAllEpisodes()
print(Episode.downloadAllEpisodes())
self.tableView.reloadData()
tableView.estimatedRowHeight = tableView.rowHeight
tableView.rowHeight = UITableViewAutomaticDimension
tableView.separatorStyle = .none
}
override var preferredStatusBarStyle: UIStatusBarStyle {
return .lightContent
}
// MARK: - Table view data source
override func numberOfSections(in tableView: UITableView) -> Int
{
return 1
}
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int
{
return episodes.count
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell
{
let cell = tableView.dequeueReusableCell(withIdentifier: "Episode Cell", for: indexPath) as! EpisodeTableViewCell
let episode = self.episodes[(indexPath as NSIndexPath).row]
cell.episode = episode
return cell
}
// MARK: - UITableViewDelegate
override func tableView(_ tableView: UITableView, didSelectRowAt indexPath:
IndexPath)
{
let selectedEpisode = self.episodes[(indexPath as NSIndexPath).row]
// import SafariServices
let safariVC = SFSafariViewController(url: selectedEpisode.url! as URL)
safariVC.view.tintColor = UIColor(red: 248/255.0, green: 47/255.0, blue: 38/255.0, alpha: 1.0)
safariVC.delegate = self
self.present(safariVC, animated: true, completion: nil)
}
// MARK: - Target / Action
#IBAction func fullBlogDidTap(_ sender: AnyObject)
{
// import SafariServices
let safariVC = SFSafariViewController(url: URL(string: "http://www.ductran.io/blog")!)
safariVC.view.tintColor = UIColor(red: 248/255.0, green: 47/255.0, blue: 38/255.0, alpha: 1.0)
safariVC.delegate = self
self.present(safariVC, animated: true, completion: nil)
}
}
extension EpisodesTableViewController : SFSafariViewControllerDelegate
{
func safariViewControllerDidFinish(_ controller: SFSafariViewController) {
controller.dismiss(animated: true, completion: nil)
}
}
whay can't show the parse json in my UITableviewCell in the app
where the problem.
You just need to change this downloadAllEpisodes method of Episode with closure like this.
static func downloadAllEpisodes(completion: ([Episode]) -> ()) {
var episodes = [Episode]()
let url = URL(string:"http://pallive.xp3.biz/DucBlog.json")
URLSession.shared.dataTask(with: url!) { (data, response, error) in
if error != nil {
print(error)
completion(episodes)
}
else {
if let jsonData = data ,let jsonDictionary = NetworkService.parseJSONFromData(jsonData) {
let espDictionaries = jsonDictionary["episodes"] as! [[String : AnyObject]]
for espDictionary in espDictionaries {
let newEpisode = Episode(espDictionary: espDictionary)
episodes.append(newEpisode)
}
}
completion(episodes)
}
}.resume()
}
Now call this method like this.
Episode.downloadAllEpisodes() {(episodes) -> () in
if episodes.count > 0 {
print(episodes)
self.episodes = episodes
self.tableView.reloadData()
}
}
I am trying to use youtube api in ios swift, and following this tutorial http://www.appcoda.com/youtube-api-ios-tutorial/, but some how my didSelectRowAtIndexPath method is never being called.
Any suggestions will be helpful. Thanks
import UIKit
class SearchVideosViewController: UIViewController, UITableViewDataSource,UITableViewDelegate , UITextFieldDelegate{
#IBOutlet weak var wait: UIView!
#IBOutlet weak var tblShowVideoList: UITableView!
#IBOutlet weak var searchVideoText: UITextField!
var selectedVideoIndex:Int!
var videosArray: Array<Dictionary<NSObject,AnyObject>> = []
var apiKey = "my_api_key"
override func viewDidLoad() {
super.viewDidLoad()
searchVideoText.delegate = self
tblShowVideoList.delegate = self
tblShowVideoList.dataSource = self
wait.hidden = true
// Do any additional setup after loading the view.
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
func numberOfSectionsInTableView(tableView: UITableView) -> Int {
return 1
}
func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return videosArray.count
}
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
var cell: UITableViewCell!
cell = tableView.dequeueReusableCellWithIdentifier("videolistcell", forIndexPath: indexPath)
let videoTitle = cell.viewWithTag(10) as! UILabel
let videoThumbnail = cell.viewWithTag(11) as! UIImageView
let videoDetails = videosArray[indexPath.row]
videoTitle.text = videoDetails["title"] as? String
videoThumbnail.image = UIImage(data: NSData(contentsOfURL: NSURL(string: (videoDetails["thumbnail"] as? String)!)!)!)
return cell
}
func tableView(tableView: UITableView, heightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat {
return 140.0
}
// MARK: UITextFieldDelegate method implementation
func textFieldShouldReturn(textField: UITextField) -> Bool {
textField.resignFirstResponder()
wait.hidden = false
let type = "video"
// Form the request URL string.
var urlString = "https://www.googleapis.com/youtube/v3/search?part=snippet&q=\(textField.text)&type=\(type)&key=\(apiKey)"
urlString = urlString.stringByAddingPercentEncodingWithAllowedCharacters(NSCharacterSet.URLQueryAllowedCharacterSet())!
// Create a NSURL object based on the above string.
let targetURL = NSURL(string: urlString)
// Get the results.
performGetRequest(targetURL, completion: { (data, HTTPStatusCode, error) -> Void in
if HTTPStatusCode == 200 && error == nil {
// Convert the JSON data to a dictionary object.
do {
let resultsDict = try NSJSONSerialization.JSONObjectWithData(data!, options: []) as! Dictionary<NSObject, AnyObject>
// Get all search result items ("items" array).
let items: Array<Dictionary<NSObject, AnyObject>> = resultsDict["items"] as! Array<Dictionary<NSObject, AnyObject>>
// Loop through all search results and keep just the necessary data.
for var i=0; i<items.count; ++i {
let snippetDict = items[i]["snippet"] as! Dictionary<NSObject, AnyObject>
// Gather the proper data depending on whether we're searching for channels or for videos.
// Create a new dictionary to store the video details.
var videoDetailsDict = Dictionary<NSObject, AnyObject>()
videoDetailsDict["title"] = snippetDict["title"]
videoDetailsDict["thumbnail"] = ((snippetDict["thumbnails"] as! Dictionary<NSObject, AnyObject>)["default"] as! Dictionary<NSObject, AnyObject>)["url"]
videoDetailsDict["videoID"] = (items[i]["id"] as! Dictionary<NSObject, AnyObject>)["videoId"]
// Append the desiredPlaylistItemDataDict dictionary to the videos array.
self.videosArray.append(videoDetailsDict)
// Reload the tableview.
self.tblShowVideoList.reloadData()
}
} catch {
print(error)
}
}
else {
print("HTTP Status Code = \(HTTPStatusCode)")
print("Error while loading channel videos: \(error)")
}
// Hide the activity indicator.
self.wait.hidden = true
})
return true
}
func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
print("Selected row index \(indexPath.row)")
selectedVideoIndex = indexPath.row
performSegueWithIdentifier("playVideo", sender: self)
}
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
if segue.identifier == "playVideo" {
let videosPlayerViewController = segue.destinationViewController as! VideosPlayerViewController
videosPlayerViewController.videoID = videosArray[selectedVideoIndex]["videoId"] as! String
}
}
// MARK: Custom method implementation
func performGetRequest(targetURL: NSURL!, completion: (data: NSData?, HTTPStatusCode: Int, error: NSError?) -> Void) {
let request = NSMutableURLRequest(URL: targetURL)
request.HTTPMethod = "GET"
let sessionConfiguration = NSURLSessionConfiguration.defaultSessionConfiguration()
let session = NSURLSession(configuration: sessionConfiguration)
let task = session.dataTaskWithRequest(request, completionHandler: { (data: NSData?, response: NSURLResponse?, error: NSError?) -> Void in
dispatch_async(dispatch_get_main_queue(), { () -> Void in
completion(data: data, HTTPStatusCode: (response as! NSHTTPURLResponse).statusCode, error: error)
})
})
task.resume()
}
}
Try comments on:
searchVideoText.delegate = self
I have managed to retrieve data from JSON using swiftJSON but I am facing problems when i try to populate tableview. I am new to iOS development, so please bear with me on this. I would appreciate if you could help or provide some ideas ?
Here's the code:
override func viewDidLoad(){
super.viewDidLoad()
getContactListJSON()
}
func getContactListJSON(){
let urlString = "http://jsonplaceholder.typicode.com/users"
let urlEncodedString = urlString.stringByAddingPercentEscapesUsingEncoding(NSUTF8StringEncoding)
let url = NSURL( string: urlEncodedString!)
var task = NSURLSession.sharedSession().dataTaskWithURL(url!) {(data, response, innerError) in
let json = JSON(data: data)
let contactsArray = json.arrayValue
dispatch_async(dispatch_get_main_queue(), {
for contacts in contactsArray
{
let id = contacts["id"].stringValue
let name = contacts["name"].stringValue
println( "id: \(id) name: \(name)" )
}
})
}
task.resume()
}
Here is your complete code for that:
import UIKit
class TableViewController: UITableViewController {
var tableName = [String]()
var tableID = [String]()
override func viewDidLoad() {
super.viewDidLoad()
getContactListJSON()
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
func getContactListJSON(){
let urlString = "http://jsonplaceholder.typicode.com/users"
let urlEncodedString = urlString.stringByAddingPercentEscapesUsingEncoding(NSUTF8StringEncoding)
let url = NSURL( string: urlEncodedString!)
var task = NSURLSession.sharedSession().dataTaskWithURL(url!) {(data, response, innerError) in
let json = JSON(data: data)
let contactsArray = json.arrayValue
dispatch_async(dispatch_get_main_queue(), {
for contacts in contactsArray
{
let id = contacts["id"].stringValue
let name = contacts["name"].stringValue
println( "id: \(id) name: \(name)" )
self.tableName.append(name)
self.tableID.append(id)
}
dispatch_async(dispatch_get_main_queue(),{
self.tableView.reloadData()
})
})
}
task.resume()
}
// MARK: - Table view data source
override func numberOfSectionsInTableView(tableView: UITableView) -> Int {
return 1
}
override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return tableName.count
}
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCellWithIdentifier("Cell", forIndexPath: indexPath) as! TableViewCell
// Configure the cell...
cell.id.text = tableID[indexPath.row]
cell.name.text = tableName[indexPath.row]
return cell
}
}
And HERE is working sample project for you with custom cell.
First declare a local variable NSArray called contactsArray.
override func viewDidLoad(){
super.viewDidLoad()
getContactListJSON()
}
//Code for downloading data
func getContactListJSON(){
let urlString = "http://jsonplaceholder.typicode.com/users"
let urlEncodedString = urlString.stringByAddingPercentEscapesUsingEncoding(NSUTF8StringEncoding)
let url = NSURL( string: urlEncodedString!)
var task = NSURLSession.sharedSession().dataTaskWithURL(url!) {(data, response, innerError) in
let json = JSON(data: data)
self.contactsArray = json.arrayValue
dispatch_async(dispatch_get_main_queue(), {
[self.tableView reloadData]
})
}
task.resume()
}
func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return self.contactsArray.count;
}
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
var cell:UITableViewCell = self.tableView.dequeueReusableCellWithIdentifier("cell") as UITableViewCell
var contacts:NSDictionary = self.contactsArray[indexPath.row];
cell.textLabel?.text = contacts["name"].stringValue
//.......
//.......
return cell
}
Here is a piece of code.
var dataArray = [String]()
override func viewDidLoad(){
super.viewDidLoad()
getContactListJSON()
}
func getContactListJSON(){
let urlString = "http://jsonplaceholder.typicode.com/users"
let urlEncodedString = urlString.stringByAddingPercentEscapesUsingEncoding(NSUTF8StringEncoding)
let url = NSURL( string: urlEncodedString!)
var task = NSURLSession.sharedSession().dataTaskWithURL(url!) {(data, response, innerError) in
let json = JSON(data: data)
let contactsArray = json.arrayValue
dispatch_async(dispatch_get_main_queue(), {
for contacts in contactsArray
{
let id = contacts["id"].stringValue
let name = contacts["name"].stringValue
println( "id: \(id) name: \(name)" )
self.dataArray.append(name)
}
self.tableView.reloadData()
})
}
task.resume()
}
Here i am taking name. If you want to display id as well, then create a model class for it.