언리얼엔진5/각종 지식

[UE5] 구글 시트 불러와서 JSON 파싱하기

Rocketbabydolls 2024. 5. 27. 16:45

   프로젝트를 하다 구글 시트에서 데이터를 불러와야 할 일이 생겼다. 어찌어찌 GPT 의 도움을 받아 구현에 성공했지만 완전히 이해하지 못한 것 같아 블로그에 따로 정리하려 한다.

 

  오늘 가져올 시트는 아래와 같다.

 

간단하게 만든 구글 시트

 

 

// Fill out your copyright notice in the Description page of Project Settings.

#pragma once

#include "CoreMinimal.h"
#include "UObject/NoExportTypes.h"
#include "HttpModule.h"
#include "Interfaces/IHttpRequest.h"
#include "Interfaces/IHttpResponse.h"
#include "Json.h"
#include "JsonUtilities.h"
#include "PAHttpDownloadManager.generated.h"

/**
 * 
 */

DECLARE_DYNAMIC_MULTICAST_DELEGATE(FOnDataFetched);

UCLASS()
class PROJECTA_API UPAHttpDownloadManager : public UObject
{
	GENERATED_BODY()


public:

	UPAHttpDownloadManager();
	
	UFUNCTION(BlueprintCallable, Category = HTTP)
	void FetchGoogleSheetData();


	UPROPERTY()
	TMap<FString, float> DataMap;

	FOnDataFetched OnDataFetched;

protected:
	
	void OnResponseReceived(FHttpRequestPtr Request, FHttpResponsePtr Response, bool bWasSuccessful);



};

 

 

++)  당연히 build.cs 에서 모듈을 포함해줘야 한다.

 

 

 

 

 

UObject를 상속받는 HttpDownloader 클래스를 선언했다.

언리얼에서 제공하는 Http 모듈을 통해 간편하게 구현할 수 있다.

 

 

FetchGoogleSheetData();

  -> Http 요청으로 구글 시트에 요청 보내고 받아오는 메서드. request 완료 시 OnResponseReceived 를 호출한다.

OnResponseReceived();

  -> 본격적인 JSON 파싱 및 데이터 저장을 하는 메서드

 

void UPAHttpDownloadManager::FetchGoogleSheetData()
{
    // HTTP Module 가져오기
    FHttpModule* Http = &FHttpModule::Get();

    // HTTP Request 생성
    TSharedRef<IHttpRequest> Request = Http->CreateRequest();

    // Google Sheets API URL 설정
    FString GoogleSheetID = TEXT("아이디 입력");
    FString GoogleSheetRange = TEXT("Values");
    FString ApiKey = TEXT("api 키 입력");
    FString Url = FString::Printf(TEXT("https://sheets.googleapis.com/v4/spreadsheets/%s/values/%s?key=%s"), *GoogleSheetID, *GoogleSheetRange, *ApiKey);

    Request->SetURL(Url);
    Request->SetVerb("GET");
    Request->SetHeader(TEXT("Content-Type"), TEXT("application/json"));

    // Request 완료 시 콜백 설정
    Request->OnProcessRequestComplete().BindUObject(this, &UPAHttpDownloadManager::OnResponseReceived);

    // Request 실행
    Request->ProcessRequest();

    UE_LOG(LogTemp, Log, TEXT("UPAHttpDownloadManager Fetching Google Sheet Data"));
}

 

 

HTTP request가 마무리되면 onresponsereceived 를 델리게이트로 연결해서 실행시켜준다.

 

 

void UPAHttpDownloadManager::OnResponseReceived(FHttpRequestPtr Request, FHttpResponsePtr Response, bool bWasSuccessful)
{
    UE_LOG(LogTemp, Log, TEXT("UPAHttpDownloadManager OnResponseReceived start"));
    if (bWasSuccessful && Response.IsValid())
    {
        UE_LOG(LogTemp, Log, TEXT("UPAHttpDownloadManager OnResponseReceived valid"));
        FString ResponseString = Response->GetContentAsString();

        // JSON 파싱
        TSharedPtr<FJsonObject> JsonObject;
        TSharedRef<TJsonReader<>> Reader = TJsonReaderFactory<>::Create(ResponseString);

        if (FJsonSerializer::Deserialize(Reader, JsonObject) && JsonObject.IsValid())
        {
            UE_LOG(LogTemp, Log, TEXT("UPAHttpDownloadManager OnResponseReceived deserialized"));
            const TArray<TSharedPtr<FJsonValue>>* Rows;

            if (JsonObject->TryGetArrayField(TEXT("values"), Rows))
            {

                UE_LOG(LogTemp, Log, TEXT("UPAHttpDownloadManager getarrayfield"));
            

                for (const TSharedPtr<FJsonValue>& RowValue : *Rows)
                {
                    const TArray<TSharedPtr<FJsonValue>>& Row = RowValue->AsArray();
                    if (Row.Num() == 2)
                    {
                        FString Key = Row[0]->AsString();
                        float Value = FCString::Atof(*Row[1]->AsString());

                        DataMap.Add(Key, Value);

                       // UE_LOG(LogTemp, Log, TEXT("UPAHttpDownloadManager DataMap added: %s - %f"), *Key, Value);
                    }
                }

                // 데이터 로그 출력
                for (const TPair<FString, float>& Pair : DataMap)
                {
                    UE_LOG(LogTemp, Log, TEXT("%s: %f"), *Pair.Key, Pair.Value);
                }

                OnDataFetched.Broadcast();
            }
        }
        else
        {
            UE_LOG(LogTemp, Error, TEXT("Failed to deserialize JSON response"));
        }
    }
    else
    {
        UE_LOG(LogTemp, Error, TEXT("Failed to fetch Google Sheet data"));
    }
}

 

 

Http로부터 받아온 문자열을 열어서
JSON 파싱 후

JSON 배열 중 values 필드를 가져온다.

 

그리고 설계에 맞게 인코딩 후 원하는 자료구조에 넣어주면 된다.

 

 

 

데이터가 잘 들어오는 것을 확인할 수 있다.