> For the complete documentation index, see [llms.txt](https://developers-apps-in-toss.toss.im/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://developers-apps-in-toss.toss.im/documentation/api-and-sdk-zh/common/permission/contact.md).

# 联系人

{% hint style="info" %}
**需要进行权限设置**

`fetchContacts`在使用之前，需要先设置联系人权限。请先查看权限设置指南。
{% endhint %}

***

### 获取联系人

**SDK 函数：** `fetchContacts`

`fetchContacts`是按页获取用户联系人列表的函数。

**签名**

```typescript
function fetchContacts(options: {
  size: number;
  offset: number;
  query?: {
    contains?: string;
  };
}): Promise<ContactResult>;
```

**参数**

* **options** · 必填

  获取联系人时指定的选项对象。

  * **options.size** · 必填

    一次获取的联系人数量。例如，传入 10 时，最多会获取 10 个联系人。
  * **options.offset** · 必填

    是要获取的联系人的起始位置。首次调用时请传入 `0`。之后请使用上一次调用返回的 `nextOffset` 值。

    * **options.query** · 必填

      是额外的筛选选项。

      * **options.query.contains** · 必填

        用于只获取姓名中包含特定字符串的联系人。不传入此值时，将获取所有联系人。

**属性**

* openPermissionDialog

  显示一个重新请求联系人读取权限的对话框。用户可以选择“允许”、“仅允许一次”或“不允许”。如果选择“允许”或“仅允许一次”，则 `allowed`返回 `denied`会返回。
* getPermission

  返回联系人读取权限的当前状态。 `allowed`表示用户已允许联系人读取权限。 `denied`表示用户已拒绝联系人读取权限。 `notDetermined`表示用户从未请求过联系人读取权限。如果在 Toss 应用设置中联系人权限被拒绝，则 `osPermissionDenied`会返回。

**返回值**

* `Promise<ContactResult>`

返回包含联系人列表和分页信息的对象。

* `result`：获取到的联系人列表。
* `nextOffset`：下一次调用使用的偏移值。如果没有更多联系人可获取，则 `null`。
* `done`：表示是否已获取所有联系人。如果全部获取完了，则 `true`。

### 联系人权限错误

**错误类型：** `FetchContactsPermissionError`

在联系人权限被拒绝时发生的错误。发生错误时 `error instanceof FetchContactsPermissionError`可以通过它确认。

**签名**

```typescript
class FetchContactsPermissionError extends PermissionError {
  constructor();
}
```

**示例**

**获取包含特定字符串的联系人列表**

这是获取联系人列表的示例。按下“查看权限”按钮来确认当前的联系人读取权限。如果用户拒绝了权限或系统限制了权限时， `FetchContactsPermissionError`会返回。按下“请求权限”按钮可以请求联系人读取权限。

{% tabs %}
{% tab title="js" %}

```js
import { fetchContacts, FetchContactsPermissionError } from '@apps-in-toss/web-framework';

async function handleFetchContacts() {
  try {
    const response = await fetchContacts({
      size: 10,
      offset: 0,
      query: { contains: '김' },
    });

    return response;
  } catch (error) {
    if (error instanceof FetchContactsPermissionError) {
      console.log('没有联系人读取权限');
    }
    console.error('获取联系人失败：', error);
  }
}

async function handleGetPermissionForFetchContacts() {
  const permission = await fetchContacts.getPermission();
  return permission;
}

async function handleOpenPermissionDialogForFetchContacts() {
  const permission = await fetchContacts.openPermissionDialog();
  return permission;
}
```

{% endtab %}

{% tab title="React" %}

```tsx
import { ContactEntity, fetchContacts, FetchContactsPermissionError } from '@apps-in-toss/web-framework';
import { useState } from 'react';

function ContactsList() {
  const [contacts, setContacts] = useState<{
    result: ContactEntity[];
    nextOffset: number | null;
    done: boolean;
  }>({
    result: [],
    nextOffset: null;
    done: false;
  });

  const handlePress = async () => {
    try {
      if (contacts.done) {
        console.log('已获取所有联系人。');
        return;
      }

      const response = await fetchContacts({
        size: 10,
        offset: contacts.nextOffset ?? 0,
        query: { contains: '김' },
      });
      setContacts((prev) => ({
        result: [...prev.result, ...response.result],
        nextOffset: response.nextOffset,
        done: response.done,
      }));
    } catch (error) {
      if (error instanceof FetchContactsPermissionError) {
        console.log('没有联系人读取权限');
      }
      console.error('获取联系人失败：', error);
    }
  };

  return (
    <div>
      {contacts.result.map((contact, index) => (
        <span key={index}>
          {contact.name}: {contact.phoneNumber}
        </span>
      ))}
      <input
        type="button"
        value={contacts.done ? '已获取所有联系人。' : '获取下一批联系人'}
        disabled={contacts.done}
        onClick={handlePress}
      />
      <input
        type="button"
        value="查看权限"
        onClick={async () => {
          const permission = await fetchContacts.getPermission();
          alert(permission);
        }}
      />
      <input
        type="button"
        value="请求权限"
        onClick={async () => {
          const permission = await fetchContacts.openPermissionDialog();
          alert(permission);
        }}
      />

  );
}
```

{% endtab %}

{% tab title="React Native" %}

```tsx
import { ContactEntity, fetchContacts, FetchContactsPermissionError } from '@apps-in-toss/framework';
import { useState } from 'react';
import { Alert, Button, Text, View } from 'react-native';

function ContactsList() {
  const [contacts, setContacts] = useState<{
    result: ContactEntity[];
    nextOffset: number | null;
    done: boolean;
  }>({
    result: [],
    nextOffset: null;
    done: false;
  });

  const handlePress = async () => {
    try {
      if (contacts.done) {
        console.log('已获取所有联系人。');
        return;
      }

      const response = await fetchContacts({
        size: 10,
        offset: contacts.nextOffset ?? 0,
        query: { contains: '김' },
      });
      setContacts((prev) => ({
        result: [...prev.result, ...response.result],
        nextOffset: response.nextOffset,
        done: response.done,
      }));
    } catch (error) {
      if (error instanceof FetchContactsPermissionError) {
        console.log('没有联系人读取权限');
      }
      console.error('获取联系人失败：', error);
    }
  };

  return (
    <View>
      {contacts.result.map((contact, index) => (
        <Text key={index}>
          {contact.name}: {contact.phoneNumber}
        </Text>
      ))}
      <Button
        title={contacts.done ? '已获取所有联系人。' : '获取下一批联系人'}
        disabled={contacts.done}
        onPress={handlePress}
      />
      <Button
        title="查看权限"
        onPress={async () => {
          const permission = await fetchContacts.getPermission();
          Alert.alert(permission);
        }}
      />
      <Button
        title="请求权限"
        onPress={async () => {
          const permission = await fetchContacts.openPermissionDialog();
          Alert.alert(permission);
        }}
      />
    </View>
  );
}
```

{% endtab %}
{% endtabs %}


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://developers-apps-in-toss.toss.im/documentation/api-and-sdk-zh/common/permission/contact.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
