草庐IT

ios - 巨大的延迟(没有错误!)仅在请求地址簿权限后第一次

coder 2024-01-11 原文

在请求用户允许使用他的地址簿后,我只有第一次出现巨大的延迟(5-6 秒)。第一次后,添加新联系人 View Controller 会立即显示。 任何人都知道为什么会这样?我在 IOS 7.1 和 8 上使用 Xcode 5 或 6 beta(发生同样的事情)

这是我请求权限的方式:

    ABAddressBookRef addressBook = NULL;
    CFErrorRef error = NULL;

    switch (ABAddressBookGetAuthorizationStatus()) {
        case kABAuthorizationStatusAuthorized: {
            addressBook = ABAddressBookCreateWithOptions(NULL, &error);
            [self addToContacts];
            if (addressBook != NULL) CFRelease(addressBook);
            break;
        }
        case kABAuthorizationStatusDenied: {
            //NSLog(@"Access denied to address book");
            NSString *msgString = @"You have denied access to contacts. Please go to settings to enable access, then try again.";
            UIAlertView *returnAl = [[UIAlertView alloc] initWithTitle:@"Unable to save!" message:msgString delegate:nil cancelButtonTitle:nil otherButtonTitles:nil];
            [returnAl show];
            [self performSelector:@selector(dismissAlert:) withObject:returnAl afterDelay:3];

            break;
        }
        case kABAuthorizationStatusNotDetermined: {
            addressBook = ABAddressBookCreateWithOptions(NULL, &error);
            ABAddressBookRequestAccessWithCompletion(addressBook, ^(bool granted, CFErrorRef error) {
                if (granted) {
                    NSLog(@"Access was granted trying to add");
                    [self addToContacts];
                } else {
                    NSLog(@"Access was not granted");
                }
                if (addressBook != NULL) CFRelease(addressBook);
            });
            break;
        }
        case kABAuthorizationStatusRestricted: {
            NSLog(@"access restricted to address book");
            NSString *msgString = @"You have denied access to contacts. Please go to settings to enable access, then try again.";
            UIAlertView *returnAl = [[UIAlertView alloc] initWithTitle:@"Unable to save!" message:msgString delegate:nil cancelButtonTitle:nil otherButtonTitles:nil];
            [returnAl show];
            [self performSelector:@selector(dismissAlert:) withObject:returnAl afterDelay:3];
            break;
        }
    }

这就是我发起添加新联系人的方式

ABAddressBookRef addressBook = ABAddressBookCreateWithOptions(nil,nil);
ABRecordRef person = ABPersonCreate();

// Setting basic properties
ABRecordSetValue(person, kABPersonFirstNameProperty, (__bridge CFTypeRef)(user[@"name"]) , nil);
ABRecordSetValue(person, kABPersonLastNameProperty, (__bridge CFTypeRef)(user[@"surName"]), nil);
ABRecordSetValue(person, kABPersonJobTitleProperty, (__bridge CFTypeRef)(user[@"workTitle"]), nil);
//ABRecordSetValue(person, kABPersonDepartmentProperty, @"iPhone development department", nil);
ABRecordSetValue(person, kABPersonOrganizationProperty, (__bridge CFTypeRef)(user[@"company"]), nil);
ABRecordSetValue(person, kABPersonNoteProperty, @"Contact saved by introdU app", nil);
// Adding phone numbers
ABMutableMultiValueRef phoneNumberMultiValue = ABMultiValueCreateMutable(kABMultiStringPropertyType);
ABMultiValueAddValueAndLabel(phoneNumberMultiValue, (__bridge CFTypeRef)(user[@"mobile"]), (CFStringRef)@"iPhone", NULL);
ABMultiValueAddValueAndLabel(phoneNumberMultiValue, (__bridge CFTypeRef)(user[@"tel"]), (CFStringRef)@"Work", NULL);
//ABMultiValueAddValueAndLabel(phoneNumberMultiValue, @"08701234567", (CFStringRef)@"0870", NULL);
ABRecordSetValue(person, kABPersonPhoneProperty, phoneNumberMultiValue, nil);
if (phoneNumberMultiValue != NULL) { CFRelease(phoneNumberMultiValue); phoneNumberMultiValue = NULL; };

// Adding url
ABMutableMultiValueRef urlMultiValue = ABMultiValueCreateMutable(kABMultiStringPropertyType);
ABMultiValueAddValueAndLabel(urlMultiValue, (__bridge CFTypeRef)(user[@"url"]), kABPersonHomePageLabel, NULL);
ABRecordSetValue(person, kABPersonURLProperty, urlMultiValue, nil);
CFRelease(urlMultiValue);

