> ## 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.

# Inicio rápido de macOS

> Agregue el SDK de C de PlayFab Services a un proyecto de Xcode en macOS y realice su primera llamada a la API de PlayFab mediante la biblioteca cliente nativa de C.

# Inicio rápido: macOS

Introducción al SDK de PlayFab Services para macOS. Siga estos pasos para incluir las bibliotecas en su proyecto y probar el código de ejemplo de las funciones básicas de PlayFab.

Este inicio rápido le ayuda a realizar su primera llamada a la API de PlayFab con el SDK de macOS. Antes de continuar, asegúrese de haber completado los pasos de [Inicio rápido: Game Manager](/services/playfab/live-service-management/gamemanager/quickstart), que garantizan que tiene una cuenta de PlayFab y que está familiarizado con Game Manager de PlayFab.

## Requisitos

* Una [cuenta de desarrollador de PlayFab](https://developer.playfab.com).
* IDE de [XCode](https://developer.apple.com/xcode/) instalado.

## Configuración del proyecto

Descargue el SDK de PlayFab para macOS en su proyecto desde la [página de versiones del SDK de PlayFab](https://github.com/PlayFab/PlayFabCSdk/releases/latest).

### Integración del SDK de C de PlayFab en su propio proyecto

#### Adición de archivos binarios al juego

Después de obtener los archivos binarios mediante descarga o compilándolos a partir del código fuente, debería poder integrarlos fácilmente en su juego o aplicación. Debe agregar los siguientes archivos binarios al juego:

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

Siga estas instrucciones para agregarlos:

1. En XCode, vaya al destino que desee y selecciónelo.

2. En la sección **General**, desplácese hacia abajo y, en la sección "**Frameworks, Libraries, and Embedded Content**", seleccione el signo "**+**".

3. Busque sus archivos binarios de **PlayFabServices** / **PlayFabCore** / **HttpClient** y seleccione las carpetas xcframework. (*También puede seleccionar una biblioteca específica si navega dentro de las carpetas xcframework, pero se recomienda importar el paquete xcframework, ya que funcionará tanto para compilaciones de dispositivo como de simulador.*)

4. Después de importar correctamente los archivos binarios, HttpClient\_macOS, PlayFabCore\_macOS y PlayFabServices\_macOS aparecen en Frameworks, Libraries, and Embedded Content.

#### Adición de rutas de búsqueda de encabezados

Una vez agregados los archivos binarios, deberá asegurarse de que las rutas de búsqueda de encabezados también estén configuradas correctamente.

1. Vaya a su proyecto.

2. Seleccione "**Build Settings**" y, después, busque "**Header Search Paths**".

3. Actualice el valor de la propiedad para incluir los encabezados del SDK. Agregue una referencia a los encabezados que se encuentran en la carpeta **include**. Ejemplo:
   ```
   PlayFabCSdk-macOS/include
   ```

## Inicialización e inicio de sesión

Siga los pasos siguientes para hacer funcionar algunas llamadas de ejemplo de PlayFab:

### Encabezados

Incluya **PFServices.h** para obtener acceso a toda la funcionalidad de PlayFab incluida.

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

### Inicialización

La inicialización de PlayFab requiere dos llamadas de función: **PFServicesInitialize** y **PFServiceConfigCreateHandle**. El resultado de esta inicialización es un **PFServiceConfigHandle**. Proporcione este identificador a una llamada de inicio de sesión posterior para dirigir la llamada al título correcto en el back-end de 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);
```

### Inicio de sesión

Una vez que tenga un **PFServiceConfigHandle**, puede usarlo para realizar una llamada de inicio de sesión de jugador. En el SDK, use un método **PFAuthenticationLoginWith\*Async** como **PFAuthenticationLoginWithAppleAsync**. Esta función le permite iniciar la sesión de un jugador en PlayFab mediante un **token de identidad de un usuario de Apple**. (*Consulte la documentación de Apple sobre la [autenticación de usuarios con Sign in with Apple](https://developer.apple.com/documentation/sign_in_with_apple/sign_in_with_apple_rest_api/authenticating_users_with_sign_in_with_apple)*).

Después de realizar una llamada de inicio de sesión, puede comprobar el estado de la llamada con **XAsyncGetStatus**. El estado comienza como **E\_PENDING** y cambia a **S\_OK** una vez que la llamada se completa correctamente. Si la llamada produce un error por algún motivo, el estado refleja ese error. El control de errores en todas las llamadas de PlayFab Services funciona de esta manera.

Junto con un resultado **S\_OK**, recibe un **PFEntityHandle**. Use este identificador para realizar llamadas posteriores a PlayFab como el jugador que inició sesión. Incluye todo el material necesario para autenticarse en el servicio de PlayFab como ese jugador.

```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);
```

## Llamadas al servicio

Después de que el jugador inicie sesión, ya puede realizar llamadas al back-end de PlayFab. Este es un ejemplo de una llamada para obtener los archivos almacenados en PlayFab para el jugador actual.

### Obtención de EntityKey

Algo que puede resultar útil para algunas llamadas a PlayFab es conocer la **PFEntityKey** del jugador. Una vez que tenga un **PFEntityToken**, puede recuperar una **PFEntityKey** con **PFEntityGetEntityKey**.

```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);
```

### Llamada a GetFiles

Todas las llamadas de PlayFab siguen un patrón similar: preparar el objeto de solicitud, realizar la llamada (mediante el **PFEntityHandle** del inicio de sesión), crear un objeto para recibir la respuesta y, después, llamar a una función **GetResult** para rellenar el contenedor recién creado.

```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);
```

## Limpieza

Cuando el juego esté listo para cerrarse o necesite limpiar PlayFab por algún otro motivo, asegúrese de cerrar todos los identificadores abiertos y llamar a **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
```

