I'm working on a universal MacOS app in Electron, and while I've gotten pretty far, I can't seem to figure out how to enable it for testing in Testflight.
I keep running into the following error in App Store Connect no matter what I do:
I'm using:
electron-builder: 23.0.8
electron: 17.4.3
electron-builder-notarize: 1.4.0
I'm building on an M1 Macbook Air, Monterey 12.3.1.
Varying useful stuff I've found:
https://github.com/electron/osx-sign/issues/251
https://developer.apple.com/forums/thread/689377
https://jondot.medium.com/shipping-electron-apps-to-mac-app-store-with-electron-builder-e960d46148ec
https://www.electronjs.org/docs/latest/tutorial/mac-app-store-submission-guide
https://til.simonwillison.net/electron/sign-notarize-electron-macos
My setup
package.json
"build": {
"appId": "com.xxxxx.xxxxxx",
"afterSign": "electron-builder-notarize",
"mac": {
"category": "public.app-category.entertainment",
"darkModeSupport": true,
"hardenedRuntime": true,
"gatekeeperAssess": false,
"entitlements": "build/entitlements.mac.plist",
"entitlementsInherit": "build/entitlements.mac.plist",
"icon": "build/icon.icns",
"target": [
{
"target": "mas",
"arch": "universal"
},
"dmg"
]
},
"mas": {
"type": "distribution",
"hardenedRuntime": false,
"provisioningProfile": "embedded.provisionprofile",
"entitlements": "build/entitlements.mas.plist",
"entitlementsInherit": "build/entitlements.mas.inherit.plist"
}
}
entitlements.mas.plist
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>com.apple.security.app-sandbox</key>
<true/>
<key>com.apple.security.application-groups</key>
<string>TEAMID.com.app.appname</string>
<key>com.apple.application-identifier</key>
<string>TEAMID.com.app.appname</string>
<key>com.apple.developer.team-identifier</key>
<string>TEAMID</string>
<key>com.apple.security.cs.allow-jit</key>
<true/>
<key>com.apple.security.cs.allow-unsigned-executable-memory</key>
<true/>
<key>com.apple.security.cs.allow-dyld-environment-variables</key>
<true/>
</dict>
</plist>
entitlements.mas.inherit.plist
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>com.apple.security.app-sandbox</key>
<true/>
<key>com.apple.security.inherit</key>
<true/>
</dict>
</plist>
After looking through all these, and just playing around with adding different entitlements, it was resolved with the following settings. I honestly have no idea which of these is relevant at this point, and after days of debugging I am beyond the point of caring haha. But for future internet travelers who find themselves stuck, here is what I have that got me through:
package.json relevant section (added loginhelper!)
"build": {
"appId": "com.xxxxxx.xxxxxx",
"afterSign": "electron-builder-notarize",
"mac": {
"category": "public.app-category.entertainment",
"darkModeSupport": true,
"hardenedRuntime": true,
"gatekeeperAssess": false,
"entitlements": "build/entitlements.mac.plist",
"entitlementsInherit": "build/entitlements.mac.plist",
"icon": "build/icon.icns",
"target": [
{
"target": "mas",
"arch": "universal"
},
"dmg"
]
},
"mas": {
"type": "distribution",
"hardenedRuntime": false,
"provisioningProfile": "embedded.provisionprofile",
"entitlements": "build/entitlements.mas.plist",
"entitlementsInherit": "build/entitlements.mas.inherit.plist",
"entitlementsLoginHelper": "build/entitlements.mas.loginhelper.plist"
}
}
entitlements.mas.plist
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>com.apple.security.app-sandbox</key>
<true/>
<key>com.apple.security.application-groups</key>
<string>TEAMID.com.app.appname</string>
<key>com.apple.application-identifier</key>
<string>TEAMID.com.app.appname</string>
<key>com.apple.developer.team-identifier</key>
<string>TEAMID</string>
<key>com.apple.security.cs.allow-jit</key>
<true/>
<key>com.apple.security.cs.allow-unsigned-executable-memory</key>
<true/>
<key>com.apple.security.cs.allow-dyld-environment-variables</key>
<true/>
<key>com.apple.security.network.client</key>
<true/>
<key>com.apple.security.files.user-selected.read-only</key>
<true/>
<key>com.apple.security.files.user-selected.read-write</key>
<true/>
</dict>
</plist>
entitlements.mas.inherit.plist
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>com.apple.security.app-sandbox</key>
<true/>
<key>com.apple.security.inherit</key>
<true/>
<key>com.apple.security.cs.allow-jit</key>
<true/>
<key>com.apple.security.cs.allow-unsigned-executable-memory</key>
<true/>
</dict>
</plist>
entitlements.mas.loginhelper.plist
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>com.apple.security.app-sandbox</key>
<true/>
</dict>
</plist>
I want to log nlog generated application logs in app service diagnostic blob [i.e, Application Logging (Blob)
] but only default logs are printed not the nlog based custom logs
but I can print Application Logging (Filesystem) when file target is added to nlog.config. The problem is only with blob.
nlog.config file:
<?xml version="1.0" encoding="utf-8" ?>
<nlog xmlns="http://www.nlog-project.org/schemas/NLog.xsd"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
autoReload="true"
throwConfigExceptions="true"
internalLogLevel="info"
internalLogFile="d:\home\LogFiles\temp\internal-nlog-AspNetCore3.txt">
<!-- enable asp.net core layout renderers -->
<extensions>
<add assembly="NLog.Web.AspNetCore"/>
</extensions>
<!-- the targets to write to -->
<targets>
<target xsi:type="Trace" name="String" layout="${level}\: ${logger}[0]${newline} |trace| ${message}${exception:format=tostring}" />
<target xsi:type="Console" name="lifetimeConsole" layout="${level}\: ${logger}[0]${newline} |console| ${message}${exception:format=tostring}" />
</targets>
<rules>
<logger name="*" minlevel="Trace" writeTo="lifetimeConsole,String" final="true"/>
</rules>
</nlog>
program.cs file
namespace testapp
{
public class Program
{
public static void Main(string[] args)
{
var logger = NLog.Web.NLogBuilder.ConfigureNLog("nlog.config").GetCurrentClassLogger();
try
{
logger.Debug("init main");
CreateHostBuilder(args).Build().Run();
}
catch (Exception exception)
{
logger.Error(exception, "Stopped program because of exception");
throw;
}
finally
{
NLog.LogManager.Shutdown();
}
}
public static IHostBuilder CreateHostBuilder(string[] args) =>
Host.CreateDefaultBuilder(args)
.ConfigureLogging(logging =>
{
logging.SetMinimumLevel(Microsoft.Extensions.Logging.LogLevel.Trace);
logging.AddConsole();
logging.AddDebug();
logging.AddAzureWebAppDiagnostics();
})
.UseNLog() // NLog: Setup NLog for Dependency injection
.ConfigureServices(serviceCollection => serviceCollection
.Configure<AzureBlobLoggerOptions>(options =>
{
options.BlobName = "testlog.txt";
}))
.ConfigureWebHostDefaults(webBuilder =>
{
webBuilder.UseStartup<Startup>();
});
}
}
The Nlog based loggings are not logged in app service diagnostic blob, instead only default logging is printed.
Kindly help to resolve this issue.
Seems that System.Diagnostics.Trace-Target works best for ASP.NET-application and not for ASP.NetCore applications in Azure.
When using AddAzureWebAppDiagnostics it will redirect all output written to Microsoft ILogger to FileSystem or Blob. But any output written to pure NLog Logger-objects will not be redirected.
Maybe the solution is to setup a NLog FileTarget writing to the HOME-directory:
<nlog>
<targets async="true">
<!-- Environment Variable %HOME% matches D:/Home -->
<target type="file" name="appfile" filename="${environment:HOME:cached=true}/logfiles/application/app-${shortdate}-${processid}.txt" />
</targets>
<rules>
<logger name="*" minLevel="Debug" writeTo="appFile" />
</rules>
</nlog>
See also: https://learn.microsoft.com/en-us/azure/app-service/troubleshoot-diagnostic-logs#stream-logs
For including Blob-output then take a look at NLog.Extensions.AzureBlobStorage
Alternative to Blob-output could be ApplicationInsights but it might have different pricing.
My goal is to create a custom switch including animated transitions between checked and unchecked state.
I easily achieved a default state and my switch looks as expected in both states and it changes its look when its state is changed.
Problem arises when I attach animated-selector instead of regular one.
I'm gettting an error like this:
android.view.InflateException: Binary XML file line #10: Binary XML
file line #10: Error inflating class android.widget.Switch
Caused by: android.content.res.Resources$NotFoundException: File
res/drawable/switch_track_animation_unchecked_checked.xml from
drawable resource ID #0x7f060072
at android.content.res.Resources.loadDrawableForCookie(Resources.java:2640)
Caused by: android.content.res.Resources$NotFoundException: File
res/drawable/switch_track_animated_selector.xml from drawable resource
ID #0x7f060070
I can assure that I'm properly accessing those drawables etc.
I went through invalidate caches and restart, clean build, rebuild etc. and it won't work.
View sample
<Switch
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:thumb="#drawable/switch_thumb_selector"
android:track="#drawable/switch_track_animated_selector"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
android:checked="true"
android:id="#+id/switch2"/>
switch_track_animated_selector
<animated-selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:id="#+id/checked"
android:drawable="#drawable/switch_bckg_on"
android:state_checked="true"/>
<item android:id="#+id/unchecked"
android:drawable="#drawable/switch_bckg_off"
android:state_checked="false"/>
<transition
android:fromId="#+id/unchecked"
android:toId="#+id/checked"
android:drawable="#drawable/switch_track_animation_unchecked_checked"/>
<transition
android:fromId="#+id/checked"
android:toId="#+id/unchecked"
android:drawable="#drawable/switch_track_animation_checked_unchecked"/>
</animated-selector>
switch_bckg_on.xml
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<solid android:color="#00B05A"/>
<stroke android:width="1dp" android:color="#00B05A" />
<corners android:radius="180dp"/>
<padding android:left="0dp" android:top="0dp" android:right="0dp" android:bottom="0dp" />
</shape>
switch_bckg_off.xml
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<solid android:color="#F1F1F1"/>
<stroke android:width="1dp" android:color="#E0E0E0" />
<corners android:radius="180dp"/>
<padding android:left="0dp" android:top="0dp" android:right="0dp" android:bottom="0dp" />
</shape>
switch_track_animation_checked_unchecked.xml
<?xml version="1.0" encoding="utf-8"?>
<animated-vector xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:aapt="http://schemas.android.com/aapt"
android:drawable="#drawable/switch_bckg_on">
<target android:name="android:drawable">
<aapt:attr name="android:animation">
<objectAnimator
android:duration="#android:integer/config_shortAnimTime"
android:interpolator="#android:interpolator/accelerate_decelerate"
android:propertyName="strokeColor"
android:valueFrom="#A0A0A0"
android:valueTo="#1E9618"
android:valueType="intType" />
</aapt:attr>
</target>
</animated-vector>
switch_track_animation_unchecked_checked.xml
<?xml version="1.0" encoding="utf-8"?>
<animated-vector xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:aapt="http://schemas.android.com/aapt"
android:drawable="#drawable/switch_bckg_off">
<target android:name="android:drawable">
<aapt:attr name="android:animation">
<objectAnimator
android:duration="#android:integer/config_shortAnimTime"
android:interpolator="#android:interpolator/accelerate_decelerate"
android:propertyName="strokeColor"
android:valueFrom="#A0A0A0"
android:valueTo="#1E9618"
android:valueType="intType"/>
</aapt:attr>
</target>
</animated-vector>
I also checked above approach using vector drawable instead of shape and I had the same result.
Example of vectors
ic_thumb_vector_off
<vector android:height="33dp" android:viewportHeight="300"
android:viewportWidth="300" android:width="33dp" xmlns:android="http://schemas.android.com/apk/res/android">
<path android:name="background_off" android:fillColor="#FFFFFF" android:fillType="nonZero"
android:pathData="M149.926,149.926m-149.176,0a149.176,149.176 0,1 1,298.352 0a149.176,149.176 0,1 1,-298.352 0"
android:strokeAlpha="0.1" android:strokeColor="#000000" android:strokeWidth="0.5"/>
<path android:name="icon_off" android:fillColor="#9B9B9B" android:fillType="evenOdd"
android:pathData="M166.88,146.104C166.13,145.354 166.13,144.228 166.88,143.478L195.019,115.339C195.77,114.588 196.145,113.463 196.145,112.712C196.145,111.962 195.77,110.836 195.019,110.086L189.767,104.833C189.016,104.083 187.891,103.708 187.14,103.708C186.015,103.708 185.264,104.083 184.514,104.833L156.375,132.972C155.624,133.723 154.499,133.723 153.748,132.972L125.609,104.833C124.859,104.083 123.733,103.708 122.983,103.708C122.233,103.708 121.107,104.083 120.357,104.833L115.104,110.086C114.354,110.836 113.979,111.962 113.979,112.712C113.979,113.463 114.354,114.588 115.104,115.339L143.243,143.478C143.994,144.228 143.994,145.354 143.243,146.104L115.104,174.243C114.354,174.993 113.979,176.119 113.979,176.869C113.979,177.62 114.354,178.745 115.104,179.496L120.357,184.748C121.107,185.499 122.233,185.874 122.983,185.874C123.733,185.874 124.859,185.499 125.609,184.748L153.748,156.609C154.499,155.859 155.624,155.859 156.375,156.609L184.514,184.748C185.264,185.499 186.39,185.874 187.14,185.874C187.891,185.874 189.016,185.499 189.767,184.748L195.019,179.496C195.77,178.745 196.145,177.62 196.145,176.869C196.145,176.119 195.77,174.993 195.019,174.243L166.88,146.104Z"
android:strokeColor="#00000000" android:strokeWidth="1"/>
</vector>
ic_thumb_vector_on
<vector android:height="33dp" android:viewportHeight="302"
android:viewportWidth="302" android:width="33dp" xmlns:android="http://schemas.android.com/apk/res/android">
<path android:name="background_on" android:fillColor="#FFFFFF" android:fillType="nonZero"
android:pathData="M151,151m-150.25,0a150.25,150.25 0,1 1,300.5 0a150.25,150.25 0,1 1,-300.5 0"
android:strokeAlpha="0.1" android:strokeColor="#000000" android:strokeWidth="0.5"/>
<path android:name="icon_on" android:fillColor="#00B05A" android:fillType="evenOdd"
android:pathData="M105.523,153.198C104.806,152.5 104.448,151.453 104.448,150.754C104.448,150.056 104.806,149.009 105.523,148.31L110.536,143.422C111.968,142.026 114.117,142.026 115.549,143.422L115.907,143.772L135.602,164.371C136.318,165.069 137.393,165.069 138.109,164.371L186.093,115.841L186.451,115.841C187.883,114.444 190.032,114.444 191.464,115.841L196.477,120.728C197.91,122.125 197.91,124.22 196.477,125.616L139.183,183.573C138.467,184.272 137.751,184.621 136.676,184.621C135.602,184.621 134.886,184.272 134.17,183.573L106.239,154.246L105.523,153.198Z"
android:strokeColor="#00000000" android:strokeWidth="1"/>
</vector>
Maybe I/m missing something in gradle file?
apply plugin: 'com.android.application'
apply plugin: 'kotlin-android'
apply plugin: 'kotlin-android-extensions'
android {
compileSdkVersion 28
defaultConfig {
applicationId "...customswitch"
minSdkVersion 22
targetSdkVersion 28
versionCode 1
versionName "1.0"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
}
}
}
dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])
implementation"org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
implementation 'androidx.appcompat:appcompat:1.0.2'
implementation 'androidx.core:core-ktx:1.0.2'
implementation 'androidx.constraintlayout:constraintlayout:1.1.3'
testImplementation 'junit:junit:4.12'
androidTestImplementation 'androidx.test:runner:1.2.0'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0'
}
I expect this view to load and not to throw an error on view init.
Your issue is that switch_track_animation_unchecked_checked.xml and switch_track_animation_checked_unchecked.xml are animated VectorDrawables, and these animate static VectorDrawable states. You are trying to animate ShapeDrawable, and not VectorDrawable and that's what is causing the exception, I think.
You need to replace switch_bckg_on.xml and switch_bckg_off.xml with <vector>...</vector> implementations to animate them from within an <animated-vector>...</animated-vector> block.
Alternatively you could replace the AnimatedVectorDrawables with StateListAnimator, although I'm not sure that will actually be able to do what you're trying to achieve here.
It seems like your switch_track_animated_selector does not have some default state without any id. You may try to add this state. This helped me in a similar situation
I get this error
W:\android-studio-projects\sharedid\app\build\intermediates\merged_manifests\flavor_customer1Debug\processFlavor_customer1DebugManifest\merged\AndroidManifest.xml:49:
error: resource string/MyAppName (aka
com.customer1.app:string/MyAppName) not found.
error: failed processing manifest.
...
My gradle contains this
flavor_customer1 {
java.srcDirs = ["W:/android-studio-projects/sharedid/app/src/main/java/"]
manifest.srcFile "W:/android-studio-projects/sharedid/app/src/customer1/AndroidManifest.xml"
assets.srcDirs = ["W:/android-studio-projects/sharedid/app/src/customer1/assets/"]
resources.srcDirs = ["W:/android-studio-projects/sharedid/app/src/main/res/", "W:/android-studio-projects/sharedid/app/src/customer1/res/"]
}
I have defined MyAppName in file
"W:/android-studio-projects/sharedid/app/src/customer1/res/values/strings_specific.xml"
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="MyAppName">Customer 1</string>
</resources>
In "W:/android-studio-projects/sharedid/app/src/customer1/AndroidManifest.xml" I use the string like this
<application
android:allowBackup="true"
android:icon="#drawable/app_logo__forlarge"
android:label="#string/MyAppName"
android:theme="#style/AppBaseTheme_Customer_One"
android:name="com.shared.app.MyApp"
>
...
What am I missing? I am trying to switch over to using product flavors
Apparentlt merge depends on "main" folder also containing strings.xml even though each flavor has their own