Parse get data with block not assigning value to variable in scope - swift

Having issues to assign uiImageFile = image!. If It try to assign self.myImage = image! where myImage is a global variable it works.
Is it something possible to be done?
The code is retrieving images ok, also the cell will take an image if pointed directly. Just this bridge that is not working. And it only do not work for the image.
Also the following test line println("TESTSTRING\(indexPath.row)") just above the return is being able to get and print value from testString = "\(indexPath.row)" that is inside getDataInBackgroundWithBlock.
Sorry about the question title. Not sure how to resume the issue in a single sentence.
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cellIdentifier = "Cell"
let cell = tableView.dequeueReusableCellWithIdentifier(cellIdentifier, forIndexPath: indexPath) as! HobbieFeedTableViewCell
let object: PFObject = self.timelineData.objectAtIndex(indexPath.row) as! PFObject
var myText = object.objectForKey("postText") as? String
let userImageFile = object.objectForKey("postImage") as? PFFile
var uiImageFile = UIImage()
var testString = String()
println(userImageFile, indexPath.row)
if userImageFile != nil {
userImageFile?.getDataInBackgroundWithBlock({ (imageData:NSData?, error:NSError?) -> Void in
if error == nil {
if let myImageData = imageData {
let image = UIImage(data:myImageData)
self.myImage = image!
uiImageFile = image!
testString = "\(indexPath.row)"
}
}
}, progressBlock: { (percent: Int32) -> Void in
})
}
cell.cellTitle.text = myText
cell.cellImage.image = uiImageFile
// cell.cellImage.image = myImage
println("TESTSTRING\(indexPath.row)")
return cell
}

cell.cellImage.image = uiImageFile
gets executed before uiImageFile has been retrieved. This is because the
getDataInBackgroundWithBlock
returns right away before the retrieval is done.
You can fix it by: (1) Retrieve all images into a local array in the viewDidLoad function (2) Use push notification on completion on retrieval to trigger a tableview.reload

Related

Getting images from parse on correct order

I'm trying to get some strings and one photo from parse.com for tableview. I have an NSObject for this class and also an array of object to store them. I can get the newsTitle and the newsDetail in correct order by got fail when try to get newsPhoto. I suppose it lost its order when try get get images in block. Does anybody know what should I change on below code to fix it?
func getNews(){
let query = PFQuery(className: "bulletinOnParse")
query.orderByDescending("createdAt")
query.findObjectsInBackgroundWithBlock {
(allNews: [PFObject]?, error: NSError?) -> Void in
if error == nil {
var duyuru:News
for news in allNews! {
duyuru = News()
let nTitle = news.objectForKey("title") as! String
duyuru.newsTitle = nTitle
let nDetail = news.objectForKey("comment") as! String
duyuru.newsDetail = nDetail
let imageFile = news["newsphoto"] as! PFFile
imageFile.getDataInBackgroundWithBlock {
(imageData: NSData?, error: NSError?) -> Void in
if error == nil {
if let imageData = imageData {
let image = UIImage(data:imageData)
duyuru.newsPhoto = image!
}
}
}
self.bulletin += [duyuru]
}
} else {
// Log details of the failure
print("\(error!.userInfo)")
}
self.tableView.reloadData()
}
}
And cellForRowAtIndexPath method below
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCellWithIdentifier("Cell", forIndexPath: indexPath) as! DuyuruTableViewCell
self.tableView.rowHeight = 100
let cellInfo = bulletin[indexPath.row]
cell.newsTitle.text = cellInfo.newsTitle
cell.news.text = cellInfo.newsDetail
dispatch_async(dispatch_get_main_queue(), {
cell.newsPhoto.image = cellInfo.newsPhoto
})
return cell
}
Here is the answer of how I solve the problem;
First I created an image array from PFFile object
var resultUserImageFiles = [PFFile]()
Then I get the name and add the array on getNews() method
self.resultUserImageFiles.append(news.objectForKey("newsphoto") as! PFFile)
And I get each photo for cell on below method in cellForRowAtIndexPath method.
self.resultUserImageFiles[indexPath.row].getDataInBackgroundWithBlock { (imageData: NSData?, error:NSError?) -> Void in
if error == nil {
let image = UIImage(data: imageData!)
cell.newsPhoto.image = image
}
}