// Adding emails
ABMutableMultiValueRef emailMultiValue = ABMultiValueCreateMutable(kABMultiStringPropertyType);
ABMultiValueAddValueAndLabel(emailMultiValue, (__bridge CFTypeRef)(user[@"email"]), (CFStringRef)@"Work", NULL);
//ABMultiValueAddValueAndLabel(emailMultiValue, @"ondrej.rafaj@fuerteint.com", (CFStringRef)@"Work", NULL);
ABRecordSetValue(person, kABPersonEmailProperty, emailMultiValue, nil);
CFRelease(emailMultiValue);

// Adding address
ABMutableMultiValueRef addressMultipleValue = ABMultiValueCreateMutable(kABMultiDictionaryPropertyType);
NSMutableDictionary *addressDictionary = [[NSMutableDictionary alloc] init];
[addressDictionary setObject:user[@"address"] forKey:(NSString *)kABPersonAddressStreetKey];
[addressDictionary setObject:user[@"city"] forKey:(NSString *)kABPersonAddressCityKey];
[addressDictionary setObject:user[@"postalCode"] forKey:(NSString *)kABPersonAddressZIPKey];
[addressDictionary setObject:user[@"country"] forKey:(NSString *)kABPersonAddressCountryKey];
//[addressDictionary setObject:@"gb" forKey:(NSString *)kABPersonAddressCountryCodeKey];
ABMultiValueAddValueAndLabel(addressMultipleValue, (__bridge CFTypeRef)(addressDictionary), kABWorkLabel, NULL);
ABRecordSetValue(person, kABPersonAddressProperty, addressMultipleValue, nil);
CFRelease(addressMultipleValue);

ABPersonSetImageData(person, (__bridge CFTypeRef)(profileImageData), nil);
// Adding person to the address book
ABAddressBookAddRecord(addressBook, person, nil);
CFRelease(addressBook);


// Creating view controller for a new contact

ABNewPersonViewController *c = [[ABNewPersonViewController alloc] init];
[c setNewPersonViewDelegate:self];
[c setDisplayedPerson:person];
if (person != NULL) { CFRelease(person); person = NULL; };
[self.navigationController pushViewController:c animated:YES];

最佳答案

