| 개요

 

커스텀 설정 창의 예시

SettingsProvider클래스와 Attribute를 사용해서 Project Settings 혹은 Preferences 창을 커스터마이즈하는 법을 소개하고자 한다.

 

| 설정파일 추가

[FilePath("UserSettings/CustomSettings.asset",
          FilePathAttribute.Location.ProjectFolder)]
public sealed class CustomSettings: ScriptableSingleton<CustomSettings>
{
    // 설정 값 정의
    public string customSettingsValue = null;

    // 저장 함수 추가 (인자는 설정파일의 텍스트 저장 여부)
    public void Save() => Save(true);

    // 비활성화 되었을 때, 설정이 저장되도록
    void OnDisable() => Save();
}
 

| SettingsProvider를 재정의할 클래스 정의

 

sealed class CustomSettingsProvider : SettingsProvider
{
    public CustomSettingsProvider ()
      : base("Project/Custom Settings", SettingsScope.Project) {}

    public override void OnGUI(string search)
    {
        var settings = CustomSettings.instance;

        // Properties...
        var customSettingsValue = settings.customSettingsValue;

        EditorGUI.BeginChangeCheck();

        customSettingsValue = EditorGUILayout.TextField("Custom Settings", customSettingsValue);

        // 값이 변경되었을 경우 설정 값을 저장
        if (EditorGUI.EndChangeCheck())
        {
            settings.customSettingsValue = customSettingsValue;
            settings.Save();
        }
    }

    [SettingsProvider]
    public static SettingsProvider CreateCustomSettingsProvider()
      => new CustomSettingsProvider();
}
 
환경 설정에 커스텀 설정을 추가한 모습

| 키워드 설정

public CustomSettingsProvider ()
      : base("Project/Custom Settings", SettingsScope.Project) 
{
    keywords = new HashSet<string>( new []{ "CustomSetting" });
}
 

위와 같이 keywords를 설정해주면 검색창에서 해당 키워드로 리스트업할 수 있다.

 

| 커스텀 설정 바로가기

    void OnGUI()
    {
        if (GUILayout.Button("Open my custom preference"))
        {
            SettingsService.OpenUserPreferences("Preferences/MyCustomPref");
        }

        if (GUILayout.Button("Open my custom project settings"))
        {
            SettingsService.OpenProjectSettings("Project/MyCustomSettings");
        }
    }
 

 

 

| 마치며

SettingsProvider 클래스와 Attribute, ScriptableSingleton을 활용해서 간단히 설정창을 커스텀하는 방법을 알아보았다.

 

SettingsProvider를 상속한 추가 클래스 정의 없이, 아래의 Action 멤버변수를 지정하면 위 예제와 같이 설정 상세 UI를 커스터마이즈할 수 있다.

 

  • IMGUI: guiHandler
  • UI Toolkit: activeHandler

 

| 참고

 

 

반응형

| 개요

써드파티 플러그인을 적용하거나 OS 버전 업과 같은 이유로 SDK Build Tools의 버전을 올려야하는 경우가 있다.

이때 Gradle의 최소 요구 버전이 달라지는 경우가 있는데, 아래와 같은 에러가 발생한다.

FAILURE: Build failed with an exception.

* Where:
Build file '/Users/<usr>/.jenkins/workspace/<job>/<GradleProject>/launcher/build.gradle' line: <line>

* What went wrong:
A problem occurred evaluating project ':launcher'.
> Failed to apply plugin [id 'com.android.internal.version-check']
   > Minimum supported Gradle version is 5.6.4. Current version is 5.1.1. If using the gradle wrapper, try editing the distributionUrl in /Users/<usr>/.gradle/daemon/5.1.1/gradle/wrapper/gradle-wrapper.properties to gradle-5.6.4-all.zip
 
 

필자는 그래들 플러그인(classpath: com.android.tools.build:gradle:3.6.4)을 3.6.4버전을 쓰게 되면서 최소 요구 Gradle 버전은 5.6.4이었다.

dependencies {
  classpath 'com.android.tools.build:gradle:<version>'
}
 