PFFile Image cache in Swift 2.0

I am getting image as PFFile. but when my table is scrolling every time PFFile is downloading and its take time.
I want to cache my file so if its will be downloaded then it will get from cache not from the Parse.
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
var cell = tableView.dequeueReusableCellWithIdentifier("cell") as! RidesCustomCell!
if cell == nil {
cell = RidesCustomCell(style: UITableViewCellStyle.Default, reuseIdentifier: "cell")
}
let currentDic = dataArray.objectAtIndex(indexPath.row) as! NSDictionary
cell.backgroundColor = UIColor.clearColor()
cell.txtName.text = currentDic.valueForKey("firstName") as? String
cell.txtPrice.text = currentDic.valueForKey("price") as? String
cell.txtTime.text = currentDic.valueForKey("date")as? String
cell.txtFrom.text = currentDic.valueForKey("from") as? String
cell.txtTo.text = currentDic.valueForKey("to") as? String
print(currentDic)
cell.imgUser.image = UIImage(named: "noImg.png")
if (currentDic.valueForKey("imageFile") != nil){
// let userImageFile = currentDic.valueForKey("imageFile") as! PFFile
let queue : dispatch_queue_t = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0)
dispatch_async(queue, { () -> Void in
print(currentDic)
let pfuserGet = currentDic.valueForKey("user") as! PFUser
print(pfuserGet.username)
print(pfuserGet.email)
print(pfuserGet.password)
let userImageFile = pfuserGet.objectForKey("profilePicture") as! PFFile
userImageFile.getDataInBackgroundWithBlock {
(imageData: NSData?, error: NSError?) -> Void in
if error == nil {
if let imageData = imageData {
let image = UIImage(data:imageData)
cell.imgUser.image = image
}
}
}
})
}
return cell;
}
I had a look at your code. The issue is the PFFile.getDataInBackground() now since you are using dictionaries I would get the PFFile inside your PFQuery block and and store it in the dictionary as UImage() instead of a PFFile.
And all you have to do in the cellForRowAtIndexPath is load the image from the dictionary.
I think this will solve your problem

Facebook Friends List in TableView: Think need Async Programming?

I am trying to get a friend list from Facebook, i have the call request inside the tableview cellforrowatindexpath but i also have it in a separate function too. Thought to try both ways but i get the same result.
If i do a print from inside the completion block i do get results, however, if i try to print friendProfile outside the completion block it returns nil and therefore when i create the table cells they unwrap nil and the code fails. I think it is because the completion block is not returning data until after i call to create the cells. I am reading, and perhaps this has to do with Asynchronous programming? Or needing to wait till data is returned from Facebook? Or will the completion handler always return nil?
`
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
var request = FBSDKGraphRequest(graphPath:"/me/taggable_friends", parameters: ["fields":"user_id,first_name,last_name,name,picture.type(large)"]);
request.startWithCompletionHandler ({ (connection : FBSDKGraphRequestConnection!, result : AnyObject!, error : NSError!) -> Void in
if error == nil {
//print("Friends are : \(result)")
let jsonResult = result
self.friendsArray = jsonResult["data"] as! NSArray
var index = 0
for data in self.friendsArray {
let fn = data["first_name"]! as! String
let ln = data["last_name"]! as! String
let id = data["id"]! as! String
let picture = data["picture"] as! NSDictionary
let parsePic = picture["data"] as! NSDictionary
let url = parsePic["url"] as! String
self.friendProfile .updateValue((fn + " " + ln), forKey: id)
self.friendProfilePic .updateValue(url, forKey: id)
self.friendProfileID . updateValue(id, forKey: index)
index++
}
} else {
print("Error Getting Friends \(error)");
}
//if i do a print(friendprofilId) in here it works
})
//but a print(friendprofilId) here returns nil
let cellidentifier = "SettingsTableViewCell"
let cell = tableView.dequeueReusableCellWithIdentifier(cellidentifier, forIndexPath: indexPath) as! SettingsTableViewCell
let id = self.friendProfileID[indexPath.row]
print(self.friendProfileID)
if (id != nil) {
let name = self.friendProfile[id!]
let url = self.friendProfilePic[id!]
// cell.imageView?.image = returnFriendProfileImage(url!)
cell.textLabel!.text = name
}
return cell
}
`
You need to call tableView.reloadData() in the place where you have it commented that it works. Also, don't retrieve your data in cellForRowAtIndexPath. Just call the function you had in viewDidLoad
An asynchronous function call with return immediately, while the completion block will complete once it receives a response from the web server. In your case, you call startWithCompletionHandler, which returns immediately and configure your cell before the completion block receives a response from Facebook's server. It makes sense that friendProfilId is still null since you haven't received the data from Facebook.

