I'm trying to parse XML with XMLParser and put it on a PickerView. This is my code:
Main code:
import UIKit
class ViewController: UIViewController, XMLParserDelegate {
#IBOutlet weak var containerView: UIView!
#IBOutlet weak var pickerView: UIPickerView!
#IBOutlet weak var Image: UIImageView!
#IBOutlet weak var Button: UIButton!
var arrayCategorias = [Categories]()
var parser = XMLParser()
override func viewDidLoad() {
super.viewDidLoad()
let urlString = URL(string: "http://thecatapi.com/api/categories/list")
self.parser = XMLParser(contentsOf: urlString!)!
let success:Bool = self.parser.parse()
parser.delegate = self
if success {
print("success")
} else {
print("parse failure!")
}
print(arrayCategorias.count)
}
#IBAction func botonPulsado(_ sender: Any) {
}
func parser(_ parser: XMLParser, didStartElement elementName: String, namespaceURI: String?, qualifiedName qName: String?, attributes attributeDict: [String : String]) {
if(elementName=="category")
{
let categoria = Categories()
for string in attributeDict {
let strvalue = string.value as NSString
switch string.key {
case "id":
categoria.id = strvalue.integerValue
break
case "name":
categoria.name = strvalue as String
break
default:
break
}
}
arrayCategorias.append(categoria)
}
func parser(_ parser: XMLParser, didEndElement elementName: String, namespaceURI: String?, qualifiedName qName: String?) {
}
func parser(_ parser: XMLParser, foundCharacters string: String) {
}
func parser(_ parser: XMLParser, parseErrorOccurred parseError: Error) {
print("failure error: ", parseError)
}
}
}
Class Categories Code:
import Foundation
class Categories{
var id: Int = 0
var name: String = ""
}
I don't know exactly what the problem is, but when I try to read arrayCategorias() just to see if there is any data, it just shows me 0. And where I catch the error, it shows me: "parse failure".
If anyone can help me, I'm just an android programmer and I don't know why it doesn't work.
I need help with putting the data on the PickerView.
There are a whole bunch of issues:
You have set your delegate after you parsed, whereas you must do this before you call parse().
You have some of your delegate methods implemented inside didStartElement. These need to be top level methods of your parser delegate.
Minor unrelated issue, but your class name of Categories isn't quite right, because it represents a single "category", not many. So I'd rename this to be Category. (I'd personally also make it a struct, but that's up to you.)
Your id and name values are not attributes of the category element. They are their own elements, so you have to parse them separately (using foundCharacters and build the Category object on didEndElement of category.
The id of the categories appears to be an integer, so I'd make the id of Category an Int.
You're calling parse() of a XMLParser that is using a URL from the main thread. That's inadvisable because you're blocking the main thread while it does the request. Personally, I'd use URLSession to request the data asynchronously, process it on a background queue, and only dispatch the final update of the model object and UI update to the main queue.
Personally, I'd adopt asynchronous patterns myself with #escaping completion handlers, to help isolate UI updates that I trigger after a parse from the parsing itself
A stylistic matter, but I wouldn't put all of this XMLParserDelegate code in the view controller. At the very least, put it in an extension so it's nicely organized. Even better, define a stand-alone parser delegate object in the spirit of the single responsibility principle and ensuring that you're not accidentally updating view controller model objects while the UI might be referring to it. It more safely ensures thread-safety and keeps your code more nicely encapsulated.
Pulling this all together, you could do something like:
struct Category {
let id: Int
let name: String
}
class ViewController: UIViewController {
#IBOutlet weak var pickerView: UIPickerView!
var categories = [Category]()
override func viewDidLoad() {
super.viewDidLoad()
startRequestAndParse() { categories, error in
guard let categories = categories, error == nil else {
print(error?.localizedDescription ?? "Unknown error")
return
}
// if you got here, everything is OK, so update model and UI on main thread
DispatchQueue.main.async {
self.categories = categories
print(self.categories)
// trigger whatever UI update you want here, too;
self.pickerView.reloadAllComponents()
}
}
}
/// Initiate request from server and parse results
///
/// - Parameters:
/// - completion: This is called when the request/parsing is done. This may be called
/// on background thread. If parsing failed, the array of categories
/// will be `nil` and we should have `error`.
/// - categories: First parameter of the `completion` closure is the array of `Category` objects, or `nil` on error.
/// - error: Second parameter of the `completion` closure is the resulting `Error`, if any.
private func startRequestAndParse(completion: #escaping (_ categories: [Category]?, _ error: Error?) -> Void) {
let url = URL(string: "http://thecatapi.com/api/categories/list")!
let task = URLSession.shared.dataTask(with: url) { data, _, error in
guard let data = data, error == nil else {
completion(nil, error)
return
}
// ok, now parse
let parser = XMLParser(data: data)
let delegate = ParserDelegate()
parser.delegate = delegate
parser.parse()
completion(delegate.categories, parser.parserError)
}
task.resume()
}
}
// this assumes you set the picker's `delegate` to be the view controller (either in IB or programmatically in `viewDidLoad`
extension ViewController: UIPickerViewDelegate {
func pickerView(_ pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String? {
return categories[row].name
}
}
// this assumes you set the picker's `dataSource` to be the view controller (either in IB or programmatically in `viewDidLoad`
extension ViewController: UIPickerViewDataSource {
func numberOfComponents(in pickerView: UIPickerView) -> Int {
return 1
}
func pickerView(_ pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int {
return categories.count
}
}
/// Parser delegate for categories
class ParserDelegate: NSObject, XMLParserDelegate {
private var id: Int?
private var name: String?
private var value: String?
var categories: [Category]?
// initialize `categories`
func parserDidStartDocument(_ parser: XMLParser) {
categories = []
}
// if `id` or `name`, initialize `value` so we'll capture the appropriate value
func parser(_ parser: XMLParser, didStartElement elementName: String, namespaceURI: String?, qualifiedName qName: String?, attributes attributeDict: [String : String]) {
if elementName == "id" || elementName == "name" {
value = ""
}
}
// if `value` is not `nil`, go ahead and concatenate the additional characters
func parser(_ parser: XMLParser, foundCharacters string: String) {
value? += string
}
// if `id` or `name`, update the appropriate property
// if `category`, build a `Category` object and add it to our array
// regardless, reset `value` to `nil`
func parser(_ parser: XMLParser, didEndElement elementName: String, namespaceURI: String?, qualifiedName qName: String?) {
switch elementName {
case "id":
if let value = value {
id = Int(value)
}
case "name":
name = value
case "category":
if let id = self.id, let name = self.name {
categories!.append(Category(id: id, name: name))
}
id = nil
name = nil
default:
()
}
value = nil
}
// if any error, reset `categories` so caller knows there was an issue
func parser(_ parser: XMLParser, parseErrorOccurred parseError: Error) {
categories = nil
}
}
Related
Here i am getting data in xml and i have retrieved into Dictionary to load in tableView. Work flow - When user in home screen and taps on create button and it takes to next search product screen there user can able their amazon products. searched product are loaded into table view cell.
My issue is when taps on create button tableView tries to load data and its getting crash
Crash line is results!.count.
Here is the code i tried:
var results: [[String: String]]?
var currentDictionary: [String: String]? // the current dictionary
var currentValue: String? // the current value for one of the
keys in the dictionary
let recordKey = "ItemAttributes"
let dictionaryKeys = Set<String>(["Title"])
func parserDidStartDocument(_ parser: XMLParser) {
results = []
}
// start element
//
// - If we're starting a "record" create the dictionary that will hold the results
// - If we're starting one of our dictionary keys, initialize `currentValue` (otherwise leave `nil`)
func parser(_ parser: XMLParser, didStartElement elementName: String, namespaceURI: String?, qualifiedName qName: String?, attributes attributeDict: [String : String]) {
if elementName == recordKey {
currentDictionary = [:]
} else if dictionaryKeys.contains(elementName) {
currentValue = ""
}
}
// found characters
//
// - If this is an element we care about, append those characters.
// - If `currentValue` still `nil`, then do nothing.
func parser(_ parser: XMLParser, foundCharacters string: String) {
currentValue? += string
}
// end element
//
// - If we're at the end of the whole dictionary, then save that dictionary in our array
// - If we're at the end of an element that belongs in the dictionary, then save that value in the dictionary
func parser(_ parser: XMLParser, didEndElement elementName: String, namespaceURI: String?, qualifiedName qName: String?) {
if elementName == recordKey {
results!.append(currentDictionary!)
currentDictionary = nil
} else if dictionaryKeys.contains(elementName) {
currentDictionary![elementName] = currentValue
currentValue = nil
}
}
// Just in case, if there's an error, report it. (We don't want to fly blind here.)
func parser(_ parser: XMLParser, parseErrorOccurred parseError: Error) {
print(parseError)
currentValue = nil
currentDictionary = nil
results = nil
}
// func numberOfSectionsInTableView(tableView: UITableView) -> Int {
// return 1
// }
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return results!.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "Cell", for: indexPath as IndexPath) as! amazonProductListTableViewCell
let productlist = ProductName[indexPath.row]
print("prodic:::\(productlist)")
// cell.amazonProductTitle?.text = productlist[indexPath.row]
// cell.detailTextLabel?.text = book.bookAuthor
return cell
}
Never declare a table view datasource array as optional.
If numberOfRows is called before the array has been initialized the app crashes.
Declare results
var results = [[String: String]]()
In parserDidStartDocument as well as in parseErrorOccurred clear the array
results.removeAll()
Consider that every force unwrapped optional can cause a crash and you are using a lot of exclamation marks!
import UIKit
var operationViewFlag: Int!
var dataReceived: Int!
class HomeCellView: UITableViewCell
{
#IBOutlet weak var btn_tablecell_Delete: UIButton!
#IBOutlet weak var btn_tablecell_Edit: UIButton!
#IBOutlet weak var lbl_tablecell_Email: UILabel!
}
class ViewController: UIViewController,UITableViewDataSource,UITableViewDelegate, NSXMLParserDelegate
{
#IBOutlet weak var TableView_Mainscreen: UITableView!
#IBOutlet weak var lbl_MainScreen_Title: UILabel!
#IBOutlet weak var btn_Mainscreen_Insert: UIButton!
var databasepath:String!
var arrayStudInfo:NSMutableArray!
// for only xml parsing
var parser = NSXMLParser()
var posts = NSMutableArray()
var elements = NSMutableDictionary()
var element = NSString()
var title1 = NSMutableString()
var date = NSMutableString()
// viewDidLoad
override func viewDidLoad()
{
super.viewDidLoad()
arrayStudInfo = NSMutableArray()
self.beginParsing();
TableView_Mainscreen.reloadData()
}
//viewWillAppear
override func viewWillAppear(animated: Bool)
{
super.viewWillAppear(true)
TableView_Mainscreen.reloadData()
}
override func didReceiveMemoryWarning()
{
super.didReceiveMemoryWarning()
}
// TableView Methods
func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int
{
print("Number Of Row:\(posts.count)")
return posts.count
}
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell
{
let Cell = tableView.dequeueReusableCellWithIdentifier("CellHome") as! HomeCellView
print("Index path - > \(posts[indexPath.row])")
Cell.lbl_tablecell_Email.text! = String("\(posts[(indexPath.row)]["title"])")
return Cell
}
func parser(parser: NSXMLParser, didStartElement elementName: String, namespaceURI: String?, qualifiedName qName: String?, attributes attributeDict: [String : String])
{
element = elementName
print("element Name : - \(elementName)")
if (elementName as NSString).isEqualToString("item")
{
elements = NSMutableDictionary()
elements = [:]
title1 = NSMutableString()
title1 = ""
date = NSMutableString()
date = ""
}
}
func parser(parser: NSXMLParser, didEndElement elementName: String, namespaceURI: String?, qualifiedName qName: String?)
{
print("element Name : - \(elementName)")
if (elementName as NSString).isEqualToString("item")
{
if !title1.isEqual(nil) {
elements.setObject(title1, forKey: "Name")
}
if !date.isEqual(nil) {
elements.setObject(date, forKey: "Level")
}
posts.addObject(elements)
}
}
func parser(parser: NSXMLParser, foundCharacters string: String)
{
if element.isEqualToString("Name")
{
title1.appendString(string)
} else if element.isEqualToString("Level") {
date.appendString(string)
}
}
func beginParsing()
{
posts = []
parser = NSXMLParser(contentsOfURL:(NSURL(string:"http://d1xzuxjlafny7l.cloudfront.net/downloads/Party.xml"))!)!
parser.delegate = self
parser.parse()
}
func parserDidEndDocument(parser: NSXMLParser) {
TableView_Mainscreen.reloadData()
}
}
I want to display the result of the xml api in proper formate. I want to display the name from it, in table view. Right now i am not getting any data from this. First of all If will get any data then and then we can think to convert or arrange in any formate , but i am not getting any thing. will anybody please help for the same.
Edit:
Oh! I didn't check your XML thoroughly enough! In fact, it has nothing to do with the parser loading the data asynchronously (I'll leave my original hint regarding parserDidEndDocument below, though, you might need it once you implement a refresh feature).
Turns out you simply did not use the correct names, i.e. strings for the elements. Here's the corrected code:
In tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell (note I slightly changed how to get the string, otherwise you might get an ugly prefix in it)
...
let nameString = posts[(indexPath.row)]["Name"] as! String
Cell.lbl_tablecell_Email.text = nameString
...
In parser(parser: NSXMLParser, didStartElement elementName: String, namespaceURI: String?, qualifiedName qName: String?, attributes attributeDict: [String : String])
...
if (elementName as NSString).isEqualToString("Player")
...
In parser(parser: NSXMLParser, didEndElement elementName: String, namespaceURI: String?, qualifiedName qName: String?)
...
if (elementName as NSString).isEqualToString("Player")
...
In parser(parser: NSXMLParser, foundCharacters string: String) (note you seem to have a linebreak and some whitespaces in your XML, I cut that off)
...
if element.isEqualToString("Name") && !(string.hasPrefix("\n"))
...
I assume you didn't realize those string keys that identify the elements are actually just the element's name, basically. There's a couple of small things in your code that could be optimized and/or improved (for example you don't need to initialize some vars, since you just re-init them elsewhere before actual usage anyways, also the naming of variables).
I tried it out with the link you provided and it works now.
Gist of previous answer:
Implement
func parserDidEndDocument(parser: NSXMLParser) {
TableView_Mainscreen.reloadData()
}
so that you are guaranteed to reload the table's data after the parser is done parsing.
I am having an issue in which I am parsing a String value from an API and I am trying to assign it to an UILabel. I have tested updating the label in the exact same position as it is now by setting the label (lblNamedata) to a String using the format:
self.lblNameData.text = "hello"
and it has worked fine.
I currently have:
if success {
print("parse success!")
print(strXMLData)
dispatch_async(dispatch_get_main_queue(), { () -> Void in
self.lblNameData.text=self.strXMLData
})
} else {
print("parse failure!")
}
and this isn't working.
Below is my complete current code:
import UIKit
class ViewController: UIViewController,NSXMLParserDelegate {
var strXMLData:String = ""
var currentElement:String = ""
var passData:Bool=false
var passName:Bool=false
var parser = NSXMLParser()
#IBOutlet weak var lblNameData: UILabel!
override func viewDidLoad() {
super.viewDidLoad()
let url:String="http://www.stands4.com/services/v2/quotes.php?uid=idhere&tokenid=tokenhere&searchtype=xxxx&query=xxxx"
let urlToSend: NSURL = NSURL(string: url)!
// Parse the XML
parser = NSXMLParser(contentsOfURL: urlToSend)!
parser.delegate = self
let success:Bool = parser.parse()
if success {
print("parse success!")
print(strXMLData)
dispatch_async(dispatch_get_main_queue(), { () -> Void in
self.lblNameData.text=self.strXMLData
})
} else {
print("parse failure!")
}
}
func parser(parser: NSXMLParser, didStartElement elementName: String, namespaceURI: String?, qualifiedName qName: String?, attributes attributeDict: [String : String]) {
currentElement=elementName;
if(elementName=="quote" || elementName=="author" || elementName=="result")
{
if(elementName=="quote"){
passName=true;
}
passData=true;
}
}
func parser(parser: NSXMLParser, didEndElement elementName: String, namespaceURI: String?, qualifiedName qName: String?) {
currentElement="";
if(elementName=="quote" || elementName=="author" || elementName=="result")
{
if(elementName=="quote"){
passName=false;
}
passData=false;
}
}
func parser(parser: NSXMLParser, foundCharacters string: String) {
if(passName){
strXMLData=strXMLData+"\n\n"+string
}
if(passData)
{
// print(string)
print("work")
}
}
func parser(parser: NSXMLParser, parseErrorOccurred parseError: NSError) {
NSLog("failure error: %#", parseError)
}
}
UPDATE: So I believe I found the error: in my parser function I'm setting strXMLData = strXMLData + "\n\n" + string but after I delete the \n\n I can see that my label updates...why is this?
Alright, so after many instances of trial and error, I think I figured out the answer.
Something was up in my Main.storyboard that didn't like me creating multiple lines in the UILabel, so what I did was click on the label and navigated to the Attributes Inspector. I set the "Lines" parameter to 0 and I was able to see my text!
I am trying to parse a xml file direct from a URL the code has no errors, and the app opens fine but the tableview is empty. here is the link and the code I have used, if I can get some guidance it would be greatly appreciated.
I initially built this through a tutorial (just learning the ropes)
import UIKit
class firecallViewController: UIViewController, NSXMLParserDelegate{
#IBOutlet var tbData: UITableView?
var parser = NSXMLParser()
var posts = NSMutableArray()
var elements = NSMutableDictionary()
var element = NSString()
var title1 = NSMutableString()
var date = NSMutableString()
override func viewDidLoad()
{
super.viewDidLoad()
self.beginParsing()
}
func beginParsing()
{
posts = []
parser = NSXMLParser(contentsOfURL:(NSURL(string:"https://example.com/bushfirealert/bushfireAlert.xml"))!)!
parser.delegate = self
parser.parse()
tbData!.reloadData()
}
//XMLParser Methods
func parser(parser: NSXMLParser, didStartElement elementName: String, namespaceURI: String?, qualifiedName qName: String?, attributes attributeDict: [String : String])
{
element = elementName
if (elementName as NSString).isEqualToString("item")
{
elements = NSMutableDictionary()
elements = [:]
title1 = NSMutableString()
title1 = ""
date = NSMutableString()
date = ""
}
}
func parser(parser: NSXMLParser, didEndElement elementName: String, namespaceURI: String?, qualifiedName qName: String?)
{
if (elementName as NSString).isEqualToString("item") {
if !title1.isEqual(nil) {
elements.setObject(title1, forKey: "title")
}
if !date.isEqual(nil) {
elements.setObject(date, forKey: "date")
}
posts.addObject(elements)
}
}
func parser(parser: NSXMLParser, foundCharacters string: String)
{
if element.isEqualToString("title") {
title1.appendString(string)
} else if element.isEqualToString("pubDate") {
date.appendString(string)
}
}
func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int
{
return posts.count
}
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell
{
var cell : UITableViewCell = tableView.dequeueReusableCellWithIdentifier("Cell")!
if(cell.isEqual(NSNull)) {
cell = NSBundle.mainBundle().loadNibNamed("Cell", owner: self, options: nil)[0] as! UITableViewCell;
}
cell.textLabel?.text = posts.objectAtIndex(indexPath.row).valueForKey("title") as! NSString as String
cell.detailTextLabel?.text = posts.objectAtIndex(indexPath.row).valueForKey("date") as! NSString as String
return cell as UITableViewCell
}
}
Updated answer
You told me in the comments that you don't have to use NSXMLParser.
In this case, I have an easy solution for your parsing: use CheatyXML, a very simple library.
First, follow the easy install intructions.
Then make a parser with your URL:
import CheatyXML
let feedUrl = NSURL(string: "https://example.com/bushfirealert/bushfireAlert.xml")!
let parser = XMLParser(contentsOfURL: feedUrl)
And safely unwrap all values as if you were subscripting dictionaries, and use the .string property to get the string fields contents.
Like this:
if let parser = parser,
channel = parser["channel"],
title = channel["title"].string,
link = channel["link"].string,
description = channel["description"].string,
docs = channel["docs"].string,
generator = channel["generator"].string {
print(title)
print(link)
print(description)
print(docs)
print(generator)
}
Result:
QFES Current Incidents
http://bneags01.desqld.internal/publicfeed/PublicRssFeed.aspx
QFES Current Incidents
http://www.rssboard.org/rss-specification
Argotic Syndication Framework
Now instead of my series of print you call a method of yours to populate your variables and then you reload the table view, and you're set.
Old answer
NSXMLParser works asynchronously, so when you reload your table in beginParsing(), the data is not parsed yet.
You need to reload the table when the parser has finished parsing.
Luckily, there's a callback for that.
Remove tbData!.reloadData() from beginParsing() and add this delegate method to your view controller instead:
func parserDidEndDocument(parser: NSXMLParser) {
tbData!.reloadData()
}
pretty new at swift. Currently, I have a program where on the click of a button I make an NSURL request, take that response, parse the XML, and store the data I need into a array[String]. Pressing this button also serves as a segue into a table view controller which will be dynamically populated with the info from the array.
What I'm seeing is that the segue is occurring and the next VC is being passed an empty array before my request is even complete and response is parsed. (this is all based on the print statements I've inserted in just about every other line to track the execution of my code).
How can I go about this so that the segue does not take me to the next VC until my response has been parsed?
class start: UIViewController, NSURLConnectionDelegate, NSXMLParserDelegate {
var timeArr:[String] = []
var url = "myurl.com"
#IBOutlet weak var get2: UIButton!
#IBAction func getAction(sender: UIButton) {
var request = NSMutableURLRequest(URL: NSURL(string: url)!)
httpGet (request) {
(data, error) -> Void in
if error != nil {
print(error)
mainInstance.arrivalArr.append("no arrival times")
} else {
self.beginParsing()
print(data)
}
}
}
func httpGet(request: NSURLRequest!, callback: (String, String?) -> Void) {
var session = NSURLSession.sharedSession()
var task = session.dataTaskWithRequest(request){
(data, response, error) -> Void in
if error != nil {
callback("", error!.localizedDescription)
} else {
var result = NSString(data: data!, encoding:
NSUTF8StringEncoding)!
self.data2 = data!
callback(result as String, nil)
}
}
task.resume()
}
func beginParsing()
{
posts = []
parser = NSXMLParser(data: data2)
parser.delegate = self
parser.parse()
}
func parser(parser: NSXMLParser, didStartElement elementName: String, namespaceURI: String?, qualifiedName qName: String?, attributes attributeDict: [String : String])
{
element = elementName
if (elementName as NSString).isEqualToString("prd")
{
// more code
}
}
func parser(parser: NSXMLParser, foundCharacters string: String)
{
if element.isEqualToString("prdtm") {
//code
}
}
func parser(parser: NSXMLParser, didEndElement elementName: String, namespaceURI: String?, qualifiedName qName: String?)
{
if (elementName as NSString).isEqualToString("prd") {
if !title1.isEqual(nil) {
//code
}
//code
finalTimeStr = getTime(finalTimeStr)
timeArr.append(finalTimeStr)
}
}
func getTime (time: String) -> String{
var arrivalTime = time
//code to trim and format time here
var timeA = getTimeDiff(arrivalTime)
timeA = trimToMin(timeA)
return timeA
}
func trimToMin (timeToTrim : String) -> String {
var timeInMin = timeToTrim
//code to trim to minutes
return substring2
}
func getTimeDiff (time: String) -> String{
//code to find time difference
let ret = stringFromTimeInterval(diff)
return ret
}
func stringFromTimeInterval(interval: NSTimeInterval) -> String {
//code to format interval
return String(format: "%02d:%02d:%02d", hours, minutes, seconds)
}
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
if let CDview = segue.destinationViewController as? ListView {
CDview.timeArr = timeArr
//CDview.timeArr = mainInstance.arrivalArr
}
}
override func viewDidLoad() {
super.viewDidLoad()
}
override func viewWillAppear(animated: Bool) {
timeArr = testArr
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
}
Not sure where I went wrong. It's particularly confusing because if I use hardcoded strings and jump straight into getTimeDiff then it works perfectly fine and my table view on the next VC also looks great. Would appreciate any help. I've literally moved this code around for the last 12 hours trying to understand why it's not working.
Add a segue from view controller ( and not from UIButton) in storyboard . And name it as you want ( storyboard identifier ) . Perform the segue programmatically with performSegue(...) after you parsed the data .