I have UIImage View (post image), label(post title), UIWebView(post content),
and I have this code to parse wordpress JSON posts to my app
func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
var maindata = (data[indexPath.row] as! NSDictionary)
theTitle = (maindata["post_title"] as? String)!
theImg = (maindata["image"] as? String)!
theDate = (maindata["post_date_gmt"] as? String)!
theBody = (maindata["post_content"] as? String)!
}
and I have installed JSON Api plugin on my wordpress,
but I don't know how to parse to my app ??
this is my whole code
import UIKit
import Haneke
var theTitle = ""
var theImg = ""
var theDate = ""
var theBody = ""
class ViewController: UIViewController , UITableViewDataSource , UITableViewDelegate {
#IBOutlet var myTable: UITableView!
// to refresh with pull down
var ref:UIRefreshControl?
// to refresh with pull down
var data = []
var prog:MBProgressHUD!
override func viewDidLoad()
{
super.viewDidLoad()
// to refresh with pull down
self.ref = UIRefreshControl()
self.ref?.attributedTitle = NSAttributedString(string: "اسحب للأسفل للتحديث")
self.ref?.addTarget(self, action: "ref:", forControlEvents: UIControlEvents.ValueChanged)
// to refresh with pull down
myTable.addSubview(self.ref!)
var heloWorldTimer = NSTimer.scheduledTimerWithTimeInterval(0.0001, target: self, selector: Selector("sayHello"), userInfo: nil, repeats: false)
myTable.backgroundColor = UIColor.clearColor()
myTable.dataSource = self
myTable.delegate = self
}
// to refresh with pull down
func ref (sender:UIRefreshControl)
{
self.myTable.reloadData()
self.ref?.endRefreshing()
}
// to refresh with pull down
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
func dataJsonFromURL(url:String)->NSArray
{
if var data = NSData(contentsOfURL: NSURL(string: url)!) {
return (NSJSONSerialization.JSONObjectWithData(data, options: nil, error: nil) as! NSArray)
}
else {
return data
}
}
}
func dataJsonFromURL(url:String)->NSArray
{
var data = NSData(contentsOfURL: NSURL(string: url)!)
return (NSJSONSerialization.JSONObjectWithData(data!, options: nil, error: nil) as! NSArray)
}
func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int
{
if data.count == 0 {
prog = MBProgressHUD.showHUDAddedTo(self.view, animated: true)
prog.labelText = "جاري تحميل البيانات"
prog.detailsLabelText = "الرجاء الإنتظار"
return 0
}
else
{ MBProgressHUD.hideAllHUDsForView(self.view, animated: true)
return data.count
}
}
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell
{
let cell = myTable.dequeueReusableCellWithIdentifier("NCell", forIndexPath: indexPath) as!
newsCell
var maindata = (data[indexPath.row] as! NSDictionary)
cell.selectionStyle = UITableViewCellSelectionStyle.None
cell.titleNews!.text = maindata["post_title"] as? String
cell.dateNews!.text = maindata["post_date_gmt"] as? String
if var urlImg = NSURL(string: (maindata["image"] as? String)!)
{
cell.imgNews.hnk_setImageFromURL(urlImg, placeholder: nil, format:nil, failure:nil, success:nil)
}
cell.backgroundColor = UIColor.clearColor()
return cell
}
#IBAction func rfreshB(sender: UIBarButtonItem) {
prog = MBProgressHUD.showHUDAddedTo(view, animated: true)
prog.labelText = "جاري تحميل البيانات"
prog.detailsLabelText = "الرجاء الإنتظار"
//data = dataJsonFromURL("http://hhz20.co/newstest/PhpFile/admin/show.php")
data = dataJsonFromURL("http://hhz20.co/testing/PhpFile/admin/show.php")
myTable.reloadData()
}
func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
var maindata = (data[indexPath.row] as! NSDictionary)
theTitle = (maindata["post_title"] as? String)!
theImg = (maindata["image"] as? String)!
theDate = (maindata["post_date_gmt"] as? String)!
theBody = (maindata["post_content"] as? String)!
}
func sayHello ()
{
data = dataJsonFromURL("http://hhz20.co/testing/PhpFile/admin/show.php")
myTable.reloadData()
}
}
Related
I tried to make ViewController with two TableView but meet the problem.
class FirstViewController: UIViewController, UITableViewDelegate, UITableViewDataSource {
#IBOutlet weak var tableTN: UITableView!
#IBOutlet weak var tableMainNews: UITableView!
var topnews: [TopNews]? = []
var mainnews: [Mainnewsfeed]? = []
override func viewDidLoad() {
super.viewDidLoad()
TopNewsJSON()
MainNewsJSON()
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell:UITableViewCell?
if tableView == self.tableTN {
cell = tableView.dequeueReusableCell(withIdentifier: "topnewsCell", for:indexPath) as! TopNewsCell
cell!.imgTN!.downloadImage(from: (self.topnews?[indexPath.item].image!)!)
cell!.titleTN!.text = self.topnews?[indexPath.item].headline
}
if tableView == self.tableMainNews {
cell = tableView.dequeueReusableCell(withIdentifier: "mainnewsCell", for:indexPath) as! MainNewsCell
cell!.mainnews_title!.text = self.mainnews?[indexPath.item].headline
}
return cell!
}
func numberOfSections(in tableView: UITableView) -> Int {
return 1
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
var count:Int?
if tableView == self.tableTN {
count = self.topnews!.count
}
if tableView == self.tableMainNews {
count = self.mainnews!.count
}
return count!
}
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
//print(indexPath)
}
func TopNewsJSON () {
let urlRequest = URLRequest(url: URL(string: "https://sportarena.com/wp-api/topnews2018/top/")!)
let task = URLSession.shared.dataTask(with: urlRequest) { (data,response,error) in
if error != nil {
print(error as Any)
return
}
self.topnews = [TopNews]()
do {
let json = try JSONSerialization.jsonObject(with: data!, options: .mutableContainers) as! [String : AnyObject]
//print(json)
let TN = TopNews()
let jarray = json["top-news"] as! NSArray
let jarray1 = jarray[0] as? [String: AnyObject]
if let ID = jarray1!["ID"] as? String,
let title = jarray1!["title"] as? String,
let img = jarray1!["img"] as? String {
TN.headline = title
TN.image = img
TN.id = ID
}
self.topnews?.append(TN)
DispatchQueue.main.async {
self.tableTN.reloadData()
}
} catch let error {
print(error)
}
}
task.resume()
}
func MainNewsJSON () {
let urlRequest = URLRequest(url: URL(string: "anyurl")!)
let task = URLSession.shared.dataTask(with: urlRequest) { (data,response,error) in
if error != nil {
print(error as Any)
return
}
//self.mainnews = [MainNews]()
do {
let json = try JSONSerialization.jsonObject(with: data!, options: .mutableContainers) as! [String : AnyObject]
let jarray = json["general-news"] as! NSArray
let jarray1 = jarray[0]
for jarray1 in jarray1 as! [[String: Any]] {
let MNF = Mainnewsfeed()
if let ID = jarray1["id"],
let title = jarray1["title"],
let time = jarray1["datetime"] {
MNF.headline = title as? String
MNF.id = ID as? String
MNF.time = time as? String
}
self.mainnews?.append(MNF)
DispatchQueue.main.async {
self.tableMainNews.reloadData()
}
}
} catch let error {
print(error)
}
}
task.resume()
}
}
}
After three lines as cell!.titleTN!.text = self.topnews?[indexPath.item].headline and others display error: "Value of type 'UITableViewCell' has no member 'titleTN'" (or also 'imgTN' and 'mainnews_title')
Where the error? What I need to change in my code?
Please help me.
You can try
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
if tableView == self.tableTN {
let cell = tableView.dequeueReusableCell(withIdentifier: "topnewsCell", for:indexPath) as! TopNewsCell
cell.imgTN!.downloadImage(from: (self.topnews?[indexPath.item].image!)!)
cell.titleTN!.text = self.topnews?[indexPath.item].headline
return cell
}
else
{
let cell = tableView.dequeueReusableCell(withIdentifier: "mainnewsCell", for:indexPath) as! MainNewsCell
cell.mainnews_title!.text = self.mainnews?[indexPath.item].headline
return cell
}
}
I'm having a problem regarding a feature where You can delete a cell and so delete and event using an Alamofire JSON request.
When I swipe the cell and click delete, the app crashes, but the event get deleted successfully and with no errors, in facts on Laravel side I get the event deleted.
I tried everything, but I really can't figure out how to fix the crash.
Can someone help me please?
here is my .Swift code:
import UIKit
import Alamofire
class EventViewController: UITableViewController {
#objc var transition = ElasticTransition()
#objc let lgr = UIScreenEdgePanGestureRecognizer()
#objc let rgr = UIScreenEdgePanGestureRecognizer()
let rc = UIRefreshControl()
#IBOutlet weak var myTableView: UITableView!
var myTableViewDataSource = [NewInfo]()
let url = URL(string: "http://ns7records.com/staffapp/api/events/index")
override func viewDidLoad() {
super.viewDidLoad()
loadList()
// Add Refresh Control to Table View
if #available(iOS 10.0, *) {
tableView.refreshControl = rc
} else {
tableView.addSubview(rc)
}
// Configure Refresh Control
rc.addTarget(self, action: #selector(refreshTableData(_:)), for: .valueChanged)
let attributesRefresh = [kCTForegroundColorAttributeName: UIColor.white]
rc.attributedTitle = NSAttributedString(string: "Caricamento ...", attributes: attributesRefresh as [NSAttributedStringKey : Any])
DispatchQueue.main.async {
}
// MENU Core
// customization
transition.sticky = true
transition.showShadow = true
transition.panThreshold = 0.3
transition.transformType = .translateMid
// menu// gesture recognizer
lgr.addTarget(self, action: #selector(MyProfileViewController.handlePan(_:)))
rgr.addTarget(self, action: #selector(MyProfileViewController.handleRightPan(_:)))
lgr.edges = .left
rgr.edges = .right
view.addGestureRecognizer(lgr)
view.addGestureRecognizer(rgr)
}
#objc private func refreshTableData(_ sender: Any) {
// Fetch Table Data
//myTableViewDataSource.removeAll()
tableView.reloadData()
loadList()
}
func loadList(){
var myNews = NewInfo()
// URLSession.shared.dataTask(with: url!, completionHandler: { (data, response, error) in
//
// })
let task = URLSession.shared.dataTask(with:url!) {
(data, response, error) in
if error != nil
{
print("ERROR HERE..")
}else
{
do
{
if let content = data
{
let myJson = try JSONSerialization.jsonObject(with: content, options: .mutableContainers)
//print(myJson)
if let jsonData = myJson as? [String : Any]
{
if let myResults = jsonData["data"] as? [[String : Any]]
{
//dump(myResults)
for value in myResults
{
if let myTitle = value["title"] as? String
{
//print(myTitle)
myNews.displayTitle = myTitle
}
if let myLocation = value["local"] as? String
{
myNews.location = myLocation
}
if let myDate = value["date"] as? String
{
myNews.date = myDate
}
if let myDescription = value["description"] as? String
{
myNews.description = myDescription
}
if let myCost = value["cost"] as? String
{
myNews.cost = myCost
}
if let myNumMembers = value["num_members"] as? String
{
myNews.num_members = myNumMembers
}
if let myNumMembers_conf = value["num_members_confirmed"] as? String
{
myNews.num_members_confirmed = myNumMembers_conf
}
if let myStartEvent = value["time_start"] as? String
{
myNews.startEvent = myStartEvent
}
if let myEndEvent = value["time_end"] as? String
{
myNews.endEvent = myEndEvent
}
if let myId = value["id"] as? Int
{
myNews.idEvent = myId
}
//x img
// if let myMultimedia = value["data"] as? [String : Any]
// {
if let mySrc = value["event_photo"] as? String
{
myNews.event_photo = mySrc
print(mySrc)
}
self.myTableViewDataSource.append(myNews)
}//end loop
dump(self.myTableViewDataSource)
DispatchQueue.main.async
{
self.tableView.reloadData()
self.rc.endRefreshing()
}
}
}
}
}
catch{
}
}
}
task.resume()
}
override func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath)->CGFloat {
return 150
}
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return myTableViewDataSource.count
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let myCell = tableView.dequeueReusableCell(withIdentifier: "reuseCell", for: indexPath)
let myImageView = myCell.viewWithTag(11) as! UIImageView
let myTitleLabel = myCell.viewWithTag(12) as! UILabel
let myLocation = myCell.viewWithTag(13) as! UILabel
let DateLabelCell = myCell.viewWithTag(14) as! UILabel
let numMembLabel = myCell.viewWithTag(15) as! UILabel
let numMembConfLabel = myCell.viewWithTag(16) as! UILabel
myTitleLabel.text = myTableViewDataSource[indexPath.row].displayTitle
myLocation.text = myTableViewDataSource[indexPath.row].location
DateLabelCell.text = myTableViewDataSource[indexPath.row].date
numMembLabel.text = myTableViewDataSource[indexPath.row].num_members
numMembConfLabel.text = myTableViewDataSource[indexPath.row].num_members_confirmed
if let imageURLString = myTableViewDataSource[indexPath.row].event_photo,
let imageURL = URL(string: AppConfig.public_server + imageURLString) {
myImageView.af_setImage(withURL: imageURL)
}
return myCell
}
//per passare da un viewcontroller a detailviewcontroller
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if let destination = segue.destination as? EventDetailViewController {
destination.model = myTableViewDataSource[(tableView.indexPathForSelectedRow?.row)!]
// Effetto onda
let vc = segue.destination
vc.transitioningDelegate = transition
vc.modalPresentationStyle = .custom
}
//menu
if let vc = segue.destination as? MenuViewController{
vc.transitioningDelegate = transition
vc.modalPresentationStyle = .custom
//endmenu
}
}
//menu slide
#objc func handlePan(_ pan:UIPanGestureRecognizer){
if pan.state == .began{
transition.edge = .left
transition.startInteractiveTransition(self, segueIdentifier: "menu", gestureRecognizer: pan)
}else{
_ = transition.updateInteractiveTransition(gestureRecognizer: pan)
}
}
//endmenuslide
////ximg
func loadImage(url: String, to imageView: UIImageView)
{
let url = URL(string: url )
URLSession.shared.dataTask(with: url!) { (data, response, error) in
guard let data = data else
{
return
}
DispatchQueue.main.async
{
imageView.image = UIImage(data: data)
}
}.resume()
}
/// star to: (x eliminare row e x muove row)
override func tableView(_ tableView: UITableView, moveRowAt sourceIndexPath: IndexPath, to destinationIndexPath: IndexPath) {
let movedObjTemp = myTableViewDataSource[sourceIndexPath.item]
myTableViewDataSource.remove(at: sourceIndexPath.item)
myTableViewDataSource.insert(movedObjTemp, at: destinationIndexPath.item)
}
override func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCellEditingStyle, forRowAt indexPath: IndexPath) {
if (editingStyle == .delete){
// print(parameters)
let idEvent = (myTableViewDataSource[indexPath.item].idEvent)
let parameters = [
// "id": UserDefaults.standard.object(forKey: "userid")! ,
"id" : idEvent,
] as [String : Any]
let url = "http://www.ns7records.com/staffapp/public/api/deleteevent"
print(url)
Alamofire.request(url, method:.post, parameters:parameters,encoding: JSONEncoding.default).responseJSON { response in
switch response.result {
case .success:
print(response)
let JSON = response.result.value as? [String : Any]
//self.myTableView.reloadData()
let alert = UIAlertController(title: "Yeah!", message: "Evento modificato con successo!", preferredStyle: UIAlertControllerStyle.alert)
alert.addAction(UIAlertAction(title: "OK", style: UIAlertActionStyle.destructive, handler: nil))
self.present(alert, animated: true, completion: nil)
// let data = JSON! ["data"] as! NSDictionary
if let jsonData = JSON as? [String : Any]
{
print(jsonData)
self.myTableViewDataSource.remove(at : indexPath.item)
self.myTableView.deleteRows(at: [indexPath], with: .automatic)
let indexPath = IndexPath(item: 0, section: 0)
//self.myTableView.deleteRows(at: [indexPath], with: .fade)
//self.myTableView.reloadData()
// }
// }
//}
}
case .failure(let error):
print(error)
let alert = UIAlertController(title: "Aia", message: "Non puoi cancellare questo evento!", preferredStyle: UIAlertControllerStyle.alert)
alert.addAction(UIAlertAction(title: "OK", style: UIAlertActionStyle.destructive, handler: nil))
self.present(alert, animated: true, completion: nil)
}
}
}
}
#IBAction func EditButtonTableView(_ sender: UIBarButtonItem) {
self.myTableView.isEditing = !self.myTableView.isEditing
sender.title = (self.myTableView.isEditing) ? "Done" : "Edit"
}
/// end to: (x eliminare row e x muove row)
}
// MARK: -
// MARK: UITableView Delegate
extension ViewController: UITableViewDelegate {
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
tableView.deselectRow(at: indexPath, animated: true)
}
}
Here is my project on github:
https://github.com/alshfu86/Recipes
I have one problem. If I remove something from my Firebase database I get this error:
Could not cast value of type ‘NSNull’ (0×106a4f520) to ‘NSDictionary’ (0×106a4ef58).
in method:
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "CategoryCell", for:indexPath) as! CategoryTableViewCell
let rowData = self.data[indexPath.row] as! NSDictionary
let title = rowData["title"] as! String
cell.recipeLabel.text = title.uppercased()
let imageUrl = rowData["youtubeID"] as! String
let imageQuality = rowData["imageQuality"] as! String
let urlPath = youtubeBaseImageURL + imageUrl + "/" + imageQuality + ".jpg"
let url = URL(string: urlPath)
cell.recipeImageView.kf.setImage(with: url)
print("uString(describing: rl )path = \(String(describing: url))")
return cell
}
here is all class:
import UIKit
import Kingfisher
class CategoryViewController: UIViewController,UITableViewDataSource,UITableViewDelegate {
var data = [Any]()
var categoryTitle = ""
let youtubeBaseImageURL = "http://img.youtube.com/vi/"
#IBOutlet weak var tableView: UITableView!
//is the device landscape or portrait
var isPortraid = true
override func viewDidLoad() {
super.viewDidLoad()
let backButton = UIBarButtonItem(image: UIImage(named:"chevron"), style: UIBarButtonItemStyle.plain, target: self, action: #selector(back))
self.navigationItem.leftBarButtonItem = backButton
self.tableView.delegate = self
self.title = categoryTitle
print("data: \(self.data)")
// loadAdmobBanner()
NotificationCenter.default.addObserver(self, selector: #selector(MainViewController.orientationChanged), name: NSNotification.Name.UIDeviceOrientationDidChange, object: nil)
if UIDevice.current.orientation.isLandscape {
isPortraid = false
}
}
func orientationChanged(){
if UIDevice.current.orientation.isLandscape {
isPortraid = false
} else {
isPortraid = true
}
tableView.reloadData()
}
#objc func back(){
self.navigationController?.popViewController(animated: true)
}
func numberOfSections(in tableView: UITableView) -> Int {
return 1
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return data.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "CategoryCell", for:indexPath) as! CategoryTableViewCell
let rowData = self.data[indexPath.row] as! NSDictionary
let title = rowData["title"] as! String
cell.recipeLabel.text = title.uppercased()
let imageUrl = rowData["youtubeID"] as! String
let imageQuality = rowData["imageQuality"] as! String
let urlPath = youtubeBaseImageURL + imageUrl + "/" + imageQuality + ".jpg"
let url = URL(string: urlPath)
cell.recipeImageView.kf.setImage(with: url)
print("uString(describing: rl )path = \(String(describing: url))")
return cell
}
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
let storyboard = UIStoryboard(name: "Main", bundle: Bundle.main)
let playerViewController = storyboard.instantiateViewController(withIdentifier: "PlayerViewController") as! PlayerViewController
let rowData = self.data[indexPath.row] as! NSDictionary
let youtubeUrl = rowData["youtubeID"] as! String
playerViewController.urlPath = youtubeUrl
let ingredients = rowData["ingredients"] as! String
playerViewController.about = ingredients
self.navigationController?.pushViewController(playerViewController, animated: true)
}
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
if isPortraid {return UIScreen.main.bounds.height/5
} else {
return UIScreen.main.bounds.height/5.2
}
}
#IBAction func unwindToCategory(sender: UIStoryboardSegue){
}
The error must be on this line:
let rowData = self.data[indexPath.row] as! NSDictionary
The error is that the array contains some null values (represented as NSNull). You should probably do a conditional cast, i.e.:
if let rowData = self.data[indexPath.row] as? NSDictionary {
// do stuff here
}
Or alternatively, declare data as an array of dictionaries:
var data = [NSDictionary]()
then filter out the null values before assigning them to data:
self.data = yourdatasource.filter { $0 is NSDictionary }
Then later simply retrieve the element:
let rowData = self.data[indexPath.row] // do stuff here
I am working on a project to shows news feeds to the user.
I am calling a function getNewsFeeds() to get news feeds.
I will generate new newsfeeds every one hour
ViewDidLoad(){
get current time in "HH" format and store it in currentTime
Store this currentTime in to a HoursVar variable using UserDefaults
}
ViewDidAppear(){
if( currentTime - HoursVar >= 1){
getNewsFeeds
}else{
}
retreiveStoredValuesFromUserDeafults()
}
I dont know where exactly to setup my tableViewDataSOurce and Delegate methods and reloadData to populate the tableView when getting data from the saved Userdefaults retreiveStoredValuesFromUserDeafults()
override func viewDidLoad() {
super.viewDidLoad()
hoursFormatter.dateFormat = "HH"
hoursVar = Int(hoursFormatter.string(from: hours))!
if hoursVar > 12 {
hoursVar = hoursVar - 12
}
self.defaults.set(self.hoursVar, forKey: "hoursVar")
customNavBar()
self.view.addGestureRecognizer(self.revealViewController().panGestureRecognizer())
feedsArray = ["Reliance","Economy"]
}
override func viewDidAppear(_ animated: Bool) {
//getRssFeeds()
if((hoursVar - myHoursVar) == 1 && (hoursVar - myHoursVar) > 1){
getRssFeeds()
}else{
feedsTable.register(UITableViewCell.self, forCellReuseIdentifier: "newsFeeds")
self.feedsTable.delegate = self
self.feedsTable.dataSource = self
retreiveMyArrayData()
feedsTableView.reloadData()
}
}
func getRssFeeds(){
for i in 0..<feedsArray.count{
let url = URL(string: "https://api.cognitive.microsoft.com/bing/v5.0/news/search?q=\(feedsArray[i])&count=3&mkt=en-in")
var request = URLRequest(url: url!)
request.setValue("My Subscription Key", forHTTPHeaderField: "Ocp-Apim-Subscription-Key")
Alamofire.request(request as URLRequest).responseJSON{response in
if let json = response.result.value as? [String:AnyObject]{
if let value = json["value"]{
//
print("json \(json)")
for j in 0..<value.count{
let items = value[j] as! [String:AnyObject]
let name = items["name"] as! String
let url = items["url"] as! String
let description = items["description"] as! String
let datePublished = items["datePublished"] as! String
let dateAndTime = datePublished.replacingOccurrences(of: "T", with: " ")
self.feedsName.append(name)
self.feedsUrl.append(url)
self.feedsDescription.append(description)
self.feedsDatePublished.append(dateAndTime)
if let image = items["image"] as? [String:AnyObject]{
if let thumbnail = image["thumbnail"] as? [String:AnyObject]{
let contentUrl = thumbnail["contentUrl"] as! String
self.feedsContentUrl.append(contentUrl)
}
}else{
self.feedsContentUrl.append(self.errorImage)
}
if let provider = items["provider"]{
for i in 0..<provider.count{
let items = provider[i] as! [String:AnyObject]
let providerName = items["name"] as! String
self.feedsProvider.append(providerName)
}
}
self.feedsTable.delegate = self
self.feedsTable.dataSource = self
self.feedsTable.reloadData()
self.defaults.set(self.feedsUrl, forKey: "feedsUrl")
self.defaults.set(self.feedsDescription, forKey: "feedsDescription")
self.defaults.set(self.feedsName, forKey: "feedsName")
self.defaults.set(self.feedsProvider, forKey: "feedsProvider")
self.defaults.set(self.feedsContentUrl, forKey: "feedsContentUrl")
self.defaults.set(self.feedsDatePublished, forKey: "feedsDatePublished")
print("All Counts \(self.feedsName.count)")
}
}
}
}
}
}
func slideOpen(){
self.revealViewController().revealToggle(animated: true)
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return feedsName.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "newsFeeds") as! newsFeeds
randomNumberArray = randomNumber()
//self.feedsRandomArray.append(self.feedsRandom)
print("feedsRandom \(feedsRandom)")
selectedRow = randomNumberArray[indexPath.row]
let url = URL(string: feedsContentUrl[randomNumberArray[indexPath.row]])
do{
let data = try Data(contentsOf: url!)
cell.feedsImage.image = UIImage(data: data )
}catch{
print(error)
}
let tap = UITapGestureRecognizer(target: self, action: #selector(HomeViewController.tapFunction))
let titleAttributes = [NSFontAttributeName: UIFont.preferredFont(forTextStyle: UIFontTextStyle.headline), NSForegroundColorAttributeName: UIColor.purple]
let titleString = NSAttributedString(string: feedsName[randomNumberArray[indexPath.row]] , attributes: titleAttributes)
cell.feedsHeadlines.isUserInteractionEnabled = true
cell.feedsHeadlines.addGestureRecognizer(tap)
cell.feedsHeadlines.attributedText = titleString
cell.feedsDescription.text = feedsDescription[randomNumberArray[indexPath.row]]
cell.feedsPublisherName.text = feedsProvider[randomNumberArray[indexPath.row]]
cell.publishedOn.text = feedsDatePublished[randomNumberArray[indexPath.row]]
//print("All Counts \(myFeedsName.count) \(myFeedsProvider.count) \(myFeedsContentUrl.count) \(myFeedsUrl.count) \(myFeedsDescription.count) \(myFeedsDescription.count)")
return cell
}
func tapFunction(sender:UITapGestureRecognizer) {
let safariVC = SFSafariViewController(url: NSURL(string: feedsUrl[selectedRow]) as! URL)
self.present(safariVC, animated: true, completion: nil)
safariVC.delegate = self
}
func safariViewControllerDidFinish(_ controller: SFSafariViewController) {
controller.dismiss(animated: true, completion: nil)
}
func randomNumber() -> [Int] {
let feedsIndex = feedsName.count - 1
var randomNumber = Int(arc4random_uniform(UInt32(feedsIndex)))
print("Randome number \(randomNumber) \(randomNumberArray)")
for k in 0..<randomNumberArray.count{
while randomNumber == randomNumberArray[k] {
randomNumber = Int(arc4random_uniform(UInt32(feedsIndex)))
}
}
randomNumberArray.append(randomNumber)
self.defaults.set(self.randomNumberArray, forKey: "randomNumberArray")
return randomNumberArray
}
func retreiveMyArrayData(){
myFeedsUrl = defaults.stringArray(forKey: "feedsUrl") ?? [String]()
myFeedsDescription = defaults.stringArray(forKey: "feedsDescription") ?? [String]()
myFeedsName = defaults.stringArray(forKey: "feedsName") ?? [String]()
myFeedsProvider = defaults.stringArray(forKey: "feedsProvider") ?? [String]()
myFeedsContentUrl = defaults.stringArray(forKey: "feedsContentUrl") ?? [String]()
myFeedsDatePublished = defaults.stringArray(forKey: "feedsDatePublished") ?? [String]()
myHoursVar = defaults.integer(forKey: "hoursVar")
myFeedsRandom = defaults.array(forKey: "randomNumberArray") as! [Int]
print("Values \(myHoursVar) \(myFeedsProvider) \(myFeedsUrl.count)")
}
You can set UITableViewDataSourceand UITableViewDelegate into .xib
//Setting datasource & delegate for tableview inside viewDidLoad
override func viewDidLoad() {
super.viewDidLoad()
self.feedsTableView.delegate = self
self.feedsTableView.datasource = self
}
Now, you need to reload the tableview when you setValue & retrieve the value to the userDefaults. self.feedsTableView.reloadData()
If this didn't helped you, please let me know. I'll work more to provide you with a complete workflow for the above project.
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
}
}