How do I fix this error"Could not cast value of type 'UIImageView' () to 'PFImageView' " to display images on query?

I'm trying to retrieve users profile pictures(File) from Parse onto my PFQueryTableViewController. The code I've written doesn't give me errors but every time I run my app crashes and says "Could not cast value of type UIImageView to PFImageView. I'm new to coding and don't know what that means. Is there something I have to fix in my code? I just want to retrieve the users image to display on my query.
Here is my code below for my FeedViewController:
override func tableView(tableView: UITableView?, cellForRowAtIndexPath indexPath: NSIndexPath?, object: PFObject!) -> PFTableViewCell? {
let cell = tableView!.dequeueReusableCellWithIdentifier("BubbleCell", forIndexPath: indexPath!) as! Bubbles
if let userPost : PFObject = self.posts.objectAtIndex(indexPath!.row) as! PFObject {
/ if let pic = object["photo"] as? PFFile {
// Make sure your imageView is a PFImageView
let imageView = cell.userImage as! PFImageView
// I assume this is the placeholder image while your load your image files from Parse
imageView.image = UIImage(named: "image.png")
imageView.file = pic
// Load the image file however you see fit
imageView.loadInBackground(nil)
}
Here is my code for my PostViewController:
#IBAction func postPressed(sender: AnyObject) {
let testObj = PFObject(className: "Test")
testObj["photo"] = PFUser.currentUser()?.valueForKey("photo") as! PFFile
testObj.saveInBackgroundWithBlock { (success:Bool, error :NSError?) -> Void in
if error == nil
{
print("***///detail is saved///***")
self.dismissViewControllerAnimated(true, completion: nil)
}
else {
self.alert()
}
}

How to retrieve File from Parse to display on PFQueryTableVIewController?

I'm trying to retrieve users profile pictures(File) from Parse onto my PFQueryTableViewController. I believe I've written my code correctly but I'm probably doing something wrong. So how do I retrieve users images from parse to display on my query?
override func tableView(tableView: UITableView?, cellForRowAtIndexPath indexPath: NSIndexPath?, object: PFObject!) -> PFTableViewCell? {
let cell = tableView!.dequeueReusableCellWithIdentifier("TCell", forIndexPath: indexPath!) as! Tweets
if let userTweet : PFObject = self.tweets.objectAtIndex(indexPath!.row) as! PFObject {
cell.username.text = object["account"] as? String
cell.post.text = object["post"] as? String
cell.post.numberOfLines = 0
if let Pic = object["photo"] as? PFFile {
cell.userImage.image = UIImage(named: "Image")
cell.userImage.file = Pic
}
}
You're not loading the PFFile for one.
if let pic = object["photo"] as? PFFile {
// Make sure your imageView is a PFImageView
let imageView = cell.userImage as! PFImageView
// I assume this is the placeholder image while your load your image files from Parse
imageView.image = UIImage(named: "image.png")
imageView.file = pic
// Load the image file however you see fit
imageView.loadInBackground(nil)
}
As a side note, It's good practice to not capitalize your constants due to the chance they could get confused with class names in your code.
It looks like your code is using a PFImageView, but that the cell subclass is presenting it as a UIImageView so the compiler is complaining. You need to make sure that the image view is properly set and exposed as a PFImageView.