> ## Documentation Index
> Fetch the complete documentation index at: https://devdocs.xbox.com/llms.txt
> Use this file to discover all available pages before exploring further.

# 빠른 시작 macOS

> macOS의 Xcode 프로젝트에 PlayFab Services C SDK를 추가하고 네이티브 C 클라이언트 라이브러리를 사용해 첫 PlayFab API 호출을 수행합니다.

# 빠른 시작: macOS

macOS용 PlayFab Services SDK를 시작해 보세요. 다음 단계에 따라 라이브러리를 프로젝트에 포함하고 기본 PlayFab 기능을 위한 샘플 코드를 시도해 보세요.

이 빠른 시작은 macOS SDK를 사용해 첫 번째 PlayFab API 호출을 수행하는 데 도움이 됩니다. 계속하기 전에 [빠른 시작: Game Manager](/services/playfab/live-service-management/gamemanager/quickstart)의 단계를 완료했는지 확인하세요. 이 단계에서는 PlayFab 계정이 있고 PlayFab Game Manager에 익숙한지 확인합니다.

## 요구 사항

* [PlayFab 개발자 계정](https://developer.playfab.com).
* [XCode](https://developer.apple.com/xcode/) IDE 설치됨.

## 프로젝트 설정

[PlayFab SDK 릴리스 페이지](https://github.com/PlayFab/PlayFabCSdk/releases/latest)에서 PlayFab macOS SDK를 프로젝트에 다운로드하세요.

### 자체 프로젝트에 PlayFab C SDK 통합

#### 게임에 바이너리 추가

다운로드하거나 소스에서 빌드하여 바이너리를 얻은 후, 게임/앱에 쉽게 통합할 수 있습니다. 게임에 다음 바이너리를 추가해야 합니다:

* HttpClient\_macOS.xcframework
* PlayFabCore\_macOS.xcframework
* PlayFabServices\_macOS.xcframework

추가하려면 다음 지침을 따르세요:

1. XCode에서 원하는 대상으로 이동하여 선택합니다.

2. **General** 섹션에서 아래로 스크롤하고 "**Frameworks, Libraries, and Embedded Content**" 섹션에서 "**+**" 기호를 선택합니다.

3. **PlayFabServices** / **PlayFabCore** / **HttpClient** 바이너리를 검색하고 xcframework 폴더를 선택합니다. (*xcframework 폴더 내부로 이동하여 특정 라이브러리를 선택할 수도 있지만, 장치 및 시뮬레이터 빌드 모두에서 작동하므로 xcframework 번들을 가져오는 것이 권장됩니다.*)

4. 바이너리 HttpClient\_macOS, PlayFabCore\_macOS 및 PlayFabServices\_macOS를 성공적으로 가져온 후에는 Frameworks, Libraries, and Embedded Content 아래에 나열됩니다.

#### 헤더 검색 경로 추가

바이너리를 추가한 후에는 헤더 검색 경로도 올바르게 설정되어 있는지 확인해야 합니다.

1. 프로젝트로 이동합니다.

2. "**Build Settings**"를 선택하고 "**Header Search Paths**"를 검색합니다.

3. 속성 값을 업데이트하여 SDK 헤더를 포함시킵니다. **include** 폴더에서 찾은 헤더에 대한 참조를 추가합니다. 예:
   ```
   PlayFabCSdk-macOS/include
   ```

## 초기화 및 로그인

다음 단계에 따라 일부 PlayFab 샘플 호출을 작동시켜 보세요:

### 헤더

포함된 모든 PlayFab 기능에 액세스하려면 \_\_PFServices.h\_\_를 포함합니다.

```cpp theme={null}
#include <playfab/services/PFServices.h>
```

### 초기화

PlayFab 초기화에는 \_\_PFServicesInitialize\_\_와 **PFServiceConfigCreateHandle** 두 함수 호출이 필요합니다. 이 초기화의 결과가 \_\_PFServiceConfigHandle\_\_입니다. 이 핸들을 이후 로그인 호출에 제공하여 PlayFab 백엔드의 올바른 타이틀로 호출을 지시합니다.

```cpp theme={null}
    HRESULT hr = PFServicesInitialize(nullptr); // Add your own error handling when FAILED(hr) == true

    PFServiceConfigHandle serviceConfigHandle{ nullptr };

    hr = PFServiceConfigCreateHandle(
            "https://ABCDEF.playfabapi.com",    // PlayFab API endpoint - obtained in the Game Manager
            "ABCDEF",                           // PlayFab Title id - obtained in the Game Manager
            &serviceConfigHandle);
```

### 로그인

\_\_PFServiceConfigHandle\_\_을 얻은 후에는 이를 사용해 플레이어 로그인 호출을 수행할 수 있습니다. SDK에서는 \_\_PFAuthenticationLoginWithAppleAsync\_\_와 같은 **PFAuthenticationLoginWith\*Async** 메서드를 사용합니다. 이 함수를 사용하면 \_\_Apple 사용자의 자격 증명 토큰\_\_을 사용해 플레이어를 PlayFab에 로그인할 수 있습니다. (*[Apple로 로그인을 사용해 사용자 인증하기](https://developer.apple.com/documentation/sign_in_with_apple/sign_in_with_apple_rest_api/authenticating_users_with_sign_in_with_apple)에 대한 Apple 설명서를 참조하세요*).

로그인 호출을 수행한 후 \_\_XAsyncGetStatus\_\_로 호출 상태를 확인할 수 있습니다. 상태는 \_\_E\_PENDING\_\_으로 시작하여 호출이 성공적으로 완료된 후 \_\_S\_OK\_\_로 변경됩니다. 어떤 이유로 호출이 실패하면 상태에 해당 실패가 반영됩니다. 모든 PlayFab Services 호출에 대한 오류 처리는 이 방식으로 작동합니다.

**S\_OK** 결과와 함께 \_\_PFEntityHandle\_\_을 다시 받게 됩니다. 이 핸들을 사용해 로그인된 플레이어로서 이후의 PlayFab 호출을 수행합니다. 여기에는 해당 플레이어로 PlayFab 서비스에 인증하는 데 필요한 모든 자료가 포함됩니다.

```cpp theme={null}
PFAuthenticationLoginWithAppleRequest request{};
request.createAccount = true;
request.identityToken = identityToken; // A user identity token obtained from Apple

XAsyncBlock async{};
hr = PFAuthenticationLoginWithAppleAsync(serviceConfigHandle, &request, &async); // Add your own error handling when FAILED(hr) == true
hr = XAsyncGetStatus(&async, true); // This is doing a blocking wait for completion, but you can use the XAsyncBlock to set a callback instead for async style usage

std::vector<char> loginResultBuffer;
PFAuthenticationLoginResult const* loginResult;
size_t bufferSize;
hr = PFAuthenticationLoginWithAppleGetResultSize(&async, &bufferSize);
loginResultBuffer.resize(bufferSize);

PFEntityHandle entityHandle{ nullptr };
hr = PFAuthenticationLoginWithAppleGetResult(&async, &entityHandle, loginResultBuffer.size(), loginResultBuffer.data(), &loginResult, nullptr);
```

## 서비스 호출

플레이어를 로그인한 후에는 이제 PlayFab 백엔드로 호출을 수행할 수 있습니다. 다음은 현재 플레이어에 대해 PlayFab에 저장된 파일을 가져오는 호출의 예입니다.

### EntityKey 가져오기

일부 PlayFab 호출에 유용할 수 있는 한 가지는 플레이어의 \_\_PFEntityKey\_\_를 아는 것입니다. \_\_PFEntityToken\_\_이 있으면 \_\_PFEntityGetEntityKey\_\_로 \_\_PFEntityKey\_\_를 검색할 수 있습니다.

```cpp theme={null}
    PFEntityKey const* pEntityKey{};
    std::vector<char> entityKeyBuffer;
    size_t size{};
    HRESULT hr = PFEntityGetEntityKeySize(entityHandle, &size); // Add your own error handling when FAILED(hr) == true

    entityKeyBuffer.resize(size);
    hr = PFEntityGetEntityKey(entityHandle, entityKeyBuffer.size(), entityKeyBuffer.data(), &pEntityKey, nullptr);
```

### GetFiles 호출

모든 PlayFab 호출은 요청 객체를 준비하고, (로그인의 \_\_PFEntityHandle\_\_을 사용해) 호출을 수행하고, 응답을 받을 객체를 생성한 다음, **GetResult** 함수를 호출해 새로 생성된 컨테이너를 채우는 유사한 패턴을 따릅니다.

```cpp theme={null}
    XAsyncBlock async{};
    PFDataGetFilesRequest requestFiles{};
    requestFiles.entity = pEntityKey;

    HRESULT hr = PFDataGetFilesAsync(entityHandle, &requestFiles, &async); // Add your own error handling when FAILED(hr) == true
    hr = XAsyncGetStatus(&async, true); // This is doing a blocking wait for completion, but you can use the XAsyncBlock to set a callback instead for async style usage

    size_t resultSize;
    hr = PFDataGetFilesGetResultSize(&async, &resultSize);

    std::vector<char> getFilesResultBuffer(resultSize);
    PFDataGetFilesResponse* getFilesResponseResult{ nullptr };
    hr = PFDataGetFilesGetResult(&async, getFilesResultBuffer.size(), getFilesResultBuffer.data(), &getFilesResponseResult, nullptr);
```

## 정리

게임이 종료될 준비가 되었거나 다른 이유로 PlayFab을 정리해야 하는 경우, 열려 있는 모든 핸들을 닫고 \_\_PFServicesUninitializeAsync\_\_를 호출해야 합니다.

```cpp theme={null}
    PFEntityCloseHandle(entityHandle);
    entityHandle = nullptr;

    PFServiceConfigCloseHandle(serviceConfigHandle);
    serviceConfigHandle = nullptr;

    XAsyncBlock async{};
    HRESULT hr = PFServicesUninitializeAsync(&async); // Add your own error handling when FAILED(hr) == true
    hr = XAsyncGetStatus(&async, true); // This is doing a blocking wait for completion, but you can use the XAsyncBlock to set a callback instead for async style usage
```

## 비동기 API 패턴

PlayFab Services SDK는 GDK에서 구현된 [비동기 프로그래밍 모델](https://learn.microsoft.com/en-us/gaming/gdk/_content/gc/system/overviews/async-programming-model)을 따릅니다. 이 프로그래밍 모델은 [XAsync 라이브러리](/build/core-features/common/async/async-libraries/async-library-xasync)에서 제공하는 Tasks와 Task Queues 사용을 포함합니다. 이 모델은 다른 GDK 함수 및 확장(예: XBOX Services API)과 일관성이 있습니다. 약간의 복잡성을 도입하지만, 비동기 작업에 대한 높은 수준의 제어도 제공합니다.

이 예제는 \_\_PFDataGetFilesAsync\_\_에 대한 비동기 호출을 수행하는 방법을 보여줍니다.

```cpp theme={null}
    auto async = std::make_unique<XAsyncBlock>();
    async->callback = [](XAsyncBlock* async)
    {
        std::unique_ptr<XAsyncBlock> asyncBlockPtr{ async }; // take ownership of XAsyncBlock

        size_t resultSize;
        HRESULT hr = PFDataGetFilesGetResultSize(async, &resultSize);
        if (SUCCEEDED(hr))
        {
            std::vector<char> getFilesResultBuffer(resultSize);
            PFDataGetFilesResponse* getFilesResponseResult{ nullptr };
            PFDataGetFilesGetResult(async, getFilesResultBuffer.size(), getFilesResultBuffer.data(), &getFilesResponseResult, nullptr);
        }
    };

    PFDataGetFilesRequest requestFiles{};
    requestFiles.entity = m_pEntityKey;
    HRESULT hr = PFDataGetFilesAsync(m_entityHandle, &requestFiles, async.get());
    if (SUCCEEDED(hr))
    {
        async.release(); // at this point, the callback will be called so release the unique ptr
    }

```

## 오류 처리

완료된 **XAsync** 작업은 HTTP 상태 코드를 반환합니다. 오류 상태 코드는 **XAsyncGetStatus()** 또는 **PF\*Get()** API 중 하나를 호출할 때 **HTTP\_E\_STATUS\_NOT\_FOUND**와 같은 실패 **HRESULT**로 나타납니다.

서비스에서 반환된 자세한 오류 메시지를 보려면 디버깅에 대한 다음 섹션을 참조하세요. 이러한 자세한 오류 메시지는 개발 중에 PlayFab 서비스가 클라이언트의 요청에 어떻게 반응하는지 더 잘 이해하는 데 유용할 수 있습니다.

## 디버깅

PlayFab Services SDK에서 결과를 확인하고 호출을 디버그하는 가장 쉬운 방법은 [디버그 추적](/services/playfab/sdks/c/tracing)을 활성화하는 것입니다. 디버그 추적을 활성화하면 디버거 출력 창에서 결과를 확인하고 게임의 자체 로그에 결과를 후킹할 수 있습니다.

## 참고 항목

[API 참조 문서](/services/playfab/api-references/c/pfauthentication/pfauthentication_members)


## Related topics

- [PlayFab 지원 플랫폼](/ko/services/playfab/sdks/platforms/index.md)
- [PlayFab 지원 언어](/ko/services/playfab/sdks/languages/index.md)
- [macOS용 PlayFab Services](/ko/services/playfab/sdks/platforms/macos.md)
- [NodeJS 빠른 시작](/ko/services/playfab/sdks/nodejs/quickstart.md)
- [PlayFab Party SDKs](/ko/services/playfab/multiplayer/networking/party-sdks/overview.md)
