Uiapplication.Registerforremotenotifications() Must Be Called from Main Thread Only

UIApplication.registerForRemoteNotifications() must be called from main thread only

In swift4

You can solve this issue with

DispatchQueue.main.async {
UIApplication.shared.registerForRemoteNotifications()
}

Hope this will help...

-[UIApplication delegate] must be called from main thread only

Just call it from the main thread like this.

Objective-C

dispatch_async(dispatch_get_main_queue(), ^{
[[UIApplication delegate] fooBar];
});

Swift

DispatchQueue.main.async {
YourUIControlMethod()
}

Reaching out to your app delegate like this, is a hint that your architecture could use a little cleanup.

You can call delegates from any thread you want. You only need to make sure you're on the main thread for UIKit calls.
Or that you're on the correct thread your CoreData objects expect. It all depends on the API contract your objects have.

UIApplication applicationState must be used from main thread only


(Question changed from being about the main thread to how to define and call closures. This answer has changed to reflect that.)

[UIApplication applicationState] is most likely being called from
within the GeneralHelper.

The service helper is most likely making the network request on a
background thread.

So, to make sure GeneralHelper is called on the main thread, execute
it via a DispatchQueue.

(Also! You're not calling your completion handler, so we'll add that in too.)

func registerApi(path: String, player_id: Int, contest_id: Int, country_id: Int,  completion: ((Bool) -> Void)? = nil)
{
let helper = ServiceHelper.sharedInstance
let params = [
"api_token": Constants.USER_INFO["api_token"].rawValue,
"player_id": player_id,
"country_id": country_id,
"contest_id": contest_id
]
helper.sendRequest(path: "register-country", params: params, showSpinner: true) { (response, error) in
var success = true

if let error = error
{
// Do stuff on failure.
success = false
}
else
{
// Do stuff on success
}

// Call completion handler from 'registerApi'
completion?(success)
})
}

In your test, you can now add a parameter to test for success.

func testApiWorking()
{
let controller = WorldCupChooseCountryVC()

let expected = XCTestExpectation(description: "Some Countries to return")

controller.registerApi(path: "register-country", player_id: 163, contest_id: 1, country_id: 1) { success in
if success {
// Test success
} else {
// Test fail
}

expected.fulfill()
}

waitForExpectations(timeout: 30) { (_) -> Void in
}
}

UIViewController.navigationController must be used from main thread only

Add your view controller to to navigationController from main thread as -

    do{
let decodedData = try decoder.decode(CordinateData.self, from: safeData)
let lat = decodedData.data[0].x
let lon = decodedData.data[0].y
let doubleLat = Double(lat) ?? 0.0
let doubleLon = Double(lon) ?? 0.0
nc.lon = doubleLon
nc.lat = doubleLat
DispatchQueue.main.async {
self.navigationController?.pushViewController(nc, animated: true)
//self.present(nc, animated: true, completion: nil)
}

print(doubleLat)
print(doubleLon)

}catch{
print("error")
}

UIDatePicker setEnabled must be used from main thread only

You should call notEnable() on the main thread:

DispatchQueue.main.async {
self.notEnable()
}

FIRMessaging should be called from main thread only

You should use the class method messaging to get the instance. Looks like you are creating a new instance instead of using the messaging() method.



Related Topics



Leave a reply



Submit