获取时应用程序崩溃 >800 个使用 iOS 9 联系人框架的联系人 [英] App crashing when fetching > 800 contacts using iOS 9 Contacts framework

查看:37
本文介绍了获取时应用程序崩溃 >800 个使用 iOS 9 联系人框架的联系人的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

尝试使用 iOS 9 联系人框架获取设备上的所有统一联系人.尝试获取 > 800 个联系人时,应用程序崩溃.

Trying to fetch all the unified contacts on a device using the iOS 9 Contacts framework. The app is crashing when trying to fetch > 800 contacts.

我认为这是一个内存问题.

I think this is a memory issue.

下面是我的实现

@objc func searchContacts(searchText: String?, callback: (NSObject) -> ()) -> Void {

    let contactStore = CNContactStore()

    let keysToFetch = [ CNContactGivenNameKey, CNContactFamilyNameKey, CNContactImageDataAvailableKey, CNContactThumbnailImageDataKey ]

    do {

      var cNContacts = [CNContact]()

      let fetchRequest = CNContactFetchRequest(keysToFetch: keysToFetch)

      fetchRequest.sortOrder = CNContactSortOrder.GivenName

      try contactStore.enumerateContactsWithFetchRequest(fetchRequest) { (cNContact, pointer) -> Void in

        if !cNContact.givenName.isEmpty {  // Ignore any Contacts that don't have a Given Name. Garbage Contact.

          if searchText == nil {
            // Add all Contacts if no searchText is provided.
            cNContacts.append(cNContact)
          }
          else {
            // If the Contact contains the search string then add it.
            if self.contactContainsText( cNContact, searchText: searchText! ) {
              cNContacts.append(cNContact)
            }
          }
        }
      }

      var contacts = [NSDictionary]();

      for cNContact in cNContacts {
        contacts.append( convertCNContactToDictionary(cNContact) )
      }

      callback([NSNull(), contacts])
    }
    catch let error as NSError {
      NSLog("Problem getting unified Contacts")
      NSLog(error.localizedDescription)

      callback([error.localizedDescription, NSNull()])
    }

  }

这里是字典转换器:

func convertCNContactToDictionary(cNContact: CNContact) -> NSDictionary {

        var contact = [String: AnyObject]()
        let phoneNumbers = NSMutableArray()

        contact["identifier"]         = cNContact.identifier
        contact["givenName"]          = cNContact.givenName
        contact["familyName"]         = cNContact.familyName
        contact["imageDataAvailable"] = cNContact.imageDataAvailable

        if (cNContact.imageDataAvailable) {
          let thumbnailImageDataAsBase64String = cNContact.thumbnailImageData!.base64EncodedStringWithOptions([])
          contact["thumbnailImageData"] = thumbnailImageDataAsBase64String

    //      let imageDataAsBase64String = cNContact.imageData!.base64EncodedStringWithOptions([])
    //      contact["imageData"] = imageDataAsBase64String
        }

        if (cNContact.isKeyAvailable(CNContactPhoneNumbersKey)) {
          for number in cNContact.phoneNumbers {
            var numbers = [String: AnyObject]()
            let phoneNumber = (number.value as! CNPhoneNumber).valueForKey("digits") as! String
            let countryCode = (number.value as! CNPhoneNumber).valueForKey("countryCode") as? String
            let label = CNLabeledValue.localizedStringForLabel(number.label)
            numbers["number"] = phoneNumber
            numbers["countryCode"] = countryCode
            numbers["label"] = label
            phoneNumbers.addObject(numbers)
          }
          contact["phoneNumbers"] = phoneNumbers
        }

        let contactAsNSDictionary = contact as NSDictionary

        return contactAsNSDictionary;
      }

编辑

所以我在我的模拟器中添加了一堆联系人并且可以重现崩溃.

So I add a bunch of contacts in my simulator and can reproduce the crash.

