I am trying to use Parse to create a simple tableview that triggers the URLs of PDF documents that I have uploaded to the Parse Cloud.
In the code below, my variable thePDFFile does output a URL correctly to the console. But when I try to return that variable, it comes up nil and the app crashes.
I am pretty sure that I am not unwrapping an optional correctly, but I can't see where.
The function with the error is named GrabPDF()->String.
import UIKit
import Parse
import Bolts
import AVFoundation
import AVKit
public var AudioPlayer = AVPlayer()
public var SelectedSong = Int()
var theFile:String!
var thePDFFile:String!
class TableViewController: UITableViewController, AVAudioPlayerDelegate {
var iDArray = [String]()
var NameArray = [String]()
var PDFArray = [String]()
var PDFFileArray = [PFObject]()
override func viewDidLoad() {
super.viewDidLoad()
var ObjectIDQuery = PFQuery(className:"Recordings")
ObjectIDQuery.findObjectsInBackgroundWithBlock({
(objectsArray : [AnyObject]?, error: NSError?) -> Void in
var objectIDs = objectsArray as! [PFObject]
for i in 0...objectIDs.count-1{
self.iDArray.append(objectIDs[i].valueForKey("objectId") as! String)
self.NameArray.append(objectIDs[i].valueForKey("RecordingName") as! String)
self.PDFArray.append(objectIDs[i].valueForKey("PDFFileName") as! String)
self.tableView.reloadData()
}
})
}
func grabSong() {
var SongQuery = PFQuery(className:"Recordings")
SongQuery.getObjectInBackgroundWithId(iDArray[SelectedSong], block: {
(object : PFObject?, error : NSError?) -> Void in
if let AudioFileURLTemp = object?.objectForKey("RecordingFile")?.url {
AudioPlayer = AVPlayer(URL: NSURL(string: AudioFileURLTemp!))
AudioPlayer.play()
theFile = AudioFileURLTemp
}
})
}
func grabPDF() -> String {
var PDFQuery = PFQuery(className:"Recordings")
PDFQuery.getObjectInBackgroundWithId(iDArray[SelectedSong], block: {
(object: PFObject?, error : NSError?) -> Void in
if let PDFFileURLTemp = object?.objectForKey("PDFFile")?.url {
println(PDFFileURLTemp)
let thePDFFile = PDFFileURLTemp! as String
println("The value of thePDFFile is \(thePDFFile)")
}
})
return thePDFFile
}
override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return iDArray.count
}
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
var cell = tableView.dequeueReusableCellWithIdentifier("Cell") as! UITableViewCell
cell.textLabel?.text = NameArray[indexPath.row]
return cell
}
override func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
SelectedSong = indexPath.row
grabSong()
grabPDF()
}
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
if segue.identifier == "WebView" {
if let VC2 = segue.destinationViewController as? WebViewController {
if let indexPath = tableView.indexPathForSelectedRow()?.row {
VC2.sentData = theFile
}
}
}
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
}
You're shadowing thePDFFile with that let. The shadow is popped off the stack when you pass the closing brace and you're returning the instance variable which was not set