web-dev-qa-db-ja.com

ABPersonViewControllerとABPeoplePickerNavigationControllerを正しく使用して連絡先情報を表示するにはどうすればよいですか?

アップデート9/2/10:このコードはiOS 4アップデートの時点で機能しなくなり、内部アサーションで失敗します。 「QuickContacts」と呼ばれるiPhoneSDKリファレンスライブラリで利用できる優れたアドレス帳APIの例があります。

サンプルコードはこちらから入手できます。この問題の解決に役立ちます: http://developer.Apple.com/iphone/library/samplecode/QuickContacts/Introduction/Intro.html


ユーザーがABPeoplePickerNavigationControllerから連絡先を選択できる機能をアプリに追加しようとしています。これにより、ABPersonViewController彼らが選んだ連絡先に対応します。その時点で、ユーザーが連絡先の電話番号をクリックして、アプリがカスタム動作で応答できるようにしたいと思います。

ABPeoplePickerNavigationControllerは正常に機能していますが、ABPersonViewControllerの表示で問題が発生しています。 ABPersonViewControllerを画面上でうまくアニメーション化できますが、連絡先の写真、名前、会社名しか表示されません。連絡先の他のフィールドは表示されません。

ABPersonViewControllerの 'displayedProperties'要素を使用して、電話番号を表示するようにプログラムに指示しています。これにより、奇妙な動作が発生します。電話番号が割り当てられていない連絡先を選択すると、その連絡先はバックグラウンドで「電話番号なし」と表示されます(予想どおり)が、電話番号がある連絡先を選択すると、取得するのは空白の連絡先ページ(「電話番号なし」のテキストなし)。

これは、PersonViewControllerクラスを作成するために使用しているABPeoplePickerNavigationControllerデリゲートクラスのメソッドです。これはABPersonViewControllerインターフェース:

- (BOOL) peoplePickerNavigationController:(ABPeoplePickerNavigationController *)peoplePicker shouldContinueAfterSelectingPerson:(ABRecordRef)person {

    BOOL returnState = NO;

    PersonViewController *personView = [[PersonViewController alloc] init];
    [personView displayContactInfo:person];

    [peoplePicker pushViewController:personView animated:YES];

    [personView release];

    return returnState;
}

これが私のPersonViewController.hヘッダーファイルです:

#import <UIKit/UIKit.h>
#import <Foundation/Foundation.h>
#import <AddressBookUI/AddressBookUI.h>

@interface PersonViewController : UIViewController <ABPersonViewControllerDelegate> 
{

}

- (void) displayContactInfo: (ABRecordRef)person;

@end

最後に、これが私のPersonViewController.mで、選択した連絡先を表示するためのABPersonViewControllerを作成しています。

#import "PersonViewController.h"

@implementation PersonViewController

- (void) displayContactInfo: (ABRecordRef)person
{
    ABPersonViewController *personController = [[ABPersonViewController alloc] init];

    personController.personViewDelegate = self;
    personController.allowsEditing = NO;
    personController.displayedPerson = person;
    personController.addressBook = ABAddressBookCreate();

    personController.displayedProperties = [NSArray arrayWithObjects:
            [NSNumber numberWithInt:kABPersonPhoneProperty], 
            nil];

    [self setView:personController.view];

    [[self navigationController] pushViewController:personController animated:YES];
    [personController release];
}

- (BOOL) personViewController:(ABPersonViewController*)personView shouldPerformDefaultActionForPerson:(ABRecordRef)person property:(ABPropertyID)property identifier:(ABMultiValueIdentifier)identifierForValue
{
    return YES;
}


@end

クリック可能な電話番号フィールドの代わりに、この空白の連絡先画面が表示される理由について誰かが知っていますか?


了解しました。問題の発見に近づいていると思います。上記のdisplayContactInfo呼び出しのこの部分にあると確信しています。

[self setView:personController.view];

この行を省略すると、連絡先をクリックしたときに表示されるのは空白の画面だけです。 ABPeoplePickerNavigationControllerは、PersonViewControllerをNavigationControllerスタックにプッシュしています。次に、PersonViewControllerはABPersonViewControllerオブジェクトをインスタンス化しますが、何らかの理由でABPersonViewControllerがNavigationControllerスタックに適切に追加されることはありません。

PersonViewControllerだけでなく、ABPersonViewControllerをスタックに追加する方法を知っている人はいますか?

19
Jason Machacek

この問題に自分で遭遇した人への注意:以下のように、デリゲートのviewDidLoad()メソッドでABPersonViewControllerをインスタンス化することにより、正しい動作を生成することができました。

前と同じように、これが私のABPeoplePickerNavigationControllerデリゲートのメソッドです:

- (BOOL) peoplePickerNavigationController:(ABPeoplePickerNavigationController *)peoplePicker shouldContinueAfterSelectingPerson:(ABRecordRef)person
{
    BOOL returnState = NO;

    PersonViewController *personView = [[PersonViewController alloc] init];

    [peoplePicker pushViewController:personView animated:YES];
    [personView displayContactInfo:person];

    [personView release];

    return returnState;
}

これが私のPersonViewController.h(ABPersonViewControllerデリゲート)ヘッダーファイルです:

#import <UIKit/UIKit.h>
#import <Foundation/Foundation.h>
#import <AddressBookUI/AddressBookUI.h>

@interface PersonViewController : UIViewController <ABPersonViewControllerDelegate> 
{
    ABPersonViewController *personController;
}

- (void) displayContactInfo: (ABRecordRef)person;

@end

最後に、これがデリゲートの実装(PersonViewController.m):です。

#import "PersonViewController.h"

@implementation PersonViewController

- (void) viewDidLoad
{
}

- (void) viewDidUnload
{
    [personController release];
}

- (void) displayContactInfo: (ABRecordRef)person
{
    personController = [[ABPersonViewController alloc] init];
    [personController setDisplayedPerson:person];
    [personController setPersonViewDelegate:self];
    [personController setAllowsEditing:NO];
    personController.addressBook = ABAddressBookCreate();   

    personController.displayedProperties = [NSArray arrayWithObjects:
        [NSNumber numberWithInt:kABPersonPhoneProperty], 
        nil];

    [self setView:personController.view];
}

- (BOOL) personViewController:(ABPersonViewController*)personView shouldPerformDefaultActionForPerson:(ABRecordRef)person property:(ABPropertyID)property identifier:(ABMultiValueIdentifier)identifierForValue
{
    // This is where you pass the selected contact property elsewhere in your program
    [[self navigationController] dismissModalViewControllerAnimated:YES];
    return NO;
}

@end

うまくいけば、これは誰かのために役立つことになります。 AddressBook UIフレームワークは、頭を包み込むのが少し難しいものでした(ただし、私はiPhone開発に慣れていないので、iPhoneプログラム編成の微妙な違いをまだ学んでいます)。

9
Jason Machacek