Project 하위에 build.gradle 파일을 열어보면 위와 같은 내용을 확인할 수 있다.

 

Android Gradle 플러그인 출시 노트  |  Android 개발자  |  Android Developers

Android 스튜디오 빌드 시스템은 Gradle을 기반으로 하며 Android Gradle 플러그인에는 Android 앱을 빌드하는 데 사용하는 몇 가지 추가 기능이 있습니다.

developer.android.com

 

※위 링크에서 그래들 플러그인에 대응되는 그래들 버전을 확인할 수 있다.

 

| 플러그인별 Gradle 버전

플러그인 필요한 최소 Gradle 버전
8.1 8.0
8.0 8.0
7.4 7.5
7.3 7.4
7.2 7.3.3
7.1 7.2
7.0 7.0
4.2.0+ 6.7.1

 

| 그래들 버전 설정방법

그래들의 버전 설정은 Android 스튜디오의 File > Project Structure > Project 메뉴에서 또는 gradle/wrapper/gradle-wrapper.properties 파일의 Gradle 배포 참조를 편집하여 Gradle 버전을 지정할 수 있습니다.

해당 메뉴에서 그래들 버전 설정

혹은 gradle/wrapper/gradle-wrapper.properties 파일을 아래와 같이 수정

 

distributionBase=GRADLE_USER_HOME
...
distributionUrl=https\://services.gradle.org/distributions/gradle-5.6.4-bin.zip
...
distributionPath=wrapper/dists
zipStorePath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
 

| 젠킨스에서

 
  • Jenkins > Manage Jenkins > Global Tool Configuration > Gradle > Gradle Installations
  • 해당 버전의 그래들을 추가
  • 각 프로젝트에서 변경된 그래들을 사용하도록 수정
반응형

| 현상

FAILURE: Build failed with an exception.
 
* What went wrong:
Execution failed for task ':stripReleaseDebugSymbols'.
> No toolchains found in the NDK toolchains folder for ABI with prefix: arm-linux-androideabi
 
* Try:
Run with --stacktrace option to get the stack trace. Run with --info or --debug option to get more log output. Run with --scan to get full insights.
 
* Get more help at https://help.gradle.org
 
Deprecated Gradle features were used in this build, making it incompatible with Gradle 6.0.
Use '--warning-mode all' to show the individual deprecation warnings.
See https://docs.gradle.org/5.5/userguide/command_line_interface.html#sec:command_line_warnings
 
BUILD FAILED in 36s
 

위 에러가 발생하며 빌드에 실패하는 현상

 

| 원인

그래들 버전에 맞는 NDK가 설치되어 있지 않아 발생

 

| 해결방법

 
 
구분
버전
Gradle
5.5
NDK
android-ndk-r16b

그래들 버전에 맞는 NDK 설치

 

반응형

'Workspace' 카테고리의 다른 글

