The JSON utility library already features a “pretty” writer, you just need to implement your own write blueprint function.
You can use this one:
KFJsonUtils.hpp
// Fill out your copyright notice in the Description page of Project Settings.
#pragma once
#include "CoreMinimal.h"
#include "Kismet/BlueprintFunctionLibrary.h"
#include "KFJsonUtils.generated.h"
/**
*
*/
UCLASS()
class KFPS_API UKFJsonUtils : public UBlueprintFunctionLibrary
{
GENERATED_BODY()
public:
/** Creates a file from the provided JsonObject. */
UFUNCTION(BlueprintCallable, Category="Json", meta = (DisplayName = "KF Save Json to File"))
static UPARAM(DisplayName="Success") bool KFJsonToFile(const FJsonObjectWrapper& JsonObject, const FFilePath& File, bool bIsPrettyPrint = true);
/** Creates a Json string from the provided JsonObject. */
UFUNCTION(BlueprintCallable, Category="Json", meta = (DisplayName = "Get Json String"))
static UPARAM(DisplayName="Success") bool KFJsonToString(const FJsonObjectWrapper& JsonObject, UPARAM(DisplayName="String") FString& OutJsonString, bool bIsPrettyPrint);
private:
static bool JsonObjectToStringPretty(const FJsonObjectWrapper& JsonObject, FString& Str);
static bool JsonObjectToStringCondensed(const FJsonObjectWrapper& JsonObject, FString& Str);
};
KFJsonUtils.cpp
// Fill out your copyright notice in the Description page of Project Settings.
#include "KFJsonUtils.h"
#include "JsonObjectWrapper.h"
bool UKFJsonUtils::KFJsonToFile(const FJsonObjectWrapper& JsonObject, const FFilePath& File, bool bIsPrettyPrint)
{
if (!FPaths::DirectoryExists(FPaths::GetPath(File.FilePath)))
{
FFrame::KismetExecutionMessage(*FString::Printf(TEXT("Directory not found: %s"), *FPaths::GetPath(File.FilePath)), ELogVerbosity::Error);
return false;
}
if (File.FilePath.IsEmpty())
{
FFrame::KismetExecutionMessage(*FString::Printf(TEXT("FileName cannot be empty")), ELogVerbosity::Error);
return false;
}
if (FString JsonString; KFJsonToString(JsonObject, JsonString, bIsPrettyPrint))
{
const bool& bResult = FFileHelper::SaveStringToFile(JsonString, *File.FilePath);
if (!bResult)
{
FFrame::KismetExecutionMessage(*FString::Printf(TEXT("Failed to save JSON to file. %s"), *JsonString), ELogVerbosity::Error);
}
return bResult;
}
return false;
}
bool UKFJsonUtils::KFJsonToString(const FJsonObjectWrapper& JsonObject, FString& OutJsonString, bool bIsPrettyPrint)
{
if(bIsPrettyPrint)
{
if (!JsonObjectToStringPretty(JsonObject, OutJsonString))
{
FFrame::KismetExecutionMessage(TEXT("Failed to convert JSON Object to string"), ELogVerbosity::Error);
return false;
}
}
else
{
if (!JsonObjectToStringCondensed(JsonObject, OutJsonString))
{
FFrame::KismetExecutionMessage(TEXT("Failed to convert JSON Object to string"), ELogVerbosity::Error);
return false;
}
}
return true;
}
bool UKFJsonUtils::JsonObjectToStringPretty(const FJsonObjectWrapper& JsonObject, FString& Str)
{
TSharedRef<TJsonWriter<>> JsonWriter = TJsonWriterFactory<>::Create(&Str, 0);
TSharedRef<FJsonObject> ptr = MakeShared<FJsonObject>(*JsonObject.JsonObject.Get());
return FJsonSerializer::Serialize(ptr, JsonWriter, true);
}
bool UKFJsonUtils::JsonObjectToStringCondensed(const FJsonObjectWrapper& JsonObject, FString& Str)
{
TSharedRef<TJsonWriter<TCHAR, TCondensedJsonPrintPolicy<TCHAR>>> JsonWriter = TJsonWriterFactory<TCHAR, TCondensedJsonPrintPolicy<TCHAR>>::Create(&Str, 0);
TSharedRef<FJsonObject> ptr = MakeShared<FJsonObject>(*JsonObject.JsonObject.Get());
return FJsonSerializer::Serialize(ptr, JsonWriter, true);
}