카테고리 없음
Unity와 iOS 네이티브 코드 연동하여 iCloud 데이터 저장 구현하기
wolstar
2024. 8. 22. 22:42
Unity 게임 개발에서 iCloud와 같은 iOS 고유 기능을 활용하려면, iOS 네이티브 API를 Unity와 연동해야 합니다. 이 글에서는 iOS의 네이티브 코드를 작성하고 이를 Unity C# 코드와 연결하여 iCloud 데이터를 저장하고 불러오는 방법을 설명하겠습니다.
iOS 네이티브 코드 구현
먼저, iOS 네이티브 코드를 Objective-C로 작성합니다. 이 코드는 iCloud에 데이터를 저장하고 불러오는 기능을 제공합니다.
Objective-C 클래스 구현 ,네이티브 함수와 Unity 연동
Objective-C로 작성한 iOS 네이티브 코드를 Unity에서 호출할 수 있도록 외부 함수로 노출해야 합니다. 이를 위해 extern "C"를 사용하여 C# 코드에서 호출 가능한 형태로 함수를 정의합니다.
iCloudManager.mm
#import <Foundation/Foundation.h>
#import <AVFoundation/AVFoundation.h>
@interface iOSPlugin : NSObject
@end
@implementation iOSPlugin
// iOS에서 다른 오디오가 재생 중인지 확인하는 함수
+(bool)IsAudioPlaying
{
return [[AVAudioSession sharedInstance] isOtherAudioPlaying];
}
// iCloud에서 데이터를 불러오는 함수
+(NSString *)GetiCloudData:(NSString *)key
{
// 데이터를 가져오기 전에 iCloud와 동기화
[[NSUbiquitousKeyValueStore defaultStore] synchronize];
NSUbiquitousKeyValueStore *cloudStore = [NSUbiquitousKeyValueStore defaultStore];
return [cloudStore objectForKey:key];
}
// iCloud에 데이터를 저장하는 함수
+(BOOL)SetiCloudData:(NSString *)key setValue:(NSString *)value
{
NSUbiquitousKeyValueStore *cloudStore = [NSUbiquitousKeyValueStore defaultStore];
[cloudStore setObject:value forKey:key];
// iCloud와 동기화 (비활성화됨)
return false;
}
// iCloud에서 모든 데이터를 삭제하는 함수
+(void)DeleteiCloudData()
{
NSUbiquitousKeyValueStore *cloudStore = [NSUbiquitousKeyValueStore defaultStore];
NSDictionary *dict = [cloudStore dictionaryRepresentation];
NSArray *allKeys = [dict allKeys];
for(int i = 0; i < allKeys.count; i++)
{
NSString *key = [allKeys objectAtIndex:i];
[cloudStore removeObjectForKey:key];
}
}
// iCloud 데이터를 강제로 동기화하는 함수
+(void)ForceSynciCloudData()
{
NSUbiquitousKeyValueStore *cloudStore = [NSUbiquitousKeyValueStore defaultStore];
[cloudStore synchronize];
}
// C 문자열을 반환하여 Unity가 메모리를 처리할 수 있도록 함
char* cStringCopy(const char* string)
{
if(string == NULL)
{
return NULL;
}
char* res = (char*)malloc(strlen(string) + 1);
strcpy(res, string);
return res;
}
@end
extern "C"
{
bool _IsDevicePlayingOtherAudio()
{
return [iOSPlugin IsAudioPlaying];
}
const char * _GetiCloudData(const char *key)
{
// NSString을 C 문자열로 변환하여 Unity에서 사용 가능하도록 함
return cStringCopy([[iOSPlugin GetiCloudData:[NSString stringWithUTF8String:key]] UTF8String]);
}
bool _SetiCloudData(const char *key, const char *value)
{
return [iOSPlugin SetiCloudData:[NSString stringWithUTF8String:key] setValue:[NSString stringWithUTF8String:value]];
}
void _DeleteiCloudData()
{
[iOSPlugin DeleteiCloudData];
}
void _ForceSynciCloudData()
{
[iOSPlugin ForceSynciCloudData];
}
}
네이티브 코드 설명
- IsAudioPlaying:
- AVAudioSession을 통해 현재 iOS 기기에서 다른 오디오가 재생 중인지 확인합니다.
- Unity에서 이 함수를 호출하면 게임이 실행 중일 때 다른 오디오가 재생되고 있는지 알 수 있습니다. 이를 통해 게임의 오디오 출력을 조정할 수 있습니다.
- GetiCloudData:
- 주어진 key를 사용하여 iCloud에 저장된 데이터를 가져옵니다.
- 데이터를 가져오기 전에 synchronize를 호출하여 iCloud와의 동기화를 보장합니다.
- 반환된 데이터는 NSString 형식으로, Unity에서는 C 문자열로 변환됩니다.
- SetiCloudData:
- 주어진 key와 value를 사용하여 iCloud에 데이터를 저장합니다.
- 데이터가 저장된 후 iCloud와의 동기화는 기본적으로 비활성화되어 있지만, 필요에 따라 활성화할 수 있습니다.
- DeleteiCloudData:
- iCloud에 저장된 모든 데이터를 삭제합니다.
- 이 함수는 dictionaryRepresentation을 사용하여 모든 키-값 쌍을 가져온 후, 각 키에 대해 removeObjectForKey를 호출하여 데이터를 삭제합니다.
- ForceSynciCloudData:
- iCloud 데이터를 강제로 동기화합니다.
- 이 함수는 수동으로 동기화를 강제하여, 데이터 동기화가 즉시 이루어지도록 합니다.
- cStringCopy:
- NSString을 C 문자열로 변환하여 Unity에서 메모리를 안전하게 관리할 수 있도록 합니다.
- 이 함수는 문자열 복사를 수행하여, Unity가 반환된 문자열을 자유롭게 사용할 수 있도록 합니다.
Unity에서 iOS 네이티브 함수 호출
이제 앞서 작성한 iOS 네이티브 코드를 Unity C#에서 호출할 수 있습니다. 아래의 C# 코드에서 네이티브 함수를 호출하는 방법을 확인할 수 있습니다.
public class iOSNativePlugin : MonoBehaviour
{
static string GAME_DATA_KEY => $"Game_Name";
#if UNITY_IOS && !UNITY_EDITOR
[DllImport("__Internal")]
private static extern bool _IsDevicePlayingOtherAudio();
[DllImport("__Internal")]
private static extern string _GetiCloudData(string key);
[DllImport("__Internal")]
private static extern bool _SetiCloudData(string key, string value);
[DllImport("__Internal")]
private static extern void _DeleteiCloudData();
[DllImport("__Internal")]
private static extern void _ForceSynciCloudData();
public static bool IsDevicePlayingOtherAudio()
{
return _IsDevicePlayingOtherAudio();
}
public static string GetiCloudData()
{
if (string.IsNullOrEmpty(_GetiCloudData(GAME_DATA_KEY)))
{
return "";
}
else
{
return System.Text.Encoding.UTF8.GetString(Convert.FromBase64String(_GetiCloudData(GAME_DATA_KEY)));
}
}
public static bool SetiCloudData(string value)
{
return _SetiCloudData(GAME_DATA_KEY, Convert.ToBase64String(System.Text.Encoding.UTF8.GetBytes(value)));
}
public static void DeleteiCloudData()
{
_DeleteiCloudData();
}
public static void ForceSynciCloudData()
{
_ForceSynciCloudData();
}
#else
public static bool IsDevicePlayingOtherAudio()
{
return false;
}
public static string GetiCloudData()
{
return "";
}
public static bool SetiCloudData(string value)
{
return false;
}
public static void DeleteiCloudData() { }
public static void ForceSynciCloudData() { }
#endif
}
Unity C# 코드 설명
- 플랫폼 전처리:
- #if UNITY_IOS && !UNITY_EDITOR는 iOS 환경에서만 네이티브 함수를 호출할 수 있도록 하며, Unity 에디터나 다른 플랫폼에서는 더미 함수가 대신 호출되도록 합니다.
- 네이티브 함수 호출:
- C#의 DllImport("__Internal")를 사용하여 네이티브 Objective-C 코드를 직접 호출합니다.
- 예를 들어, _IsDevicePlayingOtherAudio()는 IsAudioPlaying을 호출하여 오디오 재생 상태를 반환합니다.
- 데이터 저장 및 불러오기:
- GetiCloudData와 SetiCloudData 함수는 iCloud에서 데이터를 불러오고 저장하는 역할을 합니다.
- 저장된 데이터는 Base64 인코딩 후 저장되며, 불러올 때는 이를 디코딩하여 사용합니다.
- 데이터 동기화 및 삭제:
- ForceSynciCloudData와 DeleteiCloudData 함수는 iCloud 데이터의 동기화 및 삭제를 담당합니다.
Unity에서 iOS 네이티브 코드를 활용하여 iCloud 데이터 저장 기능을 구현하는 방법을 살펴보았습니다. 이와 같이 네이티브 코드를 연동하면, iOS 고유의 기능을 Unity 게임에 통합할 수 있습니다. iCloud를 통해 게임 데이터를 관리하면, 사용자는 여러 기기에서 동일한 데이터를 사용할 수 있어 보다 일관된 사용자 경험을 제공할 수 있습니다.