-[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.
WARNING-[UIApplication delegate] must be used from main thread only
+ (NSString *)accessTokenHashForDate:(NSDate *)date withParameters:(NSArray *)params{
__block NSString *accessToken = NULL;
if ([NSThread isMainThread]) {
accessToken = ((AppDelegate *)[[UIApplication sharedApplication] delegate]).loginProfile.accessToken;
} else {
dispatch_semaphore_t semaphore = dispatch_semaphore_create(1);
dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);
dispatch_async(dispatch_get_main_queue(), ^{
accessToken = ((AppDelegate *)[[UIApplication sharedApplication] delegate]).loginProfile.accessToken;
dispatch_semaphore_signal(semaphore);
});
dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);
dispatch_semaphore_signal(semaphore);
}
NSString *paramsStr = [params componentsJoinedByString:@""];
NSString *hashStr = [NSString stringWithFormat:@"%@%@%@%@", [CommonUtil IMEI], [date agileHashFormattedString], (!paramsStr) ? @"" : paramsStr, accessToken];
return hashStr;
}
UIApplication.delegate must be used from main thread only
With ref to this (-[UIApplication delegate] must be called from main thread only) in Swift (for your query resolution)
DispatchQueue.main.async(execute: {
// Handle further UI related operations here....
//let ad = UIApplication.shared.delegate as! AppDelegate
//let context = ad.persistentContainer.viewContext
})
With edit: (Where is the correct place to declare ad and context? Should I declare these in my viewControllers in the main dispatch)
Place of variables (ad and context) declaration defines scope for it. You need to decide what would be scope of these variable. You can declare them Project or application level (Globally), class level or particular this function level.
If you want to use these variable in other ViewControllers then declare it globally or class level with public/open/internal access control.
var ad: AppDelegate! //or var ad: AppDelegate?
var context: NSManagedObjectContext! //or var context: NSManagedObjectContext?
DispatchQueue.main.async(execute: {
// Handle further UI related operations here....
ad = UIApplication.shared.delegate as! AppDelegate
context = ad.persistentContainer.viewContext
//or
//self.ad = UIApplication.shared.delegate as! AppDelegate
//self.context = ad.persistentContainer.viewContext
})
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 theGeneralHelper
.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 aDispatchQueue
.
(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
}
}
Swift 4 ,must be used from main thread only warning
You're making this call on a background queue. To fix, try something like…
public var context: NSManagedObjectContext
DispatchQueue.main.async {
var appDelegate = UIApplication.shared.delegate as! AppDelegate
context = appDelegate.persistentContainer.viewContext
}
Although this is a pretty bad way to do this… you're using your App Delegate as a global variable (which we all know is bad!)
You should look at passing the managed object context from view controller to view controller…
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions:
(window?.rootViewController as? MyViewController)?.moc = persistentContainer.viewContext
}
and so on
Xcode Error for iOS app: [UI Application Delegate] must be called from main thread only
Use the main thread:
Swift:
DispatchQueue.main.async {
let appController = GetAppController()
}
Objective-C:
dispatch_async(dispatch_get_main_queue(), ^{
UnityAppController* appController = GetAppController();
});
Related Topics
How to Mask a Square Image into an Image with Round Corners in iOS
Differencebetween Pan and Swipe in iOS
Writing Handler for Uialertaction
Error: Initializer for Conditional Binding Must Have Optional Type, Not 'String'
How to Detect When Avplayer Video Ends Playing
iOS Simulator Games Run Very Slow (Low Fps)
Uistackview Distribution Fill Equally
Application Loader Stuck at "Authenticating with the Itunes Store" When Uploading an iOS App
Secure Keys in iOS App Scenario, Is It Safe
Setting Selected Image in Tab Bar Controller with Storyboard
iOS Enterprise Distribution Through Ota
Swift - How to Detect Orientation Changes
Uitableview with Static Cells Does Not Appear
Push Notification Not Receiving in Background iOS
Launch Apple Mail App from Within My Own App
Using Scrollview Programmatically in Swift 3
What Is Export * in Module.Modulemap File Inside Each Framework