Как приложение SquareCase от Square автоматически заполняет данные пользователя из адресной книги? - PullRequest
21 голосов
/ 03 ноября 2011

Новое iOS-приложение Square для карт имеет функцию «Создать учетную запись».Нажмите на нее, и она покажет форму, которую ВЫПОЛНЯЕТСЯ записью пользователя из адресной книги.

Как это возможно?Кто-нибудь знает?Я думал, что это невозможно, чтобы получить информацию о пользователе таким образом.На самом деле это не iOS 5.0.

Ответы [ 5 ]

55 голосов
/ 09 ноября 2011

единственное решение, которое я мог придумать, это использовать имя устройства и затем искать в адресной книге совпадение. это предполагает, что кто-то будет использовать конкретное соглашение об именах. Я, например, в качестве имени своего устройства использую iPhone от Nik. Я также единственный ник в моей адресной книге, поэтому для моего сценария хорошо использовать текст до ' в качестве имени владельца.

В нем используется очень удобная оболочка для ABAddressBook от Эрики Садун, ABContactHelper . Я оставил код перечисления вместо использования индекса массива в 0, так как, скорее всего, будет возвращено небольшое количество совпадений, чтобы вы могли расширяться, чтобы дать пользователю возможность выбрать «свои» данные. Что, хотя и не совсем соответствует квадратному решению, работает хорошо. IMHO.

NSString *firstname;
NSString *lastname;

NSString *ownerName = [[UIDevice currentDevice] name];

NSRange t = [ownerName rangeOfString:@"'s"];
if (t.location != NSNotFound) {
    ownerName = [ownerName substringToIndex:t.location];
} 

NSArray *matches = [ABContactsHelper contactsMatchingName:ownerName];
if(matches.count == 1){ 
    for (ABContact *contact in matches){
        firstname = [contact firstname];
        lastname = [contact lastname];

    }
}
23 голосов
/ 25 апреля 2013

Поскольку изменения требуют, чтобы приложения запрашивали разрешения на доступ к адресной книге, этот метод больше не работает . Ответ Ника Бёрнса работал отлично, но ему нужен доступ к адресной книге.

Я скачал Square Wallet (который является преемником ссылок на Square Card Case в первоначальном вопросе), и он больше не заполняет форму регистрации. Путь также используется для выполнения трюка с адресной книгой имени устройства, но он также больше не заполняет форму регистрации.

Используя описанный выше метод, вы все равно можете предварительно заполнить форму регистрации после , запрашивающей доступ к контактам , но она теряет желаемый "магический" опыт.

1 голос
/ 20 января 2016

У меня была такая же проблема, но в Swift, я воспользовался предложением Nik Burns и написал об этом в блоге: http://paulpeelen.com/2016/01/20/prefill-an-signup-form-in-ios-using-swift-and-cncontact/

Это в основном конечный результат в Swift:

import Contacts

...

    @IBOutlet weak var nameFirst: UILabel!
    @IBOutlet weak var nameLast: UILabel!
    @IBOutlet weak var email: UILabel!
    @IBOutlet weak var phoneNo: UILabel!
    @IBOutlet weak var address: UILabel!

    /**
     Search the addressbook for the contact
     */
    private func getMe() {
        let ownerName = getOwnerName()
        let store = CNContactStore()

        do {
            // Ask permission from the addressbook and search for the user using the owners name
            let contacts = try store.unifiedContactsMatchingPredicate(CNContact.predicateForContactsMatchingName(ownerName), keysToFetch:[CNContactGivenNameKey, CNContactFamilyNameKey, CNContactPhoneNumbersKey, CNContactPostalAddressesKey, CNContactEmailAddressesKey])

            //assuming contain at least one contact
            if let contact = contacts.first {
                // Checking if phone number is available for the given contact.
                if (contact.isKeyAvailable(CNContactPhoneNumbersKey)) {
                    // Populate the fields
                    populateUsingContact(contact)
                } else {
                    //Refetch the keys
                    let keysToFetch = [CNContactGivenNameKey, CNContactFamilyNameKey, CNContactPhoneNumbersKey, CNContactPostalAddressesKey, CNContactEmailAddressesKey]
                    let refetchedContact = try store.unifiedContactWithIdentifier(contact.identifier, keysToFetch: keysToFetch)

                    // Populate the fields
                    populateUsingContact(refetchedContact)
                }
            }
        } catch let e as NSError {
            print(e.localizedDescription)
        }

    }

    /**
     Get the device owners name

     - returns: The owners name
     */
    private func getOwnerName() -> String {
        // Get the device owners name
        var ownerName = UIDevice.currentDevice().name.trimmedString.stringByReplacingOccurrencesOfString("'", withString: "")
        // Get the model of the device
        let model = UIDevice.currentDevice().model

        // Remove the device name from the owners name
        if let t = ownerName.rangeOfString("s \(model)") {
            ownerName = ownerName.substringToIndex(t.startIndex)
        }

        return ownerName.trimmedString
    }

    /**
     Populate the fields using a contact

     - parameter contact: The contact to use
     */
    private func populateUsingContact(contact: CNContact) {
        // Set the name fields
        nameFirst.text = contact.givenName
        nameLast.text = contact.familyName

        // Check if there is an address available, it might be empty
        if (contact.isKeyAvailable(CNContactPostalAddressesKey)) {
            if let
                addrv = contact.postalAddresses.first,
                addr = addrv.value as? CNPostalAddress where addrv.value is CNPostalAddress
            {
                let address = "\(addr.street)\n\(addr.postalCode) \(addr.city)\n\(addr.country)"
                self.address.text = address
            }
        }

        // Check if there is a phonenumber available, it might be empty
        if (contact.isKeyAvailable(CNContactPhoneNumbersKey)) {
            if let
                phonenumberValue = contact.phoneNumbers.first,
                pn = phonenumberValue.value as? CNPhoneNumber where phonenumberValue.value is CNPhoneNumber
            {
                phoneNo.text = pn.stringValue
            }
        }
    }

И расширение:

extension String {

    /// Trim a string
    var trimmedString: String {
        return stringByTrimmingCharactersInSet(NSCharacterSet.whitespaceAndNewlineCharacterSet())
    }

}
1 голос
/ 15 января 2016

Поскольку меня не устраивало использование имени устройства, я решил использовать первую запись адресной книги, которая соответствует «ME»

ABAddressBookRef addressBook = ABAddressBookCreate( );
CFArrayRef allPeople = ABAddressBookCopyArrayOfAllPeople( addressBook );
ABRecordRef ref = CFArrayGetValueAtIndex( allPeople, 0 );
ABContact * contact = [ABContact contactWithRecord:ref];
0 голосов
/ 03 ноября 2011

Нет, вы можете

http://developer.apple.com/library/ios/#documentation/ContactData/Conceptual/AddressBookProgrammingGuideforiPhone/Introduction.html#//apple_ref/doc/uid/TP40007744

Я знаю, что это было доступно в 4.X; не только функция 5.0 ... Не уверен, что она была доступна раньше.

...