dotPeek을 이용한 디컴파일 / 어셈블리 브라우징 가이드  (0) 2023.04.06
[C#] Warning 숨기기  (0) 2023.03.24

 

iOS에서 앱을 배포하는 방법에는 App Store, Ad Hoc, Enterprise, Development 등 네 가지 방법이 있다.

오늘은 Ad Hoc 배포를 위해 필요한 기기등록에 대한 내용을 얘기할까 한다.

이에 앞서서 간단하게 각 배포 방법의 차이점이 무엇인지를 간략하게 정리하면 이러하다.

 
구분
용도
비고
App Store
TestFlight 혹은 App Store 등록용
 
Ad Hoc
등록된 내부인원을 위한 테스트
* 기기등록 필요
* 신규 기기 등록시 프로비너징 프로필 업데이트
Enterprise
조직 내부에서 사용하는 전용 앱에 주로 사용
* 엔터프라이즈 프로그램을 신청해야 사용할 수 있음
* 애플 로그인과 같은 몇몇 Capability 사용 불가
Development
내부 개발용
 

 

 

| 1. 기기등록

 

  • 애플 개발자 센터 > Account > Certificates, Identifiers & Profiles > Device 탭으로 이동하여 신규 기기를 등록해야한다.
  • Platform, Device Name, Device ID 등 기기 등록에 필요한 정보를 알맞게 입력하면 Continue 버튼이 활성화된다.
  • Continue > Register > Done 을 차례대로 눌러주면 기기등록은 끝이다.

 

| 2. 프로비저닝 생성 혹은 갱신

 
생성해둔 프로비저닝이 없다면 생성해준다.

 

이미 생성한 프로비저닝이 있다면 기기만 추가적으로 등록하면 된다.

 

  • Edit 버튼 클릭
  • 스크롤을 내려보면 아래 이미지와 같이 디바이스 목록을 확인할 수 있다.

위 화면에서 신규로 등록한 기기를 체크해주고 저장 후 생성 혹은 갱신된 프로비저닝을 다운로드 받는다.

 

| 3. 갱신된 프로비저닝 등록

  • 다운로드 받은 프로비저닝을 더블클릭하여, Xcode에 등록

※등록된 프로파일은 Xcode 혹은 /Users/${User}/Library/MobileDevice/Provisioning Profiles 폴더에서 확인할 수 있다.

 

위와 같이 사이닝을 자동으로 했을 경우 별다른 처리 없이 신규로 등록된 프로비저닝으로 빌드를 할 수 있고, 수동일 경우 새 프로비저닝 선택하면 된다.

 

| 4. 프로비저닝 프로필 UUID 확인방법

 

CI/CD를 이용하는 경우 프로비저닝 프로필의 UUID가 필요한 경우가 있는데, 정보 가져오기 메뉴에서 확인 가능하다.

 

혹은 Finder에서 계층/갤러리 형태로 보기 설정을 한 뒤, 파일을 선택하면 UUID를 확인할 수 있다.

하지만 기기등록은 꽤 빈번한 편으로 매번 22자릿수의 UUID를 눈으로 보며 확인하는 것은 쉬운 일은 아니다.

 

#getMobileprovisionUUID.sh

#!/bin/bash
if [ $# -ne 1 ]
then
 echo "Usage: getmobileuuid the-mobileprovision-file-path"
 exit 1
fi
# mobileprovision_uuid=`grep UUID -A1 -a $1 | grep -o "[-A-Z0-9]\{36\}"`
mobileprovision_uuid=`/usr/libexec/PlistBuddy -c "Print UUID" /dev/stdin <<< $(/usr/bin/security cms -D -i $1)`
echo "UUID is:"
echo ${mobileprovision_uuid}
 

위 코드를 이용해서 프로비저닝 프로파일의 UUID를 추출해보자.

${scriptPath}/getMobileprovisionUUID.sh ${provisionPath}/${provisionName}.mobileprovision
UUID is:
UUID 결과값
 

 

반응형

신규 Profile로 빌드된 앱을 처음 실행하면 기기에서 해당 앱 개발자를 신뢰할 수 없다는 알림이 표시됩니다.

이 메시지를 닫은 후 해당 앱 개발자에 대한 신뢰를 설정할 수 있습니다.

 

  • ‘설정 > 일반 > 프로파일 또는 프로파일 및 기기 관리’를 탭합니다. (혹은 설정 > 일반 > VPN 및 기기 관리 - 기업용 앱)

 

'기업용 앱' 제목 아래에 개발자의 프로파일이 표시됩니다.



※실제론 앱개발사의 프로파일이 보입니다.

 

기업용 앱 제목 아래에 있는 개발자 프로파일 이름을 탭하여 이 개발자에 대한 신뢰를 설정합니다.

프로파일을 신뢰한 후에 앱이 정상적으로 실행됩니다.

 

| 참고

 

반응형

Unity3d il2cpp 빌드 중 clang++와 같은 ndk 관련 툴 사용 중 위와 같은 에러가 발생

| 현상

stdout:
Building libil2cpp.so with AndroidToolChain
    Output directory: /Users/{UserName}/.jenkins/workspace/ANDROID_BUILD/Temp/StagingArea/assets/bin/Data/Native/armeabi-v7a
    Cache directory: /Users/{UserName}/.jenkins/workspace/ANDROID_BUILD/Library/il2cpp_android_armeabi-v7a/il2cpp_cache
ObjectFiles: 998 of which compiled: 371
    Time Compile: 74211 milliseconds Il2CppTypeDefinitions.cpp
    Time Compile: 68481 milliseconds Il2CppMethodPointerTable.cpp
    Time Compile: 55285 milliseconds Il2CppAttributes.cpp
    Time Compile: 41421 milliseconds Il2CppMetadataUsage.cpp
    Time Compile: 26292 milliseconds Il2CppInvokerTable.cpp
    Time Compile: 17629 milliseconds Il2CppGenericMethodPointerTable.cpp
    Time Compile: 12918 milliseconds Il2CppGenericClassTable.cpp
    Time Compile: 10404 milliseconds Bulk_Assembly-CSharp_26.cpp
    Time Compile: 9629 milliseconds Bulk_Assembly-CSharp_49.cpp
    Time Compile: 9063 milliseconds Bulk_Assembly-CSharp_144.cpp
Total compilation time: 98643 milliseconds.
il2cpp.exe didn't catch exception: Unity.IL2CPP.Building.BuilderFailedException: /Users/{UserName}/Library/Android/sdk/ndk/android-ndk-r16b/toolchains/llvm/prebuilt/darwin-x86_64/bin/clang++ @"/var/folders/wp/pskqw4ns3cn27r6k10158xkc0000gn/T/tmpWedXj6.tmp" -o "/Users/{UserName}/.jenkins/workspace/ANDROID_BUILD/Library/il2cpp_android_armeabi-v7a/il2cpp_cache/linkresult_6F0877EF66902EFEC137A171BB702A20/libil2cpp.so" -shared -Wl,-soname,libil2cpp.so -Wl,--no-undefined -Wl,-z,noexecstack -Wl,--gc-sections -Wl,--build-id --sysroot "/Users/{UserName}/Library/Android/sdk/ndk/android-ndk-r16b/platforms/android-16/arch-arm" -gcc-toolchain "/Users/{UserName}/Library/Android/sdk/ndk/android-ndk-r16b/toolchains/arm-linux-androideabi-4.9/prebuilt/darwin-x86_64" -target armv7-none-linux-androideabi -Wl,--wrap,sigaction -L "/Users/{UserName}/Library/Android/sdk/ndk/android-ndk-r16b/sources/cxx-stl/gnu-libstdc++/4.9/libs/armeabi-v7a" -lgnustl_static -llog -rdynamic -fuse-ld=gold
 
clang++: error: unable to execute command: Killed: 9
clang++: error: linker command failed due to signal (use -v to see invocation)
 
 
   at Unity.IL2CPP.Building.CppProgramBuilder.PostprocessObjectFiles(HashSet`1 objectFiles, CppToolChainContext toolChainContext)
   at Unity.IL2CPP.Building.CppProgramBuilder.Build(IBuildStatistics& statistics)
   at il2cpp.Program.DoRun(String[] args)
   at il2cpp.Program.Run(String[] args)
   at il2cpp.Program.Main(String[] args)
stderr:
 
Unhandled Exception: Unity.IL2CPP.Building.BuilderFailedException: /Users/{UserName}/Library/Android/sdk/ndk/android-ndk-r16b/toolchains/llvm/prebuilt/darwin-x86_64/bin/clang++ @"/var/folders/wp/pskqw4ns3cn27r6k10158xkc0000gn/T/tmpWedXj6.tmp" -o "/Users/{UserName}/.jenkins/workspace/ANDROID_BUILD/Library/il2cpp_android_armeabi-v7a/il2cpp_cache/linkresult_6F0877EF66902EFEC137A171BB702A20/libil2cpp.so" -shared -Wl,-soname,libil2cpp.so -Wl,--no-undefined -Wl,-z,noexecstack -Wl,--gc-sections -Wl,--build-id --sysroot "/Users/{UserName}/Library/Android/sdk/ndk/android-ndk-r16b/platforms/android-16/arch-arm" -gcc-toolchain "/Users/{UserName}/Library/Android/sdk/ndk/android-ndk-r16b/toolchains/arm-linux-androideabi-4.9/prebuilt/darwin-x86_64" -target armv7-none-linux-androideabi -Wl,--wrap,sigaction -L "/Users/{UserName}/Library/Android/sdk/ndk/android-ndk-r16b/sources/cxx-stl/gnu-libstdc++/4.9/libs/armeabi-v7a" -lgnustl_static -llog -rdynamic -fuse-ld=gold
 
clang++: error: unable to execute command: Killed: 9
 

| 원인

macOS Catalina 업데이트 이후 보안이 강화되어 확인되지 않은 개발자의 앱을 열려는 경우, 경고 팝업이 발생.

 

| 해결방법

차단된 앱을 허용하기 위해선 시스템 환경 설정 > 보안 및 개인 정보 보호 > 일반 > 확인 없이 허용 버튼을 눌러서 차단을 해제하는 방법도 있지만

NDK에서 새로운 앱을 사용할때마다 차단을 하나하나 해줘야하는 번거로움이 있습니다.

보안엔 안좋을 수 있지만, 터미널을 통해서 다운로드한 앱을 모두 허용해주도록 합니다.

 

sudo spctl --master-disable
 

해당 명령어를 터미널에서 입력 후 적용을 위해서 재부팅 필요.

 

 

 

반응형

| 현상

$ /usr/bin/agvtool new-marketing-version 0.1
xcode-select: error: tool 'agvtool' requires Xcode, but active developer directory '/Library/Developer/CommandLineTools' is a command line tools instance
FATAL: Could not set CFBundleShortVersionString to: 0.1
Build step 'Conditional step (single)' marked build as failure
 

 

| 원인

Xcode 설치 과정에서 경로가 잘못 설정되었을 경우 해당 에러 발생

 

| 해결방법

sudo xcode-select -s /Applications/Xcode.app/Contents/Developer
 

Xcode가 설치된 경로에 xcode-select 명령어 입력

 

| 참고

 

반응형

| 패키지 설치

 

brew install akamai
 

특정 버전 설치의 경우: brew install akamai@{version}

e.g. brew install akamai@1.2.1

 

패키지 설치 후 커맨드도 별도로 설치가 필요하다

Usage:
  akamai [global flags] command [command flags] [arguments...]
 
Commands:
  config
  install (alias: get)
  list
  search
  uninstall
  update
  upgrade
  help
 
Global Flags:
  --edgerc value, -e value                 Location of the credentials file [$AKAMAI_EDGERC]
  --section value, -s value                Section of the credentials file [$AKAMAI_EDGERC_SECTION]
  --accountkey value, --account-key value  Account switch key [$AKAMAI_EDGERC_ACCOUNT_KEY]
  --help                                   show help (default: false)
  --bash                                   Output bash auto-complete (default: false)
  --zsh                                    Output zsh auto-complete (default: false)
  --proxy value                            Set a proxy to use
  --version                                Output CLI version (default: false)
 
Copyright (C) Akamai Technologies, Inc
 

| 커맨드 설치

akamai install purge
 

| Authentication credentials 만들기

| 자격 증명 설정

cli를 실행하기 위해선 위에서 만든 인증 자격증명 파일을 이용해 인증을 하게 된다.

(이때 커스텀 HTTP 요청 서명 프로토콜인 EdgeGrid를 이용)

 

인증 자격증명 파일은 클라이언트 토큰/시크릿 , 호스트, 액세스 토큰 등의 내용이 기입된다.

 

[ccu]
client_secret = {client_secret}
host = {host}
access_token = {access_token}
client_token = {client_token}
 

위 내용이 작성된 파일을 /Users/{username}/.edgerc 경로에 저장

 

| 젠킨스 설정

 

  1. 젠킨스 > 잡 > 설정
  2. 파라미터 추가 > 문자열 파라미터 CACHE_URL 추가
  3. 빌드 스탭 > Exectue Shell 추가
  4. akamai purge delete $CACHE_URL 기입

 

반응형

+ Recent posts