ios 在非主线程上不能使用asCopy = NO调用Assert

w41d8nur  于 2022-12-05  发布在  iOS
关注(0)|答案(1)|浏览(282)

I have an application in iOS that asks for contact permission when you log in. This permission works fine if you hit "Allow" but sometime the APP crashes when you hit "Not Allow". The function below is where it crashes on UIAlertController *alert = [UIAlertController...

- (BOOL) checkContactPermission {
__block BOOL authorized = NO;

// VAMOS A SOPORTAR A PARTIR DE IOS 9 POR LO QUE NO NECESITAMOS COMPROBARLO
// if ([CNContactStore class]) { }; //ios9 or later
CNEntityType entityType = CNEntityTypeContacts;

// Si no hemos pedido permiso de acceso antes lo pedimos
if([CNContactStore authorizationStatusForEntityType:entityType] == CNAuthorizationStatusNotDetermined) {
    
    CNContactStore * contactStore = [[CNContactStore alloc] init];
    [contactStore requestAccessForEntityType:entityType completionHandler:^(BOOL granted, NSError * _Nullable error) {
        if(granted){
            NSLog(@"Contacts access Granted");
            authorized = YES;
        }
        // Si el usuario no nos da permiso mostramos un alert
        else {
            NSLog(@"Contacts access Denied");
            
            UIAlertController *alert = [UIAlertController
                                        alertControllerWithTitle:@"No se puede acceder a los contactos"
                                        message:@"La App necesita permiso de acceso a los contactos para mostrar el nombre de cada contacto en el listado de llamadas de la app."
                                        preferredStyle: UIAlertControllerStyleAlert];
            UIAlertAction *okAction = [UIAlertAction actionWithTitle:@"OK" style:UIAlertActionStyleDefault
                                                             handler:^(UIAlertAction * action){
                                                                 // Ok action example
                                                             }];
            [alert addAction:okAction];
            
            // Muestro el alert en el hilo principal
            dispatch_async(dispatch_get_main_queue(), ^{
                [[[[UIApplication sharedApplication]keyWindow]rootViewController]presentViewController:alert
                                                                                              animated:YES
                                                                                            completion:nil];
            });
        }
    }];
}
else if( [CNContactStore authorizationStatusForEntityType:entityType] == CNAuthorizationStatusAuthorized) {
    NSLog(@"Contacts access Authorized");
    authorized = YES;
}
return authorized;
}

This is what I get from xCode:

OK -> Thread 25 Thread 25 Queue : com.apple.root.default-qos (concurrent)

0 0x00000001034c29d1 in __43-[GetContactsPlugin checkContactPermission]_block_invoke at /Users/vyorkmur/Documents/APP MiJazztel/Alicante/cordova10/mijazztel-application-typescript/platforms/ios/Mi Jazztel/Plugins/com.viewnext.plugin.getcontacts/GetContactsPlugin/GetContactsPlugin.m:198

KO -- > Thread 4 Thread 4 Queue : com.apple.root.default-qos (concurrent)

23 0x0000000108340a19 in __43-[GetContactsPlugin checkContactPermission]_block_invoke at /Users/vyorkmur/Documents/APP MiJazztel/Alicante/cordova10/mijazztel-application-typescript/platforms/ios/Mi Jazztel/Plugins/com.viewnext.plugin.getcontacts/GetContactsPlugin/GetContactsPlugin.m:200

uqjltbpv

uqjltbpv1#

解决方案是将以下代码放入dispatch_async(dispatch_get_main_queue(), ^{

UIAlertController *alert = [UIAlertController
                                    alertControllerWithTitle:@"No se puede acceder a los contactos"
                                    message:@"La App necesita permiso de acceso a los contactos para mostrar el nombre de cada contacto en el listado de llamadas de la app."
                                    preferredStyle: UIAlertControllerStyleAlert];
        UIAlertAction *okAction = [UIAlertAction actionWithTitle:@"OK" style:UIAlertActionStyleDefault
                                                         handler:^(UIAlertAction * action){
                                                             // Ok action example
                                                         }];
        [alert addAction:okAction];

这样,它将UIAllertController加载到主线程中,并且不会崩溃。

相关问题