Wednesday, 7 January 2015

How do I parse XML enclosure in Swift



I am writing an RSS reader that collects info from XML tags and puts them in a table view. Everything works but the enclosure tag. I want to capture the url contained in the enclosure tag which is a link to an audio stream I want to play. the enclosure tag looks like this



<enclosure url="http://ift.tt/1tJEhch" type="audio/mpeg" length="76153214"/>


I have searched all over for an example and only found Objective C versions of the solution. I have be unable to figure this out. Can anyone out there help me? Here is my code so far.



import UIKit





// Define the class for the table view
// ***********************************


class TableViewController: UITableViewController, NSXMLParserDelegate, UITableViewDataSource, UITableViewDelegate {



// Step 1 - Define the variables you will use
// ******************************************
var parser = NSXMLParser()
var feeds = NSMutableArray()
var elements = NSMutableDictionary()
var element = NSString()
var ftitle = NSMutableString()
var link = NSMutableString()
var fdescription = NSMutableString()
var currentList = String()
var feedEnclosure = NSMutableString()
var mystream = NSMutableString()


// Run these methods when the App Starts up
override func viewDidLoad() {
super.viewDidLoad()


// Step 2 - Setup the RSS Feed and Initialize the Parameters
// ********************************************************
feeds = []
var url = NSURL(string: "http://ift.tt/1tJEhck")
var request = NSURLRequest(URL:url!)
parser = NSXMLParser (contentsOfURL: url)!
parser.delegate = self
parser.shouldProcessNamespaces = false
parser.shouldReportNamespacePrefixes = false
parser.shouldResolveExternalEntities = false
parser.parse()

}

// Step 3 - Define your Methods/Functions
// ***************************************

// Start Parsing and initialize variables to accept RSS data when <item> tag is encountered
func parser(parser: NSXMLParser!, didStartElement elementName: String!, namespaceURI: String!, qualifiedName qName: String!, attributes attributeDict: [NSObject : AnyObject]!) {

element = elementName

if (element as NSString).isEqualToString("item") {
elements = NSMutableDictionary.alloc()
elements = [:]
ftitle = NSMutableString.alloc ()
ftitle = ""
link = NSMutableString.alloc()
link = ""
fdescription = NSMutableString.alloc()
fdescription = ""
feedEnclosure = NSMutableString.alloc()
feedEnclosure = ""
mystream = NSMutableString.alloc()
mystream = ""



}

}

// End Parsing Function and load dictionary key with <title> <link> and <itunes:summary> elements
func parser(parser: NSXMLParser!, didEndElement elementName: String!, namespaceURI: String!, qualifiedName qName: String!) {

if (elementName as NSString).isEqualToString("item") {

if ftitle != "" {
elements.setObject(ftitle, forKey: "title")
//println(ftitle) // Lookey Loo
}

if (link != "") {
elements.setObject(link, forKey: "link")
//println(link) // Lookey Loo
}


if (fdescription != "") {
elements.setObject(fdescription, forKey: "itunes:summary")
//println(fdescription) // Lookey Loo
}

if (feedEnclosure != "") {
elements.setObject(feedEnclosure, forKey: "enclosure")
//println(mystream) // Lookey Loo
}

feeds.addObject(elements)

}

}

// Append the text from the element to the dictionary key location
func parser(parser: NSXMLParser!, foundCharacters string: String!) {


if element.isEqualToString("title"){
ftitle.appendString(string)

}else if element.isEqualToString("link"){
link.appendString(string)

}else if element.isEqualToString("itunes:summary"){
fdescription.appendString(string)

}else if element.isEqualToString("enclosure"){
mystream = attributeDict (valueForKey:@"url")
println(mystream)

}

}



// Now reload all the data
func parserDidEndDocument(parser: NSXMLParser!) {
self.tableView.reloadData()

}


// MARK ---> Define The Table View
//


// Define the number of sections in the tableview
//
override func numberOfSectionsInTableView(tableView: UITableView) -> Int {
return 1
}



// Define the number of rows to display based on the number of items loaded into the array feeds
//
override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {


return feeds.count
}



// Populate the cell with data elements from parser Recycle the last cell
//
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCellWithIdentifier("Cell", forIndexPath: indexPath) as UITableViewCell

// Load an image file into the left margin
//
var image : UIImage = UIImage(named: "300px-banner.png")!
cell.imageView.image = image

// Load the parser data from the title element
//
cell.textLabel.text = feeds.objectAtIndex(indexPath.row).objectForKey ("title") as NSString

println(mystream)

// Load 3 lines of data for each cell
//
cell.textLabel.numberOfLines = 3

return cell

}

// Only grab the data at the selected cell
//
override func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {


}

// Pass the data thru the segue
override func prepareForSegue(segue: (UIStoryboardSegue!), sender: AnyObject!) {
if (segue.identifier == "mySegue") {

// Set the path of the Segue to the other view controller
//
let vc = segue.destinationViewController as secondViewController

// Set a constant to the current selected row
//
if let indexPath = self.tableView.indexPathForSelectedRow() {

// Create a constant to hold the data you want to pass to the other view controller
//
let currentList = feeds.objectAtIndex(indexPath.row).objectForKey("itunes:summary") as NSString
//println(currentList)

// let currentstream = feeds.objectAtIndex(indexPath.row).objectForKey("url") as NSString
// println(currentstream)
// Load that data into a segue parameter that passes thru the segue
//
vc.toPass = currentList



}
}
}
}

No comments:

Post a Comment