发生这种情况是因为在任意队列上调用了 ABAddressBookRequestAccessWithCompletion(addressBook, ^(bool granted, CFErrorRef error) 的完成 block 。

因此,您第一次运行此代码时,您是在任意队列上调用您的 View Controller 表示 - 每隔一次您在主队列上调用它,因此它工作正常。

您需要做的就是将完成 block 分派(dispatch)到主队列。

ABAddressBookRequestAccessWithCompletion(addressBook, ^(bool granted, CFErrorRef error) {
            if (granted) {
                NSLog(@"Access was granted trying to add");
                dispatch_async(dispatch_get_main_queue(), ^{
                    [self addToContacts];
                });
            } else {
                NSLog(@"Access was not granted");
            }
            if (addressBook != NULL) CFRelease(addressBook);
        });

关于ios - 巨大的延迟(没有错误!)仅在请求地址簿权限后第一次,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24303467/

有关ios - 巨大的延迟(没有错误!)仅在请求地址簿权限后第一次的更多相关文章

  1. ruby - 难道Lua没有和Ruby的method_missing相媲美的东西吗? - 2

    我好像记得Lua有类似Ruby的method_missing的东西。还是我记错了? 最佳答案 表的metatable的__index和__newindex可以用于与Ruby的method_missing相同的效果。 关于ruby-难道Lua没有和Ruby的method_missing相媲美的东西吗?,我们在StackOverflow上找到一个类似的问题: https://stackoverflow.com/questions/7732154/

  2. ruby - 使用 Vim Rails,您可以创建一个新的迁移文件并一次性打开它吗? - 2

    使用带有Rails插件的vim,您可以创建一个迁移文件,然后一次性打开该文件吗?textmate也可以这样吗? 最佳答案 你可以使用rails.vim然后做类似的事情::Rgeneratemigratonadd_foo_to_bar插件将打开迁移生成的文件,这正是您想要的。我不能代表textmate。 关于ruby-使用VimRails,您可以创建一个新的迁移文件并一次性打开它吗?,我们在StackOverflow上找到一个类似的问题: https://sta

  3. ruby - 如何每月在 Heroku 运行一次 Scheduler 插件? - 2

    在选择我想要运行操作的频率时,唯一的选项是“每天”、“每小时”和“每10分钟”。谢谢!我想为我的Rails3.1应用程序运行调度程序。 最佳答案 这不是一个优雅的解决方案,但您可以安排它每天运行,并在实际开始工作之前检查日期是否为当月的第一天。 关于ruby-如何每月在Heroku运行一次Scheduler插件?,我们在StackOverflow上找到一个类似的问题: https://stackoverflow.com/questions/8692687/

  4. ruby-on-rails - rails 目前在重启后没有安装 - 2

    我有一个奇怪的问题:我在rvm上安装了ruby​​onrails。一切正常,我可以创建项目。但是在我输入“railsnew”时重新启动后,我有“程序'rails'当前未安装。”。SystemUbuntu12.04ruby-v"1.9.3p194"gemlistactionmailer(3.2.5)actionpack(3.2.5)activemodel(3.2.5)activerecord(3.2.5)activeresource(3.2.5)activesupport(3.2.5)arel(3.0.2)builder(3.0.0)bundler(1.1.4)coffee-rails(

  5. ruby - 在没有 sass 引擎的情况下使用 sass 颜色函数 - 2

    我想在一个没有Sass引擎的类中使用Sass颜色函数。我已经在项目中使用了sassgem,所以我认为搭载会像以下一样简单:classRectangleincludeSass::Script::FunctionsdefcolorSass::Script::Color.new([0x82,0x39,0x06])enddefrender#hamlengineexecutedwithcontextofself#sothatwithintemlateicouldcall#%stop{offset:'0%',stop:{color:lighten(color)}}endend更新:参见上面的#re

  6. ruby - 如何验证 IO.copy_stream 是否成功 - 2

    这里有一个很好的答案解释了如何在Ruby中下载文件而不将其加载到内存中:https://stackoverflow.com/a/29743394/4852737require'open-uri'download=open('http://example.com/image.png')IO.copy_stream(download,'~/image.png')我如何验证下载文件的IO.copy_stream调用是否真的成功——这意味着下载的文件与我打算下载的文件完全相同,而不是下载一半的损坏文件?documentation说IO.copy_stream返回它复制的字节数,但是当我还没有下

  7. ruby - 从 Ruby 中的主机名获取 IP 地址 - 2

    我有一个存储主机名的Ruby数组server_names。如果我打印出来,它看起来像这样:["hostname.abc.com","hostname2.abc.com","hostname3.abc.com"]相当标准。我想要做的是获取这些服务器的IP(可能将它们存储在另一个变量中)。看起来IPSocket类可以做到这一点,但我不确定如何使用IPSocket类遍历它。如果它只是尝试像这样打印出IP:server_names.eachdo|name|IPSocket::getaddress(name)pnameend它提示我没有提供服务器名称。这是语法问题还是我没有正确使用类?输出:ge

  8. Ruby 文件 IO 定界符? - 2

    我正在尝试解析一个文本文件,该文件每行包含可变数量的单词和数字,如下所示:foo4.500bar3.001.33foobar如何读取由空格而不是换行符分隔的文件?有什么方法可以设置File("file.txt").foreach方法以使用空格而不是换行符作为分隔符? 最佳答案 接受的答案将slurp文件,这可能是大文本文件的问题。更好的解决方案是IO.foreach.它是惯用的,将按字符流式传输文件:File.foreach(filename,""){|string|putsstring}包含“thisisanexample”结果的

  9. 没有类的 Ruby 方法? - 2

    大家好!我想知道Ruby中未使用语法ClassName.method_name调用的方法是如何工作的。我头脑中的一些是puts、print、gets、chomp。可以在不使用点运算符的情况下调用这些方法。为什么是这样?他们来自哪里?我怎样才能看到这些方法的完整列表? 最佳答案 Kernel中的所有方法都可用于Object类的所有对象或从Object派生的任何类。您可以使用Kernel.instance_methods列出它们。 关于没有类的Ruby方法?,我们在StackOverflow

  10. ruby-on-rails - Rails 3,嵌套资源,没有路由匹配 [PUT] - 2

    我真的为这个而疯狂。我一直在搜索答案并尝试我找到的所有内容,包括相关问题和stackoverflow上的答案,但仍然无法正常工作。我正在使用嵌套资源,但无法使表单正常工作。我总是遇到错误,例如没有路线匹配[PUT]"/galleries/1/photos"表格在这里:/galleries/1/photos/1/edit路线.rbresources:galleriesdoresources:photosendresources:galleriesresources:photos照片Controller.rbdefnew@gallery=Gallery.find(params[:galle

随机推荐