블로그 이미지
Every unexpected event is a path to learning for you. blueasa

카테고리

분류 전체보기 (2803)
Unity3D (859)
Programming (479)
Server (33)
Unreal (4)
Gamebryo (56)
Tip & Tech (234)
협업 (61)
3DS Max (3)
Game (12)
Utility (140)
Etc (98)
Link (32)
Portfolio (19)
Subject (90)
iOS,OSX (55)
Android (16)
Linux (5)
잉여 프로젝트 (2)
게임이야기 (3)
Memories (20)
Interest (38)
Thinking (38)
한글 (30)
PaperCraft (5)
Animation (408)
Wallpaper (2)
재테크 (18)
Exercise (3)
나만의 맛집 (3)
냥이 (10)
육아 (16)
Total
Today
Yesterday

Unity 2021.3.40f1

I2 Localization v2.8.22 f4

----

I2 Localization의 AppName 로컬라이징을 사용하고 있는데,

PostProcessBuild_iOS.cs를 약간 개조(추가)해서 iOS Privacy도 로컬라이징 하도록 추가함.

(현재는 ATT 관련 Description인 NSUserTrackingUsageDescription Privacy를 추가함)

 

아래 소스를 I2 Localization 하위에 있는 PostProcessBuild_iOS.cs가 있는 폴더에 넣거나,

원하는 곳 Editor 폴더 아래에 넣으면 된다.

 

난 에셋 삭제 시 함께 사라지는 걸 방지하기 위해 아래 위치에 추가해 뒀다.

[소스 위치] ../Assets/I2_Extentions/Localization/Scripts/Editor/PostProcessBuild_iOS_Privacy.cs

 

#if UNITY_IOS || UNITY_IPHONE
using UnityEditor.Callbacks;
using System.Collections;
using UnityEditor.iOS_I2Loc.Xcode;
using System.IO;
using UnityEditor;
using UnityEngine;
using System.Linq;


namespace I2.Loc
{
    public class PostProcessBuild_IOS_Privacy
    {
        // PostProcessBuild_IOS(10000) 다음에 실행 되도록 10001로 지정함.
        [PostProcessBuild(10001)]
        public static void ChangeXcodePlist(BuildTarget buildTarget, string pathToBuiltProject)
        {
            if (buildTarget != BuildTarget.iOS)
                return;

			if (LocalizationManager.Sources.Count <= 0)
				LocalizationManager.UpdateSources();
            var langCodes = LocalizationManager.GetAllLanguagesCode(false).Concat(LocalizationManager.GetAllLanguagesCode(true)).Distinct().ToList();
            if (langCodes.Count <= 0)
				return;
				
            try
            {
			//----[ Export localized languages to the info.plist ]---------

                string plistPath = pathToBuiltProject + "/Info.plist";
                PlistDocument plist = new PlistDocument();
                plist.ReadFromString(File.ReadAllText(plistPath));

				PlistElementDict rootDict = plist.root;

                // Get Language root
                var langArray = rootDict.CreateArray("CFBundleLocalizations");

                // Set the Language Codes
                foreach (var code in langCodes)
                {
                    if (code == null || code.Length < 2)
                        continue;
                    langArray.AddString(code);
                }

				rootDict.SetString("CFBundleDevelopmentRegion", langCodes[0]);

                // Write to file
                File.WriteAllText(plistPath, plist.WriteToString());

			//--[ Localize Privacy ]----------

				string LocalizationRoot = pathToBuiltProject + "/I2Localization";
				if (!Directory.Exists(LocalizationRoot))
					Directory.CreateDirectory(LocalizationRoot);
				
				var project = new PBXProject();
				string projPath = PBXProject.GetPBXProjectPath(pathToBuiltProject);
				//if (!projPath.EndsWith("xcodeproj"))
					//projPath = projPath.Substring(0, projPath.LastIndexOfAny("/\\".ToCharArray()));

				project.ReadFromFile(projPath);
				//var targetName = PBXProject.GetUnityTargetName();
				//string projBuild = project.TargetGuidByName( targetName );

                // 상위(PostProcessBuild_IOS.cs)에서 이미 지우고 생성했기 때문에 주석처리.
				//project.RemoveLocalizationVariantGroup("I2 Localization");
				
                // Set the Language Overrides
				foreach (var code in langCodes)
				{
					if (code == null || code.Length < 2)
						continue;

					var LanguageDirRoot = LocalizationRoot + "/" + code + ".lproj";
					if (!Directory.Exists(LanguageDirRoot))
						Directory.CreateDirectory(LanguageDirRoot);

					var infoPlistPath = LanguageDirRoot + "/InfoPlist.strings";
                    
                    // AppName
                    //var InfoPlist = string.Format("CFBundleDisplayName = \"{0}\";", LocalizationManager.GetAppName(code));
                    //File.WriteAllText(infoPlistPath, InfoPlist);
                    
                    // Privacy - NSUserTrackingUsageDescription
                    // 다른 Privacy 필요하면 아래 추가하면 됨.
                    var InfoPlist = string.Format("\n{0} = \"{1}\";", "NSUserTrackingUsageDescription", Get_NSUserTrackingUsageDescription(code));
                    File.AppendAllText(infoPlistPath, InfoPlist);


                    //var langProjectRoot = "I2Localization/"+code+".lproj";

                    // InfoPlist.strings만 수정할거라 Localizable.strings는 주석처리.
                    //var stringPaths = LanguageDirRoot + "/Localizable.strings";
                    //File.WriteAllText(stringPaths, string.Empty);

                    // AddLocalization은 PostProcessBuild_IOS.cs에서 했기 때문에 주석처리 함.
                    //project.AddLocalization(langProjectRoot + "/Localizable.strings", langProjectRoot + "/Localizable.strings", "I2 Localization");
                    //project.AddLocalization(langProjectRoot + "/InfoPlist.strings", langProjectRoot + "/InfoPlist.strings", "I2 Localization");
                }

                project.WriteToFile(projPath);
				
            }
            catch (System.Exception e)
            { 
				Debug.Log (e);
			}
        }

