Setup Social APIs #

Before you can use the Friend and Presence APIs, you must initialize the services. This step will synchronize friend/presence information between the client and the Connect backend.

The Initialize APIs can only be called after login. Upon logout, the service is un-initialized and the On* action-handlers are unbound. You must call initialize() on the service when you log back in.

Initialize services #

The initialize functions set up client side caches.

This guide is based on an example Unreal project using the Third Person Unreal C++ project template. The example project is named ‘Narwhal’, update references accordingly.

Source\Narwhal\NarwhalPlayerController.h


DECLARE_DYNAMIC_MULTICAST_DELEGATE(FFriendListDelegate);

// ...
class NARWHAL_API ANarwhalPlayerController : public APlayerController
{
    GENERATED_BODY()

public:
    // ...

	UFUNCTION(Exec)
	void InitSocialApis();

    FFriendListDelegate OnConnectFriendListChanged;

    // ...
private:
    // ...

    // add to FriendApi events
	void HandleFriendApiInitialized(TPragmaResult<> Result);
	void OnFriendChangedEvent(const FPragmaFriend& Friend);
	void OnFriendInviteReceivedEvent(const FPragmaFriendOverview& PragmaFriendOverview);
	void OnFriendUpdate(TPragmaResult<> Result);
	void OnFriendListChanged(const UPragmaFriendApi::FFriendList& FriendList);
	void OnInvitesChangedInternal(const TMap<FString, FPragmaFriendOverview>& Friends);
};

Source\Narwhal\NarwhalPlayerController.cpp

void ANarwhalPlayerController::InitSocialApis() {
  Player->FriendApi().Initialize(FOnCompleteDelegate::CreateUObject(
      this, &ANarwhalPlayerController::HandleFriendApiInitialized));

  Player->FriendApi().Initialize(
      FOnCompleteDelegate::CreateLambda([](const TPragmaResult<> &Result) {
        if (Result.IsFailure()) {
          UE_LOG(LogTemp, Error, TEXT("API Failure - %s"),
                 *Result.Error().ToString());
        }
      }));

  Player->PresenceApi().Initialize(
      FOnCompleteDelegate::CreateLambda([](const TPragmaResult<> &Result) {
        if (Result.IsFailure()) {
          UE_LOG(LogTemp, Error, TEXT("API Failure - %s"),
                 *Result.Error().ToString());
        }
      }));
}


void ANarwhalPlayerController::HandleFriendApiInitialized(
    TPragmaResult<> Result) {

  if (Result.IsFailure()) {
    UE_LOG(LogTemp, Display,
           TEXT("Presence API failed initialize with error: %s"),
           *Result.Failure().GetErrorAsString());
    return;
  }

  Player->FriendApi().OnFriendUpdated.AddUObject(
      this, &ANarwhalPlayerController::OnFriendChangedEvent);
  Player->FriendApi().OnFriendInviteReceived.AddUObject(
      this, &ANarwhalPlayerController::OnFriendInviteReceivedEvent);
  Player->FriendApi().OnFriendsListChanged.AddUObject(
      this, &ANarwhalPlayerController::OnFriendListChanged);
  Player->FriendApi().OnReceivedInvitesChanged.AddUObject(
      this, &ANarwhalPlayerController::OnInvitesChangedInternal);
  Player->FriendApi().OnSentInvitesChanged.AddUObject(
      this, &ANarwhalPlayerController::OnInvitesChangedInternal);
}

void ANarwhalPlayerController::OnFriendUpdate(
	TPragmaResult<> Result) {
	if (Result.IsFailure()) {
		UE_LOG(LogTemp, Error,
			   TEXT("API Failure - %s"),
			   *Result.Error().ToString());
		return;
	}
	OnConnectFriendListChanged.Broadcast();
}

void ANarwhalPlayerController::OnFriendChangedEvent(
    const FPragmaFriend &Friend) {
	OnConnectFriendListChanged.Broadcast();
}
void ANarwhalPlayerController::OnFriendInviteReceivedEvent(
    const FPragmaFriendOverview &PragmaFriendOverview) {
	OnConnectFriendListChanged.Broadcast();
}
void ANarwhalPlayerController::OnFriendListChanged(
    const UPragmaFriendApi::FFriendList &Friends) {
	OnConnectFriendListChanged.Broadcast();
}
void ANarwhalPlayerController::OnInvitesChangedInternal(
    const TMap<FString, FPragmaFriendOverview> &Friends) {
	OnConnectFriendListChanged.Broadcast();
}        

Force sync #

You can use the ForceSync APIs to reset the client side cache.

Source\Narwhal\NarwhalPlayerController.h

// ...
class NARWHAL_API ANarwhalPlayerController : public APlayerController
{
    GENERATED_BODY()

public:
    // ...

	UFUNCTION(Exec)
	void ForceSyncFriends();

    UFUNCTION(Exec)
	void ForceSyncPresence();

    // ...
};

Source\Narwhal\NarwhalPlayerController.cpp

void ANarwhalPlayerController::ForceSyncFriends() {
	Player->FriendApi().ForceSync(
		FOnCompleteDelegate::CreateLambda([](const TPragmaResult<> &_) {
		  /*
		   * Possible Events that could trigger:
		   * OnSentInvitesChanged
		   * OnReceivedInvitesChanged
		   * OnFriendsListChanged
		   * OnPresenceChanged
		   */
		}));
}
void ANarwhalPlayerController::ForceSyncPresence() {
	Player->PresenceApi().ForceSync(
		FOnCompleteDelegate::CreateLambda([](const TPragmaResult<> &_) {}));
}