## Patrón de API asincrónica

El SDK de PlayFab Services sigue el [modelo de programación asincrónica](https://learn.microsoft.com/en-us/gaming/gdk/_content/gc/system/overviews/async-programming-model) implementado en el GDK. Este modelo de programación implica el uso de tareas y colas de tareas proporcionadas por la [biblioteca XAsync](/build/core-features/common/async/async-libraries/async-library-xasync). Este modelo es coherente con otras funciones y extensiones del GDK (como la API de XBOX Services). Aunque presenta cierta complejidad, también aporta un alto grado de control sobre las operaciones asincrónicas.

En este ejemplo se muestra cómo realizar una llamada asincrónica a **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
    }

```

## Control de errores

Las operaciones **XAsync** completadas devuelven códigos de estado HTTP. Un código de estado de error se manifiesta como un **HRESULT** de error, como **HTTP\_E\_STATUS\_NOT\_FOUND**, al llamar a **XAsyncGetStatus()** o a una de las API **PF\*Get()**.

Para ver los mensajes de error detallados que devuelve el servicio, consulte la sección siguiente sobre depuración. Estos mensajes de error detallados pueden ser útiles durante el desarrollo para comprender mejor cómo reacciona el servicio de PlayFab a las solicitudes del cliente.

## Depuración

La manera más fácil de ver los resultados y depurar las llamadas en el SDK de PlayFab Services es habilitar el [seguimiento de depuración](/services/playfab/sdks/c/tracing). Habilitar el seguimiento de depuración le permite ver los resultados en la ventana de salida del depurador y conectar los resultados a los registros propios de su juego.

## Consulte también

[Documentación de referencia de la API](/services/playfab/api-references/c/pfauthentication/pfauthentication_members)


## Related topics

- [PlayFab Services para macOS](/es/services/playfab/sdks/platforms/macos.md)
- [Inicio rápido de NodeJS](/es/services/playfab/sdks/nodejs/quickstart.md)
- [Inicio rápido de Lua para Corona](/es/services/playfab/sdks/lua/quickstart-corona.md)
- [Inicio rápido de Lua para Defold](/es/services/playfab/sdks/lua/quickstart-defold.md)
- [Inicio rápido de Linux](/es/services/playfab/sdks/c/quickstart-linux.md)
