2014-07-20 8 views
13

मुझे समझ में नहीं आता कि मेरा कोड स्विफ्ट से संकलित क्यों नहीं है।स्विफ्ट के साथ पता पुस्तिका संपर्क कैसे प्राप्त करें?

मैं इस ऑब्जेक्टिव-सी कोड में परिवर्तित करने कोशिश कर रहा हूँ:

CFErrorRef error = NULL; 
ABAddressBookRef addressBook = ABAddressBookCreateWithOptions(NULL, &error); 

    if (addressBook != nil) { 
    NSLog(@"Succesful."); 

    NSArray *allContacts = (__bridge_transfer NSArray *)ABAddressBookCopyArrayOfAllPeople(addressBook); 
} 

यह स्विफ्ट में मेरे वर्तमान गायन है:

var error:CFErrorRef 
var addressBook = ABAddressBookCreateWithOptions(nil, nil); 

if (addressBook != nil) { 
    println("Succesful."); 

    var allContacts:CFArrayRef = ABAddressBookCopyArrayOfAllPeople(addressBook); 
} 

लेकिन, Xcode रिपोर्ट:

'अप्रबंधित 'परिवर्तनीय नहीं है' CFArrayRef '

क्या आपके पास कोई विचार है?

उत्तर

24

जाहिर है, यदि आईओएस संस्करण 9 या उससे अधिक का लक्ष्यीकरण करते हैं, तो आपको AddressBook फ्रेमवर्क का उपयोग नहीं करना चाहिए, और इसके बजाय Contacts फ्रेमवर्क का उपयोग करना चाहिए।

तो,

  1. आयात Contacts:

    import Contacts 
    
  2. अपने Info.plist में एक NSContactsUsageDescription आपूर्ति करने के लिए सुनिश्चित करें।

  3. फिर, आप संपर्कों तक पहुंच सकते हैं। जैसे स्विफ्ट 3 में:

    let status = CNContactStore.authorizationStatus(for: .contacts) 
    if status == .denied || status == .restricted { 
        presentSettingsActionSheet() 
        return 
    } 
    
    // open it 
    
    let store = CNContactStore() 
    store.requestAccess(for: .contacts) { granted, error in 
        guard granted else { 
         DispatchQueue.main.async { 
          self.presentSettingsActionSheet() 
         } 
         return 
        } 
    
        // get the contacts 
    
        var contacts = [CNContact]() 
        let request = CNContactFetchRequest(keysToFetch: [CNContactIdentifierKey as NSString, CNContactFormatter.descriptorForRequiredKeys(for: .fullName)]) 
        do { 
         try store.enumerateContacts(with: request) { contact, stop in 
          contacts.append(contact) 
         } 
        } catch { 
         print(error) 
        } 
    
        // do something with the contacts array (e.g. print the names) 
    
        let formatter = CNContactFormatter() 
        formatter.style = .fullName 
        for contact in contacts { 
         print(formatter.string(from: contact) ?? "???") 
        } 
    } 
    

    func presentSettingsActionSheet() { 
        let alert = UIAlertController(title: "Permission to Contacts", message: "This app needs access to contacts in order to ...", preferredStyle: .actionSheet) 
        alert.addAction(UIAlertAction(title: "Go to Settings", style: .default) { _ in 
         let url = URL(string: UIApplicationOpenSettingsURLString)! 
         UIApplication.shared.open(url) 
        }) 
        alert.addAction(UIAlertAction(title: "Cancel", style: .cancel)) 
        present(alert, animated: true) 
    } 
    

AddressBook ढांचे के लिए मेरे मूल जवाब कहाँ से नीचे है।


टिप्पणियों के एक जोड़े:

  • आप ABAddressBookCreateWithOptions की error पैरामीटर का उपयोग करने, इसे परिभाषित चाहते हैं Unmanaged<CFError>? किया जाना है।

  • यदि यह विफल हो जाता है, तो त्रुटि ऑब्जेक्ट पर एक नज़र डालें (takeRetainedValue कर रहा है ताकि आप रिसाव न करें)।

  • पता पुस्तिका के takeRetainedValue को भी सुनिश्चित करें, ताकि आप रिसाव न करें।

  • आपको शायद संपर्कों को पकड़ना नहीं चाहिए, लेकिन आपको शायद पहले अनुमति का अनुरोध करना चाहिए।

पुलिंग कि सभी को एक साथ आपको मिलता है:

// make sure user hadn't previously denied access 

let status = ABAddressBookGetAuthorizationStatus() 
if status == .Denied || status == .Restricted { 
    // user previously denied, so tell them to fix that in settings 
    return 
} 

// open it 

var error: Unmanaged<CFError>? 
guard let addressBook: ABAddressBook? = ABAddressBookCreateWithOptions(nil, &error)?.takeRetainedValue() else { 
    print(error?.takeRetainedValue()) 
    return 
} 

// request permission to use it 

ABAddressBookRequestAccessWithCompletion(addressBook) { granted, error in 
    if !granted { 
     // warn the user that because they just denied permission, this functionality won't work 
     // also let them know that they have to fix this in settings 
     return 
    } 

    if let people = ABAddressBookCopyArrayOfAllPeople(addressBook)?.takeRetainedValue() as? NSArray { 
     // now do something with the array of people 
    } 
} 
+1

अप्रबंधित ? एक बहुत अच्छी टिप थी। इसके बाकी के लिए भी धन्यवाद। –

संबंधित मुद्दे