2026-03-30 16:25:00 +08:00
using System.IO ;
using UnityEditor ;
using UnityEngine ;
#if UNITY_IOS
using UnityEditor.Callbacks ;
using UnityEditor.iOS.Xcode ;
#endif
namespace NativeGalleryNamespace
{
[System.Serializable]
public class Settings
{
private const string SAVE_PATH = "ProjectSettings/NativeGallery.json" ;
public bool AutomatedSetup = true ;
2026-08-07 16:14:10 +08:00
public string PhotoLibraryUsageDescription = "Allows you to choose photos from your library to set as your profile picture or attach to feedback reports. For example, select a photo when you tap your avatar in the profile page." ;
public string PhotoLibraryAdditionsUsageDescription = "Allows saving generated QR code images and downloaded videos to your photo library. For example, save a QR code to your library so you can share it with friends." ;
2026-03-30 16:25:00 +08:00
public bool DontAskLimitedPhotosPermissionAutomaticallyOnIos14 = true ; // See: https://mackuba.eu/2020/07/07/photo-library-changes-ios-14/
private static Settings m_instance = null ;
public static Settings Instance
{
get
{
if ( m_instance = = null )
{
try
{
if ( File . Exists ( SAVE_PATH ) )
m_instance = JsonUtility . FromJson < Settings > ( File . ReadAllText ( SAVE_PATH ) ) ;
else
m_instance = new Settings ( ) ;
}
catch ( System . Exception e )
{
Debug . LogException ( e ) ;
m_instance = new Settings ( ) ;
}
}
return m_instance ;
}
}
public void Save ( )
{
File . WriteAllText ( SAVE_PATH , JsonUtility . ToJson ( this , true ) ) ;
}
[SettingsProvider]
public static SettingsProvider CreatePreferencesGUI ( )
{
return new SettingsProvider ( "Project/yasirkula/Native Gallery" , SettingsScope . Project )
{
guiHandler = ( searchContext ) = > PreferencesGUI ( ) ,
keywords = new System . Collections . Generic . HashSet < string > ( ) { "Native" , "Gallery" , "Android" , "iOS" }
} ;
}
public static void PreferencesGUI ( )
{
EditorGUI . BeginChangeCheck ( ) ;
Instance . AutomatedSetup = EditorGUILayout . Toggle ( "Automated Setup" , Instance . AutomatedSetup ) ;
EditorGUI . BeginDisabledGroup ( ! Instance . AutomatedSetup ) ;
Instance . PhotoLibraryUsageDescription = EditorGUILayout . DelayedTextField ( "Photo Library Usage Description" , Instance . PhotoLibraryUsageDescription ) ;
Instance . PhotoLibraryAdditionsUsageDescription = EditorGUILayout . DelayedTextField ( "Photo Library Additions Usage Description" , Instance . PhotoLibraryAdditionsUsageDescription ) ;
Instance . DontAskLimitedPhotosPermissionAutomaticallyOnIos14 = EditorGUILayout . Toggle ( new GUIContent ( "Don't Ask Limited Photos Permission Automatically" , "See: https://mackuba.eu/2020/07/07/photo-library-changes-ios-14/. It's recommended to keep this setting enabled" ) , Instance . DontAskLimitedPhotosPermissionAutomaticallyOnIos14 ) ;
EditorGUI . EndDisabledGroup ( ) ;
if ( EditorGUI . EndChangeCheck ( ) )
Instance . Save ( ) ;
}
}
public class NGPostProcessBuild
{
#if UNITY_IOS
[PostProcessBuild( 1 )]
public static void OnPostprocessBuild ( BuildTarget target , string buildPath )
{
if ( ! Settings . Instance . AutomatedSetup )
return ;
if ( target = = BuildTarget . iOS )
{
string pbxProjectPath = PBXProject . GetPBXProjectPath ( buildPath ) ;
string plistPath = Path . Combine ( buildPath , "Info.plist" ) ;
PBXProject pbxProject = new PBXProject ( ) ;
pbxProject . ReadFromFile ( pbxProjectPath ) ;
string targetGUID = pbxProject . GetUnityFrameworkTargetGuid ( ) ;
pbxProject . AddFrameworkToProject ( targetGUID , "PhotosUI.framework" , true ) ;
pbxProject . AddFrameworkToProject ( targetGUID , "Photos.framework" , false ) ;
pbxProject . AddFrameworkToProject ( targetGUID , "MobileCoreServices.framework" , false ) ;
pbxProject . AddFrameworkToProject ( targetGUID , "ImageIO.framework" , false ) ;
File . WriteAllText ( pbxProjectPath , pbxProject . WriteToString ( ) ) ;
PlistDocument plist = new PlistDocument ( ) ;
plist . ReadFromString ( File . ReadAllText ( plistPath ) ) ;
PlistElementDict rootDict = plist . root ;
if ( ! string . IsNullOrEmpty ( Settings . Instance . PhotoLibraryUsageDescription ) )
rootDict . SetString ( "NSPhotoLibraryUsageDescription" , Settings . Instance . PhotoLibraryUsageDescription ) ;
if ( ! string . IsNullOrEmpty ( Settings . Instance . PhotoLibraryAdditionsUsageDescription ) )
rootDict . SetString ( "NSPhotoLibraryAddUsageDescription" , Settings . Instance . PhotoLibraryAdditionsUsageDescription ) ;
if ( Settings . Instance . DontAskLimitedPhotosPermissionAutomaticallyOnIos14 )
rootDict . SetBoolean ( "PHPhotoLibraryPreventAutomaticLimitedAccessAlert" , true ) ;
File . WriteAllText ( plistPath , plist . WriteToString ( ) ) ;
}
}
#endif
}
}