        /// <summary>
        /// NSUserTrackingUsageDescription(IDFA/ATT)
        /// </summary>
        /// <param name="_code">국가코드</param>
        /// <returns>로컬라이징 된 Description</returns>
		private static string Get_NSUserTrackingUsageDescription(string _code)
		{
			string strDescription = string.Empty;

			switch(_code)
			{
								case "en":
					strDescription = "This identifier will be used to deliver personalized ads to you.";
					break;

                case "ko":
                    strDescription = "이 식별자는 맞춤형 광고를 제공하는 데 사용됩니다.";
                    break;

                case "zh":      // zh도 zh-CN(중국본토)으로 보도록 함
                case "zh-CN":
                    strDescription = "该标识符将用于向您投放个性化广告。";
                    break;

                case "zh-TW":
                    strDescription = "該標識符將用於向您投放個人化廣告。";
                    break;

                case "ja":
                    strDescription = "この識別子は、パーソナライズされた広告を配信するために使用されます。";
                    break;

                case "vi":
                    strDescription = "Mã nhận dạng này sẽ được sử dụng để phân phối quảng cáo được cá nhân hóa cho bạn.";
                    break;

                case "es":
                    strDescription = "Este identificador se utilizará para enviarle anuncios personalizados.";
                    break;

                case "it":
                    strDescription = "Questo identificatore verrà utilizzato per fornirti annunci personalizzati.";
                    break;

                case "id":
                    strDescription = "Pengenal ini akan digunakan untuk menayangkan iklan yang dipersonalisasi kepada Anda.";
                    break;

                case "th":
                    strDescription = "ตัวระบุนี้จะใช้ในการส่งโฆษณาส่วนบุคคลให้กับคุณ";
                    break;

                case "pt":
                    strDescription = "Este identificador será utilizado para lhe entregar anúncios personalizados.";
                    break;

                case "hi":
                    strDescription = "इस पहचानकर्ता का उपयोग आपको वैयक्तिकृत विज्ञापन देने के लिए किया जाएगा.";
                    break;

                default:
                    strDescription = "This identifier will be used to deliver personalized ads to you.";
                    break;
			}

			return strDescription;

        }
    }
}
#endif
반응형
Posted by blueasa
, |

