Reputation: 426
I am working with parse, I am trying to return row.count of a table and output it to a label.text.
func numberOfPostedJobsCount() -> Int{
var postsCount: Int?
var query = PFQuery(className: "Post")
if let user = PFUser.currentUser() {
query.whereKey("user", equalTo: user)
}
query.findObjectsInBackgroundWithBlock { (objects:[AnyObject]?, error) -> Void in
if error == nil {
//query succeeded
print("\(objects?.count)")
} else {
print("\(error)")
}
}
return postsCount!
}
The code inside viewDidLoad() is
numberOfPostedJobs.text = String(numberOfPostedJobsCount())
error : fatal error: unexpectedly found nil while unwrapping an Optional value
Edit 1: I tried adding a public or private variable but it didn't work.
func numberOfPostedJobsCount() -> (Int) {
var num1: Int = 0
var query = PFQuery(className: "Post")
if let user = PFUser.currentUser() {
query.whereKey("user", equalTo: user)
}
query.findObjectsInBackgroundWithBlock { (objects:[AnyObject]?, error) -> Void in
if error == nil {
//query succeeded
print("\(objects?.count)")
num1 = (objects?.count)!
print(num1)
} else {
print("\(error)")
}
}
return num1
}
Upvotes: 0
Views: 151
Reputation: 219
You can use semaphores to make a asynchronous method to work synchronously:
A Sample method for your problem statement
func test()->Int {
var postsCount: Int?
let sema:dispatch_semaphore_t = dispatch_semaphore_create(0)
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0)) { () -> Void in
postsCount = 100
dispatch_semaphore_signal(sema)
}
dispatch_semaphore_wait(sema, DISPATCH_TIME_FOREVER)
return postsCount!
}
for above code:
func numberOfPostedJobsCount() -> Int{
var postsCount: Int?
var query = PFQuery(className: "Post")
let sema:dispatch_semaphore_t = dispatch_semaphore_create(0)
if let user = PFUser.currentUser() {
query.whereKey("user", equalTo: user)
}
query.findObjectsInBackgroundWithBlock { (objects:[AnyObject]?, error) -> Void in
if error == nil {
//query succeeded
postsCount = objects?.count
dispatch_semaphore_signal(sema)
print("\(objects?.count)")
} else {
postsCount = 0
dispatch_semaphore_signal(sema)
print("\(error)")
}
}
dispatch_semaphore_wait(sema, DISPATCH_TIME_FOREVER)
return postsCount!
}
Upvotes: 0
Reputation: 285072
The reason is that postsCount
is declared but never be initialized, so it's nil
when you unwrap it.
Be aware that the function findObjectsInBackgroundWithBlock
works asynchronously, that means the block is called always after the return statement. In this block you have to update your data source and/or the UI.
Edit:
Return Void
from your function and use a completion handler for example
func numberOfPostedJobsCount(completion: (Int) -> ()) {
var query = PFQuery(className: "Post")
if let user = PFUser.currentUser() {
query.whereKey("user", equalTo: user)
}
query.findObjectsInBackgroundWithBlock { (objects:[AnyObject]?, error) -> Void in
if error == nil {
//query succeeded
print("\(objects?.count)")
let num1 = (objects?.count)!
completion(num1)
} else {
print("\(error)")
completion(0)
}
}
}
You call the function this way
numberOfPostedJobsCount() { (postsCount) -> () in
numberOfPostedJobs.text = String(postsCount)
}
Upvotes: 1