这是堆栈跟踪:

 libswiftCore.dylib`function signature specialization <Arg[0] = Exploded, Arg[1] = Exploded, Arg[2] = Dead, Arg[3] = Dead> of Swift._fatalErrorMessage (Swift.StaticString, Swift.StaticString, Swift.StaticString, Swift.UInt) -> ():
    0x107e73180 <+0>:   pushq  %rbp
    0x107e73181 <+1>:   movq   %rsp, %rbp
    0x107e73184 <+4>:   pushq  %rbx
    0x107e73185 <+5>:   pushq  %rax
    0x107e73186 <+6>:   movq   %rcx, %r10
    0x107e73189 <+9>:   testb  $0x1, %dl
    0x107e7318c <+12>:  jne    0x107e731aa               ; <+42>
    0x107e7318e <+14>:  testq  %rsi, %rsi
    0x107e73191 <+17>:  js     0x107e731f9               ; <+121>
    0x107e73193 <+19>:  addq   %rdi, %rsi
    0x107e73196 <+22>:  movzbl %r9b, %eax
    0x107e7319a <+26>:  movq   %r10, %rdx
    0x107e7319d <+29>:  movq   %r8, %rcx
    0x107e731a0 <+32>:  movl   %eax, %r8d
    0x107e731a3 <+35>:  callq  0x107eccea0               ; function signature specialization <Arg[0] = Exploded, Arg[1] = Exploded> of Swift.(_fatalErrorMessage (Swift.StaticString, Swift.StaticString, Swift.StaticString, Swift.UInt) -> ()).(closure #2)
->  0x107e731a8 <+40>:  ud2    
    0x107e731aa <+42>:  movq   $0x0, -0x10(%rbp)
    0x107e731b2 <+50>:  movl   %edi, %eax
    0x107e731b4 <+52>:  cmpq   %rax, %rdi
    0x107e731b7 <+55>:  jne    0x107e73303               ; <+387>
    0x107e731bd <+61>:  cmpl   $0xd7ff, %edi             ; imm = 0xD7FF 
    0x107e731c3 <+67>:  ja     0x107e73222               ; <+162>
    0x107e731c5 <+69>:  xorl   %esi, %esi
    0x107e731c7 <+71>:  cmpl   $0x80, %edi
    0x107e731cd <+77>:  movl   $0x0, %r11d
    0x107e731d3 <+83>:  jb     0x107e732f6               ; <+374>
    0x107e731d9 <+89>:  movl   %edi, %r11d
    0x107e731dc <+92>:  shrl   $0x6, %r11d
    0x107e731e0 <+96>:  cmpl   $0x800, %edi              ; imm = 0x800 
    0x107e731e6 <+102>: jae    0x107e7329b               ; <+283>
    0x107e731ec <+108>: orb    $-0x40, %r11b
    0x107e731f0 <+112>: xorl   %esi, %esi
    0x107e731f2 <+114>: xorl   %ebx, %ebx
    0x107e731f4 <+116>: jmp    0x107e732c6               ; <+326>
    0x107e731f9 <+121>: leaq   0xd3d92(%rip), %rdi       ; "fatal error"
    0x107e73200 <+128>: leaq   0xd3f89(%rip), %rcx       ; "UnsafeBufferPointer with negative count"
    0x107e73207 <+135>: movl   $0xb, %esi
    0x107e7320c <+140>: movl   $0x2, %edx
    0x107e73211 <+145>: movl   $0x27, %r8d
    0x107e73217 <+151>: movl   $0x2, %r9d
    0x107e7321d <+157>: callq  0x107e73180               ; <+0>
    0x107e73222 <+162>: cmpl   $0xe000, %edi             ; imm = 0xE000 
    0x107e73228 <+168>: jb     0x107e73272               ; <+242>
    0x107e7322a <+170>: cmpl   $0x110000, %edi           ; imm = 0x110000 
    0x107e73230 <+176>: jae    0x107e73352               ; <+466>
    0x107e73236 <+182>: movl   %edi, %r11d
    0x107e73239 <+185>: shrl   $0x6, %r11d
    0x107e7323d <+189>: movl   %edi, %eax
    0x107e7323f <+191>: shrl   $0xc, %eax
    0x107e73242 <+194>: cmpl   $0xffff, %edi             ; imm = 0xFFFF 
    0x107e73248 <+200>: jbe    0x107e732a0               ; <+288>
    0x107e7324a <+202>: movl   %edi, %ecx
    0x107e7324c <+204>: shrl   $0x12, %ecx
    0x107e7324f <+207>: orl    $0xf0, %ecx
    0x107e73255 <+213>: movzbl %cl, %edx
    0x107e73258 <+216>: cmpl   %edx, %ecx
    0x107e7325a <+218>: jne    0x107e73303               ; <+387>
    0x107e73260 <+224>: andb   $0x3f, %al
    0x107e73262 <+226>: orb    $-0x80, %al
    0x107e73264 <+228>: movzbl %cl, %edx
    0x107e73267 <+231>: movq   %rdx, -0x10(%rbp)
    0x107e7326b <+235>: movl   $0x1, %esi
    0x107e73270 <+240>: jmp    0x107e732a6               ; <+294>
    0x107e73272 <+242>: leaq   0xd3d19(%rip), %rdi       ; "fatal error"
    0x107e73279 <+249>: leaq   0xd4a80(%rip), %rcx       ; "high- and low-surrogate code points are not valid Unicode scalar values"
    0x107e73280 <+256>: movl   $0xb, %esi
    0x107e73285 <+261>: movl   $0x2, %edx
    0x107e7328a <+266>: movl   $0x47, %r8d
    0x107e73290 <+272>: movl   $0x2, %r9d
    0x107e73296 <+278>: callq  0x107e73180               ; <+0>
    0x107e7329b <+283>: movl   %edi, %eax
    0x107e7329d <+285>: shrl   $0xc, %eax
    0x107e732a0 <+288>: orb    $-0x20, %al
    0x107e732a2 <+290>: xorl   %esi, %esi
    0x107e732a4 <+292>: xorl   %edx, %edx
    0x107e732a6 <+294>: leaq   (,%rsi,8), %rcx
    0x107e732ae <+302>: andb   $0x3f, %r11b
    0x107e732b2 <+306>: orb    $-0x80, %r11b
    0x107e732b6 <+310>: movzbl %al, %ebx
    0x107e732b9 <+313>: shlq   %cl, %rbx
    0x107e732bc <+316>: orq    %rdx, %rbx
    0x107e732bf <+319>: movq   %rbx, -0x10(%rbp)
    0x107e732c3 <+323>: incq   %rsi
    0x107e732c6 <+326>: movl   $0x8, %ecx
    0x107e732cb <+331>: movq   %rsi, %rax
    0x107e732ce <+334>: mulq   %rcx
    0x107e732d1 <+337>: jo     0x107e73303               ; <+387>
    0x107e732d3 <+339>: cmpq   $0x3f, %rax
    0x107e732d7 <+343>: ja     0x107e73329               ; <+425>
    0x107e732d9 <+345>: andl   $0x3f, %edi
    0x107e732dc <+348>: orq    $0x80, %rdi
    0x107e732e3 <+355>: movzbl %r11b, %r11d
    0x107e732e7 <+359>: movb   %al, %cl
    0x107e732e9 <+361>: shlq   %cl, %r11
    0x107e732ec <+364>: orq    %rbx, %r11
    0x107e732ef <+367>: movq   %r11, -0x10(%rbp)
    0x107e732f3 <+371>: incq   %rsi
    0x107e732f6 <+374>: movl   $0x8, %ecx
    0x107e732fb <+379>: movq   %rsi, %rax
    0x107e732fe <+382>: mulq   %rcx
    0x107e73301 <+385>: jno    0x107e73305               ; <+389>
    0x107e73303 <+387>: ud2    
    0x107e73305 <+389>: cmpq   $0x40, %rax
    0x107e73309 <+393>: jae    0x107e73329               ; <+425>
    0x107e7330b <+395>: movzbl %dil, %edx
    0x107e7330f <+399>: movb   %al, %cl
    0x107e73311 <+401>: shlq   %cl, %rdx
    0x107e73314 <+404>: orq    %r11, %rdx
    0x107e73317 <+407>: movq   %rdx, -0x10(%rbp)
    0x107e7331b <+411>: leaq   -0x10(%rbp), %rdi
    0x107e7331f <+415>: leaq   0x1(%rsi,%rdi), %rsi
    0x107e73324 <+420>: jmp    0x107e73196               ; <+22>
    0x107e73329 <+425>: leaq   0xd3c62(%rip), %rdi       ; "fatal error"
    0x107e73330 <+432>: leaq   0xd3df9(%rip), %rcx       ; "shift amount is larger than type size in bits"
    0x107e73337 <+439>: movl   $0xb, %esi
    0x107e7333c <+444>: movl   $0x2, %edx
    0x107e73341 <+449>: movl   $0x2d, %r8d
    0x107e73347 <+455>: movl   $0x2, %r9d
    0x107e7334d <+461>: callq  0x107e73180               ; <+0>
    0x107e73352 <+466>: leaq   0xd3c39(%rip), %rdi       ; "fatal error"
    0x107e73359 <+473>: leaq   0xd49f0(%rip), %rcx       ; "value is outside of Unicode codespace"
    0x107e73360 <+480>: movl   $0xb, %esi
    0x107e73365 <+485>: movl   $0x2, %edx
    0x107e7336a <+490>: movl   $0x25, %r8d
    0x107e73370 <+496>: movl   $0x2, %r9d
    0x107e73376 <+502>: callq  0x107e73180               ; <+0>
    0x107e7337b <+507>: nopl   (%rax,%rax)

我不知道为什么会发生这种情况.

I don't know why this happens though.

推荐答案

我会检查缩略图图像数据是否为 ​​nil,在这种情况下忽略它.可能记录被标记为有缩略图,但由于某种原因无法加载,例如不兼容的图像类型.

I would check if thumbnailImageData is nil and ignore it in that case. It's possible that a record is marked as having a thumbnail but it can't be loaded for some reason, like an incompatible image type.

这篇关于获取时应用程序崩溃 &gt;800 个使用 iOS 9 联系人框架的联系人的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