didSelectRowAtIndexPath not being called - ios

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

Related

How do I fix laggy UITableView scrolling performance when downloading JSON?

In my application, I download a JSON file off of the internet and fill up a UITableView with items from the file. It does work well, and there are no problems or errors, but the scrolling performance is very laggy, and the UI glitches out a tiny bit.
I assume this is because of the images that I'm downloading from the JSON file, so I've looked into multi-threading, but I don't think I am doing it right because it does load much faster, but scrolling performance is still the same as before.
Can somebody please tell me how to fix this? This UITableView is the most important thing in the app, and I have been spending much time on trying to fix it. Thank you!
Here is my code-
import UIKit
class ViewController: UIViewController, UITableViewDataSource {
#IBOutlet weak var tableView: UITableView!
var nameArray = [String]()
var idArray = [String]()
var ageArray = [String]()
var genderArray = [String]()
var descriptionArray = [String]()
var imgURLArray = [String]()
let myActivityIndicator = UIActivityIndicatorView(activityIndicatorStyle: UIActivityIndicatorViewStyle.gray)
final let urlString = "https://pbsocfilestorage.000webhostapp.com/jsonDogs.json"
override func viewDidLoad() {
super.viewDidLoad()
self.downloadJsonWithURL()
// Activity Indicator
myActivityIndicator.center = view.center
myActivityIndicator.hidesWhenStopped = true
myActivityIndicator.startAnimating()
view.addSubview(myActivityIndicator)
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
func downloadJsonWithURL() {
let url = NSURL(string:urlString)
URLSession.shared.dataTask(with: (url as? URL)!, completionHandler: {(data, response, error) ->
Void in
print("Good so far...")
if let jsonObj = try? JSONSerialization.jsonObject(with: data!, options: .allowFragments) as? NSDictionary {
print(jsonObj!.value(forKey: "dogs"))
if let dogArray = jsonObj!.value(forKey: "dogs") as? NSArray {
print("Why u no work!")
for dog in dogArray {
if let dogDict = dog as? NSDictionary {
if let name = dogDict.value(forKey: "name") {
self.nameArray.append(name as! String)
}
if let name = dogDict.value(forKey: "id") {
self.idArray.append(name as! String)
}
if let name = dogDict.value(forKey: "age") {
self.ageArray.append(name as! String)
}
if let name = dogDict.value(forKey: "gender") {
self.genderArray.append(name as! String)
}
if let name = dogDict.value(forKey: "image") {
self.imgURLArray.append(name as! String)
}
if let name = dogDict.value(forKey: "description") {
self.descriptionArray.append(name as! String)
}
OperationQueue.main.addOperation ({
self.myActivityIndicator.stopAnimating()
self.tableView.reloadData()
})
}
}
}
}
}).resume()
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return nameArray.count
}
func tableView(tableView: UITableView, estimatedHeightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat {
return UITableViewAutomaticDimension;
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let imgURL = NSURL(string: imgURLArray[indexPath.row])
let cell = tableView.dequeueReusableCell(withIdentifier: "reusableCell") as! TableViewCell
URLSession.shared.dataTask(with: (imgURL as! URL), completionHandler: {(data, resp, error) -> Void in
if (error == nil && data != nil) {
OperationQueue.main.addOperation({
cell.dogNameLabel.text = self.nameArray[indexPath.row]
cell.idLabel.text = self.idArray[indexPath.row]
cell.ageLabel.text = self.ageArray[indexPath.row]
cell.genderLabel.text = self.genderArray[indexPath.row]
print("Cell info was filled in!")
if imgURL != nil {
let data = NSData(contentsOf: (imgURL as? URL)!)
cell.dogImage.image = UIImage(data: data as! Data)
}
})
}
}).resume()
return cell
}
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if segue.identifier == "showDog" {
if let indexPath = self.tableView.indexPathForSelectedRow{
let detailViewController = segue.destination as! DetailViewController
detailViewController.imageString = imgURLArray[indexPath.row]
detailViewController.nameString = nameArray[indexPath.row]
detailViewController.idString = idArray[indexPath.row]
detailViewController.ageString = ageArray[indexPath.row]
detailViewController.descriptionString = descriptionArray[indexPath.row]
detailViewController.genderString = genderArray[indexPath.row]
}
}
}
}
There is a big mistake. You are loading data with dataTask but you aren't using that returned data at all. Rather than you are loading the data a second time with synchronous contentsOf. Don't do that.
And don't update the labels in the asynchronous completion block. The strings are not related to the image data.
This is more efficient:
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let imgURL = URL(string: imgURLArray[indexPath.row])
let cell = tableView.dequeueReusableCell(withIdentifier: "reusableCell", for: indexPath) as! TableViewCell
cell.dogNameLabel.text = self.nameArray[indexPath.row]
cell.idLabel.text = self.idArray[indexPath.row]
cell.ageLabel.text = self.ageArray[indexPath.row]
cell.genderLabel.text = self.genderArray[indexPath.row]
print("Cell info was filled in!")
URLSession.shared.dataTask(with: imgURL!) { (data, resp, error) in
if let data = data {
OperationQueue.main.addOperation({
cell.dogImage.image = UIImage(data: data)
})
}
}.resume()
return cell
}
Note: You are strongly discouraged from using multiple arrays as data source. It's very error-prone. Use a custom struct or class. And create imgURLArray with URL instances rather than strings. This is also much more efficient.
Nevertheless, you should use a download manager which caches the images and cancels downloads if a cell goes off-screen. At the moment each image is downloaded again when the user scrolls and cellForRow is called again for this particular cell.

