class FollowingTableTableViewController: UITableViewController {
let usernames = NSMutableArray()
override func viewDidLoad() {
super.viewDidLoad()
getUsernames()
// Uncomment the following line to preserve selection between presentations
// self.clearsSelectionOnViewWillAppear = false
// Uncomment the following line to display an Edit button in the navigation bar for this view controller.
// self.navigationItem.rightBarButtonItem = self.editButtonItem()
}
func getUsernames() {
var user1 = PFUser.currentUser()
var findUsernames:PFQuery = PFQuery(className: "FollowRequests")
findUsernames.whereKey("from", equalTo: user1!)
findUsernames.includeKey("to")
findUsernames.findObjectsInBackgroundWithBlock { (objects: [AnyObject]?, error: NSError?) -> Void in
var myObjects = objects as! [PFObject]
//Solve this part. Need to get all of the users from the "to" field in FollowRequests.
//If No error
if (error == nil) {
for myObjects in objects! {
var user2 = PFUser()
user2.objectForKey("to")
self.usernames.addObject(user2.username!)
println(user2.username)
}
self.tableView.reloadData()
}
}
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
// #warning Incomplete method implementation.
// Return the number of rows in the section.
return self.usernames.count
}
override func tableView(tableView: UITableView,
cellForRowAtIndexPath indexPath: NSIndexPath)
-> UITableViewCell {
let item: AnyObject = self.usernames[indexPath.row]
let cell = tableView.dequeueReusableCellWithIdentifier("cell", forIndexPath: indexPath) as! UITableViewCell
cell.textLabel!.text = (usernames[indexPath.row] as! String)
return cell
}
I keep getting the fatal error:
unexpectedly found nil while unwrapping an Optional value.
What do I need to do?
Hoping to find where I messed up.
There is a lot of ? in your code:
First: are you trying to query using the currentUser(username ) or (objectID)
Second: in the findObjectsInBackgroundWithBlock method
you need to check if there is an error first then convert the array of any object to PFObject
if error == nil{
if let objects = objects as! [PFObject]{
for oneSpecificObject in objects{
var data = oneSpecificObject["to"] as! String
self.usernames.addObject(data)
}
self.tableView.reloadData()
}
}
Third: In the cellForRowAtIndexPath method
why you have that extra line
let item: AnyObject = self.usernames[indexPath.row]
//review carefully your code then if you still have problem let me know.
Related
I am trying to display items in my List entity on a table view. I believe my issue is a type casting one, but after researching a bit, I've been unable to find a solution. My exact error is "Cannot assign value of type 'List' to type 'String?'.
Below is the code:
import UIKit
import CoreData
class ToBeastViewController: UIViewController, UITableViewDelegate, UITableViewDataSource {
#IBOutlet weak var tableView: UITableView!
var items = [List]()
let matthewsManagedObjectContext = (UIApplication.sharedApplication().delegate as! AppDelegate).managedObjectContext
func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
let request = NSFetchRequest(entityName: "List")
do {
let response = try matthewsManagedObjectContext.executeFetchRequest(request)
print("Sucess!")
let arrayList = response as! [List]
for item in arrayList {
print(item.item)
}
}
catch {
print("Failed!")
} // numberOfRowsInSection end
return items.count
}
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
// let cell:UITableViewCell = self.tableView.dequeueReusableCellWithIdentifier("MyCell")! as UITableViewCell
let cell = tableView.dequeueReusableCellWithIdentifier("MyCell", forIndexPath: indexPath)
// var itemString = List as! item
cell.textLabel?.text = items[indexPath.row]
return cell
}
func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
print("You selected cell #\(indexPath.row)!")
}
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
}
The issue is with the line:
cell.textLabel?.text = items[indexPath.row]
...or at least that's my understanding. I apologize if the formatting is poor or if I am missing information that may help. Some of my attempts to solve this are commented out. Thank you for any help!
Edit*
Below is the code from the View that takes text input and adds it to List:
import UIKit
import CoreData
class JustBeastItViewController: UIViewController {
let matthewsManagedObjectContext = (UIApplication.sharedApplication().delegate as! AppDelegate).managedObjectContext
// var items = [List]()
#IBAction func doneButtonPressed(sender: UIBarButtonItem) {
let newManagedObject = NSEntityDescription.insertNewObjectForEntityForName("List", inManagedObjectContext: matthewsManagedObjectContext)
let newItem = newManagedObject as! List
newItem.item = justBeastItTextField.text
do {
try matthewsManagedObjectContext.save()
print("It was successful!")
}
catch {
print("There was an error!")
}
let request = NSFetchRequest(entityName: "List")
do {
let response = try matthewsManagedObjectContext.executeFetchRequest(request)
print("Sucess!")
let arrayList = response as! [List]
for item in arrayList {
print(item.item)
}
}
catch {
print("Failed!")
}
}
#IBOutlet weak var justBeastItTextField: UITextField!
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
}
I'm working on a message app with parse.
I would like to filter by sender the result of query but it duplicate sender for each messages.
I think it is possible to find same value on a array? (in this exemple clientsArray)
Any idea?
Below the code that I used.
var clientName = ""
var clientsArray:[String] = [String]()
override func viewDidLoad() {
super.viewDidLoad()
//Message List Query
let messages = PFQuery(className:"Message")
messages.whereKey("user", equalTo:PFUser.currentUser()!["retailer"]!)
messages.findObjectsInBackgroundWithBlock {
(objects: [AnyObject]?, error: NSError?) -> Void in
if error == nil {
print("Successfully retrieved \(objects!.count) scores.")
if let objects = objects as? [PFObject] {
self.clientName.removeAll()
for object in objects {
if let clientName = object["clientName"] as? String {
self.clientsArray.append(clientName)
}
self.tableView.reloadData()
print(self.clientsArray)
}
}
} else {
print(error)
}
}
}
// MARK: - Table view data source
override func numberOfSectionsInTableView(tableView: UITableView) -> Int {
// #warning Incomplete implementation, return the number of sections
return 1
}
override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
// #warning Incomplete implementation, return the number of rows
return clientsArray.count
}
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCellWithIdentifier("clientsCell", forIndexPath: indexPath)
let clientName = clientsArray[indexPath.row]
if let clientNameLabel = cell.viewWithTag(301) as? UILabel {
clientNameLabel.text = clientName
}
return cell
}
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
if segue.identifier == "showChat" {
if let destination = segue.destinationViewController as? newChatViewController {
destination.clientName = clientsArray[(tableView.indexPathForSelectedRow?.row)!]
//self.hidesBottomBarWhenPushed = true
}
}
}
It's really hard to answer without seeing what the data structure looks like. But I can tell you the problem with your code.
if let clientName = object["clientName"] as? String {
self.clientsArray.append(clientName)
}
Your if-let statement is simply getting the object of ["clientName"], which is just your clients name. Then you're appending your clients name to your clientsArray object.
This is why you're just seeing luke.
I can help resolve the problem, but I need to know what your data's structure looks like. Can you print out an entire object?
I am using parse with Swift and I am trying to bring up and post an image from Parse on to my tableView but I keep receiving in the log
fatal error: unexpectedly found nil while unwrapping an Optional
value
here's my code for querying the image:
import UIKit
import Parse
class HomePage: UITableViewController {
var images = [UIImage]()
var titles = [String]()
var imageFiles = [PFFile]()
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
println(PFUser.currentUser())
var query = PFQuery(className:"Post")
//query.whereKey("username", equalTo:followedUser)
query.findObjectsInBackgroundWithBlock {(objects: [AnyObject]?, error: NSError?) -> Void in
if error == nil {
// The find succeeded.
println("Successfully retrieved \(objects!.count) scores.")
// Do something with the found objects
for object in objects! {
// Update - replaced as with as!
self.titles.append(object["Title"] as! String)
// Update - replaced as with as!
self.imageFiles.append(object["imageFile"] as! PFFile)
self.tableView.reloadData()
}
} else {
// Log details of the failure
println(error)
}
}
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
override func numberOfSectionsInTableView(tableView: UITableView) -> Int {
return 1
}
override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return titles.count
}
override func tableView(tableView: UITableView, heightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat {
return 500
}
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
var myCell:cell = self.tableView.dequeueReusableCellWithIdentifier("myCell") as! cell
myCell.rank.text = "21"
myCell.votes.text = "4012"
myCell.postDescription.text = titles[indexPath.row]
return myCell
}
}
Also I get the one line of code highlighted in green which is this :
self.imageFiles.append(object["imageFile"] as! PFFile)
What am I doing wrong and what can I do to make the the code pull up the image from Parse?
now its no longer giving me the error unwrapped nil but it still shows
self.imageFiles.append(object["imageFile"] as! PFFile)
in green highlighting and the app keeps crashing when i open it.
this is my parse backend in case that might be an issue:
i solved the issue by adding in the ovveride func UITableviewCell
imageFile[indexPath.row].getDataInBackgroundWithBlock { (data, error) -> Void in
if let downloadedImage = UIImage(data: data!) {
myCell.postedImage.image = downloadedImage
}
}
i think this worked because i got rid of the if error == nil and now its working great for me.
I really don't know whats going on and Im really confused why this happens. I might be doing something wrong but when i try to access my array out of the function, there is nothing in it. If anyone can help me please tell me.
import UIKit
class withFriendsView: UITableViewController {
var withFriendsArray:NSMutableArray = NSMutableArray()
var friendImg = [PFFile]()
var friendusername = [String]()
var friendName = [String]()
override func viewDidLoad() {
super.viewDidLoad()
}
override func viewDidAppear(animated: Bool) {
super.viewDidAppear(animated)
loadWithFriends()
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
}
override func numberOfSectionsInTableView(tableView: UITableView) -> Int {
return 1
}
override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return friendusername.count
}
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell:WithFriendsCell = tableView.dequeueReusableCellWithIdentifier("withFriends", forIndexPath: indexPath) as! WithFriendsCell
friendImg[indexPath.row].getDataInBackgroundWithBlock {
(data:NSData?, error:NSError?) -> Void in
let img = UIImage(data: data!)
cell.friendsImage.image = img
}
return cell
}
func loadWithFriends() {
var channelQuery = ChannelQuery.query()!
var activityQuery = ActivityQuery.query()!
channelQuery.whereKey("Host", matchesKey: "ActChannel", inQuery: activityQuery)
channelQuery.whereKey("Host", equalTo: "kia495")
var data = channelQuery.findObjects()
if data!.count != 0 {
for objects in data! {
let username = objects["Users"]!!.objectId
let predicate = NSPredicate(format: "objectId == %#", username!!)
var userQuery = PFQuery(className: "_User", predicate: predicate)
var objects = userQuery.findObjects()
for object in objects! {
friendImg.append(object.objectForKey("profileImage") as! PFFile)
}
}
}
}
}
You should reload the table after adding an element to the array
First move loadWithFriends() from viewDidAppear to viewDidLoad
in this line, you are returning another array, try returning friendImg.count
override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return friendusername.count
}
This findObjectsInBackgroundWithBlock looks like an async method, which will immediately return. The code in the block will be executed only when the data is ready. So when you try to access the data from friendImg, it may not be ready and you will get nil.
If the data is not very large, you can use sync method to do this.
I'm working with tableview controller and try to add pull refresh features but i'm having unexpectedly found nil while unwrapping an Optional value error when test the pull to refresh feature in my iPhone 5. The error happen at connectionDidFinishLoading function.
class FixtureTableTableViewController: UITableViewController,UITableViewDelegate,NSURLConnectionDelegate {
var fixtures:[Fixture] = []
var data = NSMutableData()
var jsonResults:NSArray! = nil
override func viewDidLoad() {
println("view did load")
super.viewDidLoad()
connectToServer();
self.refreshControl = UIRefreshControl()
//self.refreshControl?.attributedTitle = NSAttributedString(string: "pull to refresh")
self.refreshControl?.addTarget(self, action: Selector("refresh"), forControlEvents: UIControlEvents.ValueChanged)
//self.fixtures = Fixture().listAll()
// Uncomment the following line to preserve selection between presentations
// self.clearsSelectionOnViewWillAppear = false
// Uncomment the following line to display an Edit button in the navigation bar for this view controller.
// self.navigationItem.rightBarButtonItem = self.editButtonItem()
}
func refresh(){
println("refresh table")
fixtures = []
connectToServer()
self.refreshControl?.endRefreshing()
}
func connectToServer(){
println("connect to server")
let plist = NSBundle.mainBundle().pathForResource("hijaukuningapp",ofType: "plist")
let dict = NSDictionary(contentsOfFile: plist!)
var serverURL = dict["serverURL"] as String
println("server url \(serverURL)")
let urlPath:String = serverURL + "mobileFixture/list"
println(urlPath)
var url = NSURL(string: urlPath)
var request = NSURLRequest(URL: url)
var connect = NSURLConnection(request: request, delegate: self, startImmediately: true)
connect.start()
}
func connection(connection: NSURLConnection, didReceiveData _data: NSData!){
println("receivedata")
data.appendData(_data)
println("end append data")
}
func connectionDidFinishLoading(connection: NSURLConnection){
println("finished loading data\(data)")
var err: NSError
// throwing an error on the line below (can't figure out where the error message is)
jsonResults = NSJSONSerialization.JSONObjectWithData(data, options: NSJSONReadingOptions.MutableContainers, error: nil) as NSArray
println(jsonResults)
fixtures = Fixture().listAll(jsonResults)
self.tableView.reloadData()
}
override func viewWillAppear(animated: Bool) {
println("viewWillAppear")
super.viewWillAppear(animated)
}
/*
override func viewWillAppear(animated: Bool) {
//startConnection();
println(jsonResults)
for result : AnyObject in jsonResults {
//println(result)
if let fixture = result as? Dictionary<String,AnyObject>{
var fixtureID = fixture["day"]
println(fixtureID)
var monthNamne = fixture["monthname"]
var tempFixture = Fixture()
tempFixture.day = fixtureID as String
tempFixture.month = monthNamne as String
var f2 = Fixture()
f2.homeTeam="KELANTAN"
f2.awayTeam = "KEDAH"
f2.venue = "STADIUM SULTAN MOHAMED, ALOR SETAR"
f2.day = "13"
f2.month = "OCT"
f2.time = "2045"
fixtures.append(f2)
self.tableView.reloadData()
}
println(fixtures.count)
}
}
*/
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
// MARK: - Table view data source
override func numberOfSectionsInTableView(tableView: UITableView) -> Int {
// #warning Potentially incomplete method implementation.
// Return the number of sections.
return 1
}
override func tableView(tableView: UITableView?, numberOfRowsInSection section: Int) -> Int {
// #warning Incomplete method implementation.
// Return the number of rows in the section.
return fixtures.count
}
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCellWithIdentifier("myCell", forIndexPath: indexPath) as FixtureTableViewCell
cell.lblVenue.text = fixtures[indexPath.row].venue
cell.lblHome.text = fixtures[indexPath.row].homeTeam.name
cell.lblAway.text = fixtures[indexPath.row].awayTeam.name
cell.lblDay.text = fixtures[indexPath.row].day
cell.lblMonth.text = fixtures[indexPath.row].month
cell.lblTime.text = fixtures[indexPath.row].time
var code:String = fixtures[indexPath.row].homeTeam.code + ".png"
var awayCode:String = fixtures[indexPath.row].awayTeam.code + ".png"
cell.homeLogo.image = UIImage(named: code);
cell.awayLogo.image = UIImage(named: awayCode)
return cell
}
override func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
println("indexpat " )
}
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject!) {
println("prepare for sergues")
var detailController:FixtureDetailViewController = segue.destinationViewController as FixtureDetailViewController
var indexPath = self.tableView.indexPathForSelectedRow()
detailController.fixture = fixtures[indexPath!.row]
}
/*
// Override to support conditional editing of the table view.
override func tableView(tableView: UITableView!, canEditRowAtIndexPath indexPath: NSIndexPath!) -> Bool {
// Return NO if you do not want the specified item to be editable.
return true
}
*/
/*
// Override to support editing the table view.
override func tableView(tableView: UITableView!, commitEditingStyle editingStyle: UITableViewCellEditingStyle, forRowAtIndexPath indexPath: NSIndexPath!) {
if editingStyle == .Delete {
// Delete the row from the data source
tableView.deleteRowsAtIndexPaths([indexPath], withRowAnimation: .Fade)
} else if editingStyle == .Insert {
// Create a new instance of the appropriate class, insert it into the array, and add a new row to the table view
}
}
*/
/*
// Override to support rearranging the table view.
override func tableView(tableView: UITableView!, moveRowAtIndexPath fromIndexPath: NSIndexPath!, toIndexPath: NSIndexPath!) {
}
*/
/*
// Override to support conditional rearranging of the table view.
override func tableView(tableView: UITableView!, canMoveRowAtIndexPath indexPath: NSIndexPath!) -> Bool {
// Return NO if you do not want the item to be re-orderable.
return true
}
*/
/*
// MARK: - Navigation
// In a storyboard-based application, you will often want to do a little preparation before navigation
override func prepareForSegue(segue: UIStoryboardSegue!, sender: AnyObject!) {
// Get the new view controller using [segue destinationViewController].
// Pass the selected object to the new view controller.
}
*/
}
In this line your data object is nil.
jsonResults = NSJSONSerialization.JSONObjectWithData(data, options: NSJSONReadingOptions.MutableContainers, error: nil) as NSArray
Fix it by doing:
if let d = data {
//Only executed if data isn't nil
jsonResults = NSJSONSerialization.JSONObjectWithData(d, options: NSJSONReadingOptions.MutableContainers, error: nil) as NSArray
}
In swift, an optional value means that it could be nil. If you don't get the actual value out of the optional, your code won't compile. The pattern above will only execute the code if the value is not nil.