언리얼엔진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 필드를 가져온다.
그리고 설계에 맞게 인코딩 후 원하는 자료구조에 넣어주면 된다.