viewcontroller conform to protocol "UITableViewDataSource, Video Mode Delegate"?

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
}
}

not showing data in table view swift

i have one table view with two labels. I need to display the data which are coming from json. But now its not showing any data in table view:
import UIKit
class ViewController: UIViewController,UITableViewDataSource,UITableViewDelegate
{
let yourJsonFormat: String = "JSONFile" // set text JSONFile : json data from file
// set text JSONUrl : json data from web url
var arrDict :NSMutableArray=[]
#IBOutlet weak var tvJSON: UITableView!
override func viewDidLoad()
{
super.viewDidLoad()
if yourJsonFormat == "JSONFile" {
jsonParsingFromFile()
} else {
jsonParsingFromURL()
}
}
func jsonParsingFromURL () {
let url = NSURL(string: "url")
let request = NSURLRequest(URL: url!)
NSURLConnection.sendAsynchronousRequest(request, queue: NSOperationQueue.mainQueue()) {(response, data, error) in
}
}
func jsonParsingFromFile()
{
let path: NSString = NSBundle.mainBundle().pathForResource("days", ofType: "json")!
let data : NSData = try! NSData(contentsOfFile: path as String, options: NSDataReadingOptions.DataReadingMapped)
}
func numberOfSectionsInTableView(tableView: UITableView) -> Int
{
return 1
}
func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int
{
return arrDict.count
}
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell
{
let cell : TableViewCell! = tableView.dequeueReusableCellWithIdentifier("Cell") as! TableViewCell
let strTitle : NSString=arrDict[indexPath.row] .valueForKey("name") as! NSString
let strDescription : NSString=arrDict[indexPath.row] .valueForKey("rating") as! NSString
cell.lblTitle.text=strTitle as String
cell.lbDetails.text=strDescription as String
return cell as TableViewCell
}
}
Any thing i missed,please help me out.
I am not able to see any data in my table view...
your code is partially correct, I followed your question
Step-1
Right click on the info.plist file, select open as, Source code. Add the lines of code that allow the http connection to this server.
do like
Step-2
For Server request
sendAsynchronousRequest is deprecated in this place use
func jsonParsingFromURL () {
let url = NSURL(string: "url")
let session = NSURLSession.sharedSession()
let request = NSURLRequest(URL: url!)
let dataTask = session.dataTaskWithRequest(request) { (data:NSData?, response:NSURLResponse?, error:NSError?) -> Void in
print("done, error: \(error)")
let dict: NSDictionary!=(try! NSJSONSerialization.JSONObjectWithData(data, options: NSJSONReadingOptions.MutableContainers)) as! NSDictionary
arrDict.addObject((dict.valueForKey("xxxx")
tvJSON .reloadData()
}
dataTask.resume()
}
For local Request
func jsonParsingFromFile()
{
let path: NSString = NSBundle.mainBundle().pathForResource("days", ofType: "json")!
let data : NSData = try! NSData(contentsOfFile: path as String, options: NSDataReadingOptions.DataReadingMapped)
let dict: NSDictionary!=(try! NSJSONSerialization.JSONObjectWithData(data, options: NSJSONReadingOptions.MutableContainers)) as! NSDictionary
arrDict.addObject((dict.valueForKey("xxxx")
tvJSON .reloadData()
}
Update and Edit
class ViewController: UIViewController,UITableViewDelegate,UITableViewDataSource {
#IBOutlet var showtable: UITableView!
var arrDict :NSMutableArray=[]
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
self.jsonParsingFromURL()
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
func jsonParsingFromURL () {
let url = NSURL(string: "http://kirisoft.limitscale.com/GetVendor.php?category_id=1")
let session = NSURLSession.sharedSession()
let request = NSURLRequest(URL: url!)
let dataTask = session.dataTaskWithRequest(request) { (data:NSData?, response:NSURLResponse?, error:NSError?) -> Void in
print("done, error: \(error)")
if error == nil
{
self.arrDict=(try! NSJSONSerialization.JSONObjectWithData(data!, options: NSJSONReadingOptions.MutableContainers)) as! NSMutableArray
print(self.arrDict)
if (self.arrDict.count>0)
{
self.showtable.reloadData()
}
// arrDict.addObject((dict.valueForKey("xxxx")
}
}
dataTask.resume()
}
func numberOfSectionsInTableView(tableView: UITableView) -> Int
{
return 1
}
func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int
{
return arrDict.count
}
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell
{
let CellIdentifier: String = "cell"
var cell = tableView.dequeueReusableCellWithIdentifier(CellIdentifier) as UITableViewCell!
if cell == nil {
cell = UITableViewCell(style: UITableViewCellStyle.Subtitle, reuseIdentifier: CellIdentifier)
}
cell?.textLabel!.text=arrDict[indexPath.row] .valueForKey("name") as? String
cell?.detailTextLabel!.text=arrDict[indexPath.row] .valueForKey("rating") as? String
return cell!
}
}
you can get the output like
For sample Project

how to populate data in UITableView ? swift

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.

How to segue from a Table Cell View in Swift

This is the code i have to far on the main table view view controller I just don't know how to go about transitioning to a new view controller to a selected cell to display more content about whatever cell was selected.
import UIKit
class MainVC: UITableViewController, UITableViewDelegate, UITableViewDataSource {
#IBOutlet var Table1: UITableView!
var postArray: [[String]] = []
var postSubject = ""
var postDescription = ""
var postDate = ""
override func viewDidLoad() {
super.viewDidLoad()
fetchData()
}
func fetchData() {
println("success1")
postArray = []
let httpMethod = "GET"
let timeout = 15
let urlAsString = "http://cgi.soic.indiana.edu/~team12/main_requests.php"
let url = NSURL(string: urlAsString)!
let urlRequest = NSMutableURLRequest(URL: url,
cachePolicy: .ReloadIgnoringLocalAndRemoteCacheData,
timeoutInterval: 15.0)
urlRequest.HTTPMethod = httpMethod
let queue = NSOperationQueue()
println("success2")
NSURLConnection.sendAsynchronousRequest(urlRequest,
queue: queue,
completionHandler: {(response: NSURLResponse!,
data: NSData!,
error: NSError!) in
if data.length > 0 && error == nil{
let html = NSString(data: data, encoding: NSUTF8StringEncoding)
} else if data.length == 0 && error == nil{
println("Nothing was downloaded")
} else if error != nil{
println("Error happened = \(error)")
}
if data.length > 0 && error == nil {
let html = NSString(data: data, encoding: NSUTF8StringEncoding)
var newArrayofDicts : NSMutableArray = NSMutableArray()
var arrayOfDicts : NSMutableArray? = NSJSONSerialization.JSONObjectWithData(data, options:NSJSONReadingOptions.MutableContainers, error:nil) as? NSMutableArray
println("successmutable")
if arrayOfDicts != nil {
for item in arrayOfDicts! {
if var dict = item as? NSMutableDictionary{
if dict["subject"] != nil{
self.postSubject = dict["subject"] as String
self.postDescription = dict["subject"] as String
self.postDate = dict["date"] as String
self.postArray.append([self.postSubject,self.postDescription,self.postDate])
println("successpost")
}
}
}
}
}
}
)
sleep(1)
}
override func viewDidAppear(animated: Bool) {
super.viewDidAppear(animated)
fetchData()
tableView.reloadData()
println("successanime")
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
}
override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return postArray.count
}
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
println("successoverride")
let cell = tableView.dequeueReusableCellWithIdentifier("UpdateCell", forIndexPath: indexPath)
as UITableViewCell
println("successupdatecell")
cell.textLabel.text = postArray[indexPath.row][1]
cell.detailTextLabel?.text = postArray[indexPath.row][2]
println("success3")
return cell
}
Try this method
func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
...
}
Or you can do it straight in the storyboard by ctrl dragging the prototype cell to the next viewController.
Hope this helps!!
Edit
If you want to segue to the next view controller programmatically, then you can do either:
performSegueWithIdentifier("yourSegueName", sender: nil)
Or:
presentViewController(nextViewController, animated: true, completion: nil)

Resources