[Android] https://docs.unity3d.com/Packages/com.unity.localization@1.2/manual/Android-App-Localization.html

 

Android App Localization | Localization | 1.2.1

Android App Localization App Name The Localization package supports localizing app names with the Android strings.xml file. When you build the Android player, the package applies the Localization values to the Gradle project during the post-build step. The

docs.unity3d.com

 

 

[iOS] https://docs.unity3d.com/Packages/com.unity.localization@1.2/manual/iOS-App-Localization.html

 

iOS App Localization | Localization | 1.2.1

iOS App Localization The Localization package provides support for localizing values within the iOS Info.plist information property list file. When building the iOS player, the Localization values are applied to the project during the post build step. The

docs.unity3d.com

 

반응형
Posted by blueasa
, |

iOS 10에서 Privacy 설정

기존 앱을 XCode8로 다시 빌드하면 
iOS 10에서 카메라나 다른 기능을 사용시 아무런 경고도 없이 Crash가 발생하게 된다.

디버그 메시지는 다음과 같다.

This app has crashed because it attempted to access privacy-sensitive data without a usage description. The app’s Info.plist must contain an NSCameraUsageDescription key with a string value explaining to the user how the app uses this data.

iOS 10에서 아래와 같은 기능을 사용하기 위해서는 사용자의 확인 메시지를 설정해줘야 한다.

사용 설명을 요구하는 API 항목들

Data ClassXCode KeyRaw Info.plist Key
Apple MusicPrivacy - Media Library Usage DescriptionNSAppleMusicUsageDescription
BluetoothPrivacy - Bluetooth Peripheral Usage DescriptionNSBluetoothPeripheralUsageDescription
CalendarPrivacy - Calendars Usage DescriptionNSCalendarsUsageDescription
CameraPrivacy - Camera Usage DescriptionNSCameraUsageDescription
ContactsPrivacy - Contacts Usage DescriptionNSContactsUsageDescription
HealthPrivacy - Health Share Usage Description Privacy - Health Update Usage DescriptionNSHealthShareUsageDescription NSHealthUpdateUsageDescription
HomePrivacy - HomeKit Usage DescriptionNSHomeKitUsageDescription
LocationPrivacy - Location Always Usage Description Privacy - Location When In Use Usage DescriptionNSLocationAlwaysUsageDescription NSLocationWhenInUseUsageDescription
MicrophonePrivacy - Microphone Usage DescriptionNSMicrophoneUsageDescription
MotionPrivacy - Motion Usage DescriptionNSMotionUsageDescription
PhotosPrivacy - Photo Library Usage DescriptionNSPhotoLibraryUsageDescription
RemindersPrivacy - Reminders Usage DescriptionNSRemindersUsageDescription
SiriPrivacy - Siri Usage DescriptionNSSiriUsageDescription
Speech RecognitionPrivacy - Speech Recognition Usage DescriptionNSSpeechRecognitionUsageDescription
TV Provider AccountPrivacy - TV Provider Usage DescriptionNSVideoSubscriberAccountUsageDescription

Info.plist에서 Privacy 설정을 추가해주면 된다.


다음은 사진 라이브러리와 카메라 접근시 사용 예제입니다.

Privacy - Camera Usage Description
Privacy - Photo Library Usage Description

[추가] Decription String을 필수로 넣어야 함. - blueasa

[Privacy - Camera Usage Description] Everyplay requires access to the Camera library

[Privacy - Photo Library Usage Description] Everyplay requires access to the photo library

[Privacy - Calenders Library Usage Description] Some ad content may access calendar


앱에서 사진 라이브러리 접근시 다음과 같은 메시지를 보게 된다.



출처: http://kka7.tistory.com/40 [까칠하게 살자]


[참조1] https://dev.tapjoy.com/ko/submitting-ios-results-warning-nscalendarsusagedescription/


[참조2] http://docs.telerik.com/platform/knowledge-base/troubleshooting/troubleshooting-app-rejected-from-app-store-missing-info-plist-key



반응형
Posted by blueasa
, |