Created
May 16, 2025 00:17
-
-
Save pbk20191/9e4df4b5db4e71f794098a02b356925c to your computer and use it in GitHub Desktop.
Post Notification using Apple NSNotificationCenter with Pure c# and CoreFoundation
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System; | |
using System.Runtime.InteropServices; | |
public static class AppleMessagesend { | |
#if UNITY_IOS || UNITY_EDITOR_OSX || UNITY_STANDALONE_OSX || UNITY_TVOS | |
const int kCFStringEncodingUTF8 = 0x08000100; | |
[DllImport("__Internal")] | |
static extern IntPtr CFStringCreateWithCString(IntPtr alloc, IntPtr cStr, int encoding); | |
[DllImport("__Internal")] | |
static extern void CFRelease(IntPtr cf); | |
[DllImport("__Internal")] | |
static extern void CFRetain(IntPtr cf); | |
[DllImport("__Internal")] | |
static extern IntPtr CFDataCreate(IntPtr allocator, byte[] bytes, long length); | |
[DllImport("__Internal")] | |
static extern void CFShow(IntPtr cfRef); | |
[DllImport("__Internal")] | |
static extern IntPtr CFPropertyListCreateWithData( | |
IntPtr allocator, | |
IntPtr data, | |
ulong options, | |
IntPtr format, // nullable | |
IntPtr* error // nullable | |
); | |
[DllImport("__Internal")] | |
static extern IntPtr CFNotificationCenterGetLocalCenter(); | |
[DllImport("__Internal")] | |
static extern void CFNotificationCenterPostNotification(IntPtr center, IntPtr name, IntPtr obj, IntPtr userInfo, bool deliverImmediately); | |
[DllImport("__Internal")] | |
static extern ulong CFDictionaryGetTypeID(); | |
[DllImport("__Internal")] | |
static extern ulong CFGetTypeID(IntPtr cf); | |
public static unsafe bool dispatchMessage(string @namespace, string plistString) | |
{ | |
if (string.IsNullOrEmpty(@namespace) || string.IsNullOrEmpty(plistString)) | |
return false; | |
IntPtr cfName = IntPtr.Zero; | |
IntPtr cfData = IntPtr.Zero; | |
IntPtr plist = IntPtr.Zero; | |
try | |
{ | |
{ | |
byte[] utf8Bytes = System.Text.Encoding.UTF8.GetBytes(@namespace); | |
Array.Resize(ref utf8Bytes, utf8Bytes.Length + 1); | |
fixed (byte* pUtf8 = utf8Bytes) | |
{ | |
cfName = CFStringCreateWithCString(IntPtr.Zero, (IntPtr)pUtf8, kCFStringEncodingUTF8); | |
if (cfName == IntPtr.Zero) return false; | |
} | |
} | |
// CFData for plist string | |
byte[] bytes = Encoding.UTF8.GetBytes(plistString); | |
cfData = CFDataCreate(IntPtr.Zero, bytes, bytes.Length); | |
if (cfData == IntPtr.Zero) return false; | |
// Parse plist | |
IntPtr* errorPtr = stackalloc IntPtr[1]; | |
errorPtr[0] = IntPtr.Zero; | |
plist = CFPropertyListCreateWithData(IntPtr.Zero, cfData, 0, IntPtr.Zero, errorPtr); | |
if (plist == IntPtr.Zero) | |
{ | |
#if UNITY_EDITOR | |
UnityEngine.Debug.LogWarning("[AppleMessagesend] Failed to parse plist."); | |
#endif | |
CFShow(*errorPtr); | |
CFRelease(*errorPtr); | |
return false; | |
} else if (CFGetTypeID(plist) != CFDictionaryGetTypeID()) | |
{ | |
#if UNITY_EDITOR | |
UnityEngine.Debug.LogWarning("[AppleMessagesend] plist is not a dictionary."); | |
#endif | |
CFShow(plist); | |
return false; | |
} | |
// Post | |
IntPtr center = CFNotificationCenterGetLocalCenter(); | |
CFNotificationCenterPostNotification(center, cfName, IntPtr.Zero, plist, true); | |
return true; | |
} | |
finally | |
{ | |
// Cleanup | |
if (cfName != IntPtr.Zero) CFRelease(cfName); | |
if (cfData != IntPtr.Zero) CFRelease(cfData); | |
if (plist != IntPtr.Zero) CFRelease(plist); | |
} | |
} | |
#else | |
public static bool dispatchMessage(string @namespace, string plistString) | |
{ | |
Debug.LogWarning("[AppleMessagesend] dispatchMessage is not supported on this platform."); | |
return false; | |
} | |
#endif | |
} | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment