diff --git a/AlternateAppIcons/iOS/AlternateAppIcons.csproj b/AlternateAppIcons/iOS/AlternateAppIcons.csproj
new file mode 100644
index 0000000..2470ed4
--- /dev/null
+++ b/AlternateAppIcons/iOS/AlternateAppIcons.csproj
@@ -0,0 +1,21 @@
+
+
+ net9.0-ios
+ Exe
+ enable
+ true
+ 13.0
+
+
+ full
+
+ AppIcon
+
+
+
+
+
+
diff --git a/AlternateAppIcons/iOS/AppDelegate.cs b/AlternateAppIcons/iOS/AppDelegate.cs
new file mode 100644
index 0000000..bc57ad9
--- /dev/null
+++ b/AlternateAppIcons/iOS/AppDelegate.cs
@@ -0,0 +1,128 @@
+namespace AlternateAppIcons;
+
+using UserNotifications;
+
+[Register ("AppDelegate")]
+public class AppDelegate : UIApplicationDelegate {
+ UIColor blue = UIColor.FromRGB (81, 43, 212);
+ UIColor green = UIColor.FromRGB (119, 187, 65);
+ UILabel? label;
+ int badgeCount;
+
+ public override UIWindow? Window {
+ get;
+ set;
+ }
+
+ public override bool FinishedLaunching (UIApplication application, NSDictionary launchOptions)
+ {
+ // create a new window instance based on the screen size
+ Window = new UIWindow (UIScreen.MainScreen.Bounds);
+
+ // create a UIViewController with a single UILabel
+ var vc = new UIViewController ();
+
+ var stackView = new UIStackView (Window.Frame);
+ stackView.Axis = UILayoutConstraintAxis.Vertical;
+ stackView.Distribution = UIStackViewDistribution.FillEqually;
+
+ label = new UILabel () {
+ TextColor = blue,
+ TextAlignment = UITextAlignment.Center,
+ Text = "Hello, App Icon Switcher!",
+ AutoresizingMask = UIViewAutoresizing.All,
+ };
+ stackView.AddArrangedSubview (label);
+
+ var primaryIconButton = UIButton.FromType (UIButtonType.RoundedRect);
+ primaryIconButton.SetTitle ("Switch to primary icon", UIControlState.Normal);
+ primaryIconButton.SetTitleColor (blue, UIControlState.Normal);
+ primaryIconButton.TouchUpInside += async (sender, args) => await UsePrimaryIconAsync ();
+ primaryIconButton.Enabled = UIApplication.SharedApplication.SupportsAlternateIcons;
+ stackView.AddArrangedSubview (primaryIconButton);
+
+ var alternateIconButton = UIButton.FromType (UIButtonType.RoundedRect);
+ alternateIconButton.SetTitle ("Switch to alternate icon", UIControlState.Normal);
+ alternateIconButton.SetTitleColor (green, UIControlState.Normal);
+ alternateIconButton.TouchUpInside += async (sender, args) => await UseAlternateIconAsync ();
+ alternateIconButton.Enabled = UIApplication.SharedApplication.SupportsAlternateIcons;
+ stackView.AddArrangedSubview (alternateIconButton);
+
+ var incrementBadgeCount = UIButton.FromType (UIButtonType.RoundedRect);
+ incrementBadgeCount.SetTitle ("Increment badge count", UIControlState.Normal);
+ incrementBadgeCount.PrimaryActionTriggered += (sender, args) => SetBadgeCount (badgeCount + 1);
+ incrementBadgeCount.Enabled = UIApplication.SharedApplication.SupportsAlternateIcons;
+ stackView.AddArrangedSubview (incrementBadgeCount);
+
+ var decrementBadgeCount = UIButton.FromType (UIButtonType.RoundedRect);
+ decrementBadgeCount.SetTitle ("Decrement badge count", UIControlState.Normal);
+ decrementBadgeCount.PrimaryActionTriggered += (sender, args) => SetBadgeCount (badgeCount - 1);
+ decrementBadgeCount.Enabled = UIApplication.SharedApplication.SupportsAlternateIcons;
+ stackView.AddArrangedSubview (decrementBadgeCount);
+
+ vc.View!.AddSubview (stackView);
+ Window.RootViewController = vc;
+
+ // make the window visible
+ Window.MakeKeyAndVisible ();
+
+ return true;
+ }
+
+ void SetBadgeCount (int count)
+ {
+ if (count >= 0) {
+ if (OperatingSystem.IsIOSVersionAtLeast (16, 0)) {
+ UNUserNotificationCenter.Current.RequestAuthorization (UNAuthorizationOptions.Badge, (bool granted, NSError error) => {
+ if (granted) {
+ UNUserNotificationCenter.Current.SetBadgeCount (count, (error) => {
+ InvokeOnMainThread (() => {
+ if (error is null) {
+ label!.Text = $"Updated badge count to {count}";
+ badgeCount = count;
+ } else {
+ label!.Text = $"Updated to update badge count: {error}";
+ }
+ });
+ });
+ } else {
+ InvokeOnMainThread (() => {
+ label!.Text = $"Denied permission to the badge: {error}";
+ });
+ }
+ });
+ } else {
+ UIApplication.SharedApplication.ApplicationIconBadgeNumber = count;
+ badgeCount = count;
+ }
+ } else {
+ label!.Text = $"Can't decrement badge count to below 0.";
+ }
+ }
+
+ async Task UsePrimaryIconAsync ()
+ {
+ label!.Text = $"Switching to primary icon...";
+ try {
+ await UIApplication.SharedApplication.SetAlternateIconNameAsync (null);
+ label!.Text = "Using primary icon";
+ label!.TextColor = blue;
+ } catch (Exception e) {
+ label!.Text = $"Failed to switch to primary icon: {e.Message}";
+ label!.TextColor = UIColor.Red;
+ }
+ }
+
+ async Task UseAlternateIconAsync ()
+ {
+ label!.Text = $"Switching to alternate icon...";
+ try {
+ await UIApplication.SharedApplication.SetAlternateIconNameAsync ("AlternateAppIcons");
+ label!.Text = $"Using alternate icon {UIApplication.SharedApplication.AlternateIconName}";
+ label!.TextColor = green;
+ } catch (Exception e) {
+ label!.Text = $"Failed to switch to alternate icon: {e.Message}";
+ label!.TextColor = UIColor.Red;
+ }
+ }
+}
diff --git a/AlternateAppIcons/iOS/Assets.xcassets/AlternateAppIcons.appiconset/Contents.json b/AlternateAppIcons/iOS/Assets.xcassets/AlternateAppIcons.appiconset/Contents.json
new file mode 100644
index 0000000..98f4d03
--- /dev/null
+++ b/AlternateAppIcons/iOS/Assets.xcassets/AlternateAppIcons.appiconset/Contents.json
@@ -0,0 +1,117 @@
+{
+ "images": [
+ {
+ "scale": "2x",
+ "size": "20x20",
+ "idiom": "iphone",
+ "filename": "Icon40.png"
+ },
+ {
+ "scale": "3x",
+ "size": "20x20",
+ "idiom": "iphone",
+ "filename": "Icon60.png"
+ },
+ {
+ "scale": "2x",
+ "size": "29x29",
+ "idiom": "iphone",
+ "filename": "Icon58.png"
+ },
+ {
+ "scale": "3x",
+ "size": "29x29",
+ "idiom": "iphone",
+ "filename": "Icon87.png"
+ },
+ {
+ "scale": "2x",
+ "size": "40x40",
+ "idiom": "iphone",
+ "filename": "Icon80.png"
+ },
+ {
+ "scale": "3x",
+ "size": "40x40",
+ "idiom": "iphone",
+ "filename": "Icon120.png"
+ },
+ {
+ "scale": "2x",
+ "size": "60x60",
+ "idiom": "iphone",
+ "filename": "Icon120.png"
+ },
+ {
+ "scale": "3x",
+ "size": "60x60",
+ "idiom": "iphone",
+ "filename": "Icon180.png"
+ },
+ {
+ "scale": "1x",
+ "size": "20x20",
+ "idiom": "ipad",
+ "filename": "Icon20.png"
+ },
+ {
+ "scale": "2x",
+ "size": "20x20",
+ "idiom": "ipad",
+ "filename": "Icon40.png"
+ },
+ {
+ "scale": "1x",
+ "size": "29x29",
+ "idiom": "ipad",
+ "filename": "Icon29.png"
+ },
+ {
+ "scale": "2x",
+ "size": "29x29",
+ "idiom": "ipad",
+ "filename": "Icon58.png"
+ },
+ {
+ "scale": "1x",
+ "size": "40x40",
+ "idiom": "ipad",
+ "filename": "Icon40.png"
+ },
+ {
+ "scale": "2x",
+ "size": "40x40",
+ "idiom": "ipad",
+ "filename": "Icon80.png"
+ },
+ {
+ "scale": "1x",
+ "size": "76x76",
+ "idiom": "ipad",
+ "filename": "Icon76.png"
+ },
+ {
+ "scale": "2x",
+ "size": "76x76",
+ "idiom": "ipad",
+ "filename": "Icon152.png"
+ },
+ {
+ "scale": "2x",
+ "size": "83.5x83.5",
+ "idiom": "ipad",
+ "filename": "Icon167.png"
+ },
+ {
+ "scale": "1x",
+ "size": "1024x1024",
+ "idiom": "ios-marketing",
+ "filename": "Icon1024.png"
+ }
+ ],
+ "properties": {},
+ "info": {
+ "version": 1,
+ "author": "xcode"
+ }
+}
\ No newline at end of file
diff --git a/AlternateAppIcons/iOS/Assets.xcassets/AlternateAppIcons.appiconset/Icon1024.png b/AlternateAppIcons/iOS/Assets.xcassets/AlternateAppIcons.appiconset/Icon1024.png
new file mode 100644
index 0000000..5070368
Binary files /dev/null and b/AlternateAppIcons/iOS/Assets.xcassets/AlternateAppIcons.appiconset/Icon1024.png differ
diff --git a/AlternateAppIcons/iOS/Assets.xcassets/AlternateAppIcons.appiconset/Icon120.png b/AlternateAppIcons/iOS/Assets.xcassets/AlternateAppIcons.appiconset/Icon120.png
new file mode 100644
index 0000000..f436513
Binary files /dev/null and b/AlternateAppIcons/iOS/Assets.xcassets/AlternateAppIcons.appiconset/Icon120.png differ
diff --git a/AlternateAppIcons/iOS/Assets.xcassets/AlternateAppIcons.appiconset/Icon152.png b/AlternateAppIcons/iOS/Assets.xcassets/AlternateAppIcons.appiconset/Icon152.png
new file mode 100644
index 0000000..867de39
Binary files /dev/null and b/AlternateAppIcons/iOS/Assets.xcassets/AlternateAppIcons.appiconset/Icon152.png differ
diff --git a/AlternateAppIcons/iOS/Assets.xcassets/AlternateAppIcons.appiconset/Icon167.png b/AlternateAppIcons/iOS/Assets.xcassets/AlternateAppIcons.appiconset/Icon167.png
new file mode 100644
index 0000000..7318c54
Binary files /dev/null and b/AlternateAppIcons/iOS/Assets.xcassets/AlternateAppIcons.appiconset/Icon167.png differ
diff --git a/AlternateAppIcons/iOS/Assets.xcassets/AlternateAppIcons.appiconset/Icon180.png b/AlternateAppIcons/iOS/Assets.xcassets/AlternateAppIcons.appiconset/Icon180.png
new file mode 100644
index 0000000..5070368
Binary files /dev/null and b/AlternateAppIcons/iOS/Assets.xcassets/AlternateAppIcons.appiconset/Icon180.png differ
diff --git a/AlternateAppIcons/iOS/Assets.xcassets/AlternateAppIcons.appiconset/Icon20.png b/AlternateAppIcons/iOS/Assets.xcassets/AlternateAppIcons.appiconset/Icon20.png
new file mode 100644
index 0000000..420df90
Binary files /dev/null and b/AlternateAppIcons/iOS/Assets.xcassets/AlternateAppIcons.appiconset/Icon20.png differ
diff --git a/AlternateAppIcons/iOS/Assets.xcassets/AlternateAppIcons.appiconset/Icon29.png b/AlternateAppIcons/iOS/Assets.xcassets/AlternateAppIcons.appiconset/Icon29.png
new file mode 100644
index 0000000..673eb6d
Binary files /dev/null and b/AlternateAppIcons/iOS/Assets.xcassets/AlternateAppIcons.appiconset/Icon29.png differ
diff --git a/AlternateAppIcons/iOS/Assets.xcassets/AlternateAppIcons.appiconset/Icon40.png b/AlternateAppIcons/iOS/Assets.xcassets/AlternateAppIcons.appiconset/Icon40.png
new file mode 100644
index 0000000..f0a0e0b
Binary files /dev/null and b/AlternateAppIcons/iOS/Assets.xcassets/AlternateAppIcons.appiconset/Icon40.png differ
diff --git a/AlternateAppIcons/iOS/Assets.xcassets/AlternateAppIcons.appiconset/Icon58.png b/AlternateAppIcons/iOS/Assets.xcassets/AlternateAppIcons.appiconset/Icon58.png
new file mode 100644
index 0000000..522f6c8
Binary files /dev/null and b/AlternateAppIcons/iOS/Assets.xcassets/AlternateAppIcons.appiconset/Icon58.png differ
diff --git a/AlternateAppIcons/iOS/Assets.xcassets/AlternateAppIcons.appiconset/Icon60.png b/AlternateAppIcons/iOS/Assets.xcassets/AlternateAppIcons.appiconset/Icon60.png
new file mode 100644
index 0000000..2b46395
Binary files /dev/null and b/AlternateAppIcons/iOS/Assets.xcassets/AlternateAppIcons.appiconset/Icon60.png differ
diff --git a/AlternateAppIcons/iOS/Assets.xcassets/AlternateAppIcons.appiconset/Icon76.png b/AlternateAppIcons/iOS/Assets.xcassets/AlternateAppIcons.appiconset/Icon76.png
new file mode 100644
index 0000000..831cd1c
Binary files /dev/null and b/AlternateAppIcons/iOS/Assets.xcassets/AlternateAppIcons.appiconset/Icon76.png differ
diff --git a/AlternateAppIcons/iOS/Assets.xcassets/AlternateAppIcons.appiconset/Icon80.png b/AlternateAppIcons/iOS/Assets.xcassets/AlternateAppIcons.appiconset/Icon80.png
new file mode 100644
index 0000000..46167e3
Binary files /dev/null and b/AlternateAppIcons/iOS/Assets.xcassets/AlternateAppIcons.appiconset/Icon80.png differ
diff --git a/AlternateAppIcons/iOS/Assets.xcassets/AlternateAppIcons.appiconset/Icon87.png b/AlternateAppIcons/iOS/Assets.xcassets/AlternateAppIcons.appiconset/Icon87.png
new file mode 100644
index 0000000..de19496
Binary files /dev/null and b/AlternateAppIcons/iOS/Assets.xcassets/AlternateAppIcons.appiconset/Icon87.png differ
diff --git a/AlternateAppIcons/iOS/Assets.xcassets/AppIcon.appiconset/Contents.json b/AlternateAppIcons/iOS/Assets.xcassets/AppIcon.appiconset/Contents.json
new file mode 100644
index 0000000..98f4d03
--- /dev/null
+++ b/AlternateAppIcons/iOS/Assets.xcassets/AppIcon.appiconset/Contents.json
@@ -0,0 +1,117 @@
+{
+ "images": [
+ {
+ "scale": "2x",
+ "size": "20x20",
+ "idiom": "iphone",
+ "filename": "Icon40.png"
+ },
+ {
+ "scale": "3x",
+ "size": "20x20",
+ "idiom": "iphone",
+ "filename": "Icon60.png"
+ },
+ {
+ "scale": "2x",
+ "size": "29x29",
+ "idiom": "iphone",
+ "filename": "Icon58.png"
+ },
+ {
+ "scale": "3x",
+ "size": "29x29",
+ "idiom": "iphone",
+ "filename": "Icon87.png"
+ },
+ {
+ "scale": "2x",
+ "size": "40x40",
+ "idiom": "iphone",
+ "filename": "Icon80.png"
+ },
+ {
+ "scale": "3x",
+ "size": "40x40",
+ "idiom": "iphone",
+ "filename": "Icon120.png"
+ },
+ {
+ "scale": "2x",
+ "size": "60x60",
+ "idiom": "iphone",
+ "filename": "Icon120.png"
+ },
+ {
+ "scale": "3x",
+ "size": "60x60",
+ "idiom": "iphone",
+ "filename": "Icon180.png"
+ },
+ {
+ "scale": "1x",
+ "size": "20x20",
+ "idiom": "ipad",
+ "filename": "Icon20.png"
+ },
+ {
+ "scale": "2x",
+ "size": "20x20",
+ "idiom": "ipad",
+ "filename": "Icon40.png"
+ },
+ {
+ "scale": "1x",
+ "size": "29x29",
+ "idiom": "ipad",
+ "filename": "Icon29.png"
+ },
+ {
+ "scale": "2x",
+ "size": "29x29",
+ "idiom": "ipad",
+ "filename": "Icon58.png"
+ },
+ {
+ "scale": "1x",
+ "size": "40x40",
+ "idiom": "ipad",
+ "filename": "Icon40.png"
+ },
+ {
+ "scale": "2x",
+ "size": "40x40",
+ "idiom": "ipad",
+ "filename": "Icon80.png"
+ },
+ {
+ "scale": "1x",
+ "size": "76x76",
+ "idiom": "ipad",
+ "filename": "Icon76.png"
+ },
+ {
+ "scale": "2x",
+ "size": "76x76",
+ "idiom": "ipad",
+ "filename": "Icon152.png"
+ },
+ {
+ "scale": "2x",
+ "size": "83.5x83.5",
+ "idiom": "ipad",
+ "filename": "Icon167.png"
+ },
+ {
+ "scale": "1x",
+ "size": "1024x1024",
+ "idiom": "ios-marketing",
+ "filename": "Icon1024.png"
+ }
+ ],
+ "properties": {},
+ "info": {
+ "version": 1,
+ "author": "xcode"
+ }
+}
\ No newline at end of file
diff --git a/AlternateAppIcons/iOS/Assets.xcassets/AppIcon.appiconset/Icon1024.png b/AlternateAppIcons/iOS/Assets.xcassets/AppIcon.appiconset/Icon1024.png
new file mode 100644
index 0000000..b573205
Binary files /dev/null and b/AlternateAppIcons/iOS/Assets.xcassets/AppIcon.appiconset/Icon1024.png differ
diff --git a/AlternateAppIcons/iOS/Assets.xcassets/AppIcon.appiconset/Icon120.png b/AlternateAppIcons/iOS/Assets.xcassets/AppIcon.appiconset/Icon120.png
new file mode 100644
index 0000000..0b74155
Binary files /dev/null and b/AlternateAppIcons/iOS/Assets.xcassets/AppIcon.appiconset/Icon120.png differ
diff --git a/AlternateAppIcons/iOS/Assets.xcassets/AppIcon.appiconset/Icon152.png b/AlternateAppIcons/iOS/Assets.xcassets/AppIcon.appiconset/Icon152.png
new file mode 100644
index 0000000..1c19313
Binary files /dev/null and b/AlternateAppIcons/iOS/Assets.xcassets/AppIcon.appiconset/Icon152.png differ
diff --git a/AlternateAppIcons/iOS/Assets.xcassets/AppIcon.appiconset/Icon167.png b/AlternateAppIcons/iOS/Assets.xcassets/AppIcon.appiconset/Icon167.png
new file mode 100644
index 0000000..4e3e8bd
Binary files /dev/null and b/AlternateAppIcons/iOS/Assets.xcassets/AppIcon.appiconset/Icon167.png differ
diff --git a/AlternateAppIcons/iOS/Assets.xcassets/AppIcon.appiconset/Icon180.png b/AlternateAppIcons/iOS/Assets.xcassets/AppIcon.appiconset/Icon180.png
new file mode 100644
index 0000000..40a7371
Binary files /dev/null and b/AlternateAppIcons/iOS/Assets.xcassets/AppIcon.appiconset/Icon180.png differ
diff --git a/AlternateAppIcons/iOS/Assets.xcassets/AppIcon.appiconset/Icon20.png b/AlternateAppIcons/iOS/Assets.xcassets/AppIcon.appiconset/Icon20.png
new file mode 100644
index 0000000..8bb1383
Binary files /dev/null and b/AlternateAppIcons/iOS/Assets.xcassets/AppIcon.appiconset/Icon20.png differ
diff --git a/AlternateAppIcons/iOS/Assets.xcassets/AppIcon.appiconset/Icon29.png b/AlternateAppIcons/iOS/Assets.xcassets/AppIcon.appiconset/Icon29.png
new file mode 100644
index 0000000..bdd130c
Binary files /dev/null and b/AlternateAppIcons/iOS/Assets.xcassets/AppIcon.appiconset/Icon29.png differ
diff --git a/AlternateAppIcons/iOS/Assets.xcassets/AppIcon.appiconset/Icon40.png b/AlternateAppIcons/iOS/Assets.xcassets/AppIcon.appiconset/Icon40.png
new file mode 100644
index 0000000..75d2789
Binary files /dev/null and b/AlternateAppIcons/iOS/Assets.xcassets/AppIcon.appiconset/Icon40.png differ
diff --git a/AlternateAppIcons/iOS/Assets.xcassets/AppIcon.appiconset/Icon58.png b/AlternateAppIcons/iOS/Assets.xcassets/AppIcon.appiconset/Icon58.png
new file mode 100644
index 0000000..06afa60
Binary files /dev/null and b/AlternateAppIcons/iOS/Assets.xcassets/AppIcon.appiconset/Icon58.png differ
diff --git a/AlternateAppIcons/iOS/Assets.xcassets/AppIcon.appiconset/Icon60.png b/AlternateAppIcons/iOS/Assets.xcassets/AppIcon.appiconset/Icon60.png
new file mode 100644
index 0000000..2e0db2a
Binary files /dev/null and b/AlternateAppIcons/iOS/Assets.xcassets/AppIcon.appiconset/Icon60.png differ
diff --git a/AlternateAppIcons/iOS/Assets.xcassets/AppIcon.appiconset/Icon76.png b/AlternateAppIcons/iOS/Assets.xcassets/AppIcon.appiconset/Icon76.png
new file mode 100644
index 0000000..755bc88
Binary files /dev/null and b/AlternateAppIcons/iOS/Assets.xcassets/AppIcon.appiconset/Icon76.png differ
diff --git a/AlternateAppIcons/iOS/Assets.xcassets/AppIcon.appiconset/Icon80.png b/AlternateAppIcons/iOS/Assets.xcassets/AppIcon.appiconset/Icon80.png
new file mode 100644
index 0000000..6559bb4
Binary files /dev/null and b/AlternateAppIcons/iOS/Assets.xcassets/AppIcon.appiconset/Icon80.png differ
diff --git a/AlternateAppIcons/iOS/Assets.xcassets/AppIcon.appiconset/Icon87.png b/AlternateAppIcons/iOS/Assets.xcassets/AppIcon.appiconset/Icon87.png
new file mode 100644
index 0000000..ca28c8d
Binary files /dev/null and b/AlternateAppIcons/iOS/Assets.xcassets/AppIcon.appiconset/Icon87.png differ
diff --git a/AlternateAppIcons/iOS/Entitlements.plist b/AlternateAppIcons/iOS/Entitlements.plist
new file mode 100644
index 0000000..36a8706
--- /dev/null
+++ b/AlternateAppIcons/iOS/Entitlements.plist
@@ -0,0 +1,6 @@
+
+
+
+
+
+
diff --git a/AlternateAppIcons/iOS/Info.plist b/AlternateAppIcons/iOS/Info.plist
new file mode 100644
index 0000000..d17d237
--- /dev/null
+++ b/AlternateAppIcons/iOS/Info.plist
@@ -0,0 +1,40 @@
+
+
+
+
+ CFBundleDisplayName
+ AlternateAppIcons
+ CFBundleIdentifier
+ com.companyname.AlternateAppIcons
+ CFBundleShortVersionString
+ 1.0
+ CFBundleVersion
+ 1.0
+ LSRequiresIPhoneOS
+
+ UIDeviceFamily
+
+ 1
+ 2
+
+ UILaunchStoryboardName
+ LaunchScreen
+ UIRequiredDeviceCapabilities
+
+ armv7
+
+ UISupportedInterfaceOrientations
+
+ UIInterfaceOrientationPortrait
+ UIInterfaceOrientationLandscapeLeft
+ UIInterfaceOrientationLandscapeRight
+
+ UISupportedInterfaceOrientations~ipad
+
+ UIInterfaceOrientationPortrait
+ UIInterfaceOrientationPortraitUpsideDown
+ UIInterfaceOrientationLandscapeLeft
+ UIInterfaceOrientationLandscapeRight
+
+
+
diff --git a/AlternateAppIcons/iOS/LaunchScreen.storyboard b/AlternateAppIcons/iOS/LaunchScreen.storyboard
new file mode 100644
index 0000000..2296c6b
--- /dev/null
+++ b/AlternateAppIcons/iOS/LaunchScreen.storyboard
@@ -0,0 +1,26 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/AlternateAppIcons/iOS/Main.cs b/AlternateAppIcons/iOS/Main.cs
new file mode 100644
index 0000000..f39ee13
--- /dev/null
+++ b/AlternateAppIcons/iOS/Main.cs
@@ -0,0 +1,6 @@
+using AlternateAppIcons;
+
+// This is the main entry point of the application.
+// If you want to use a different Application Delegate class from "AppDelegate"
+// you can specify it here.
+UIApplication.Main (args, null, typeof (AppDelegate));
diff --git a/AlternateAppIcons/iOS/README.md b/AlternateAppIcons/iOS/README.md
new file mode 100644
index 0000000..92aa997
--- /dev/null
+++ b/AlternateAppIcons/iOS/README.md
@@ -0,0 +1,17 @@
+---
+name: Alternate App Icon in iOS
+description: "Demonstrates how to change the app icon dynamically in a .NET for iOS app"
+page_type: sample
+languages:
+- csharp
+products:
+- dotnet-macios
+urlFragment: alternateappicons-ios
+---
+
+# Alternate App Icon in iOS
+
+Alternate App Icon is a sample app that accompanies the article [Alternate App Icons in .NET for iOS and tvOS](#todo-link).
+
+It demonstrates how to change the app icon at runtime.
+
diff --git a/AlternateAppIcons/iOS/Resources/LaunchScreen.xib b/AlternateAppIcons/iOS/Resources/LaunchScreen.xib
new file mode 100644
index 0000000..8190201
--- /dev/null
+++ b/AlternateAppIcons/iOS/Resources/LaunchScreen.xib
@@ -0,0 +1,43 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/AlternateAppIcons/iOS/SceneDelegate.cs b/AlternateAppIcons/iOS/SceneDelegate.cs
new file mode 100644
index 0000000..0bdc0b5
--- /dev/null
+++ b/AlternateAppIcons/iOS/SceneDelegate.cs
@@ -0,0 +1,54 @@
+namespace AlternateAppIcons;
+
+[Register ("SceneDelegate")]
+public class SceneDelegate : UIResponder, IUIWindowSceneDelegate {
+
+ [Export ("window")]
+ public UIWindow? Window { get; set; }
+
+ [Export ("scene:willConnectToSession:options:")]
+ public void WillConnect (UIScene scene, UISceneSession session, UISceneConnectionOptions connectionOptions)
+ {
+ // Use this method to optionally configure and attach the UIWindow `window` to the provided UIWindowScene `scene`.
+ // If using a storyboard, the `window` property will automatically be initialized and attached to the scene.
+ // This delegate does not imply the connecting scene or session are new (see UIApplicationDelegate `GetConfiguration` instead).
+ }
+
+ [Export ("sceneDidDisconnect:")]
+ public void DidDisconnect (UIScene scene)
+ {
+ // Called as the scene is being released by the system.
+ // This occurs shortly after the scene enters the background, or when its session is discarded.
+ // Release any resources associated with this scene that can be re-created the next time the scene connects.
+ // The scene may re-connect later, as its session was not neccessarily discarded (see UIApplicationDelegate `DidDiscardSceneSessions` instead).
+ }
+
+ [Export ("sceneDidBecomeActive:")]
+ public void DidBecomeActive (UIScene scene)
+ {
+ // Called when the scene has moved from an inactive state to an active state.
+ // Use this method to restart any tasks that were paused (or not yet started) when the scene was inactive.
+ }
+
+ [Export ("sceneWillResignActive:")]
+ public void WillResignActive (UIScene scene)
+ {
+ // Called when the scene will move from an active state to an inactive state.
+ // This may occur due to temporary interruptions (ex. an incoming phone call).
+ }
+
+ [Export ("sceneWillEnterForeground:")]
+ public void WillEnterForeground (UIScene scene)
+ {
+ // Called as the scene transitions from the background to the foreground.
+ // Use this method to undo the changes made on entering the background.
+ }
+
+ [Export ("sceneDidEnterBackground:")]
+ public void DidEnterBackground (UIScene scene)
+ {
+ // Called as the scene transitions from the foreground to the background.
+ // Use this method to save data, release shared resources, and store enough scene-specific state information
+ // to restore the scene back to its current state.
+ }
+}
diff --git a/AlternateAppIcons/iOS/screenshot.png b/AlternateAppIcons/iOS/screenshot.png
new file mode 100644
index 0000000..e07e83d
Binary files /dev/null and b/AlternateAppIcons/iOS/screenshot.png differ
diff --git a/AlternateAppIcons/tvOS/AlternateAppIcons.csproj b/AlternateAppIcons/tvOS/AlternateAppIcons.csproj
new file mode 100644
index 0000000..1e119d2
--- /dev/null
+++ b/AlternateAppIcons/tvOS/AlternateAppIcons.csproj
@@ -0,0 +1,21 @@
+
+
+ net9.0-tvos
+ Exe
+ enable
+ true
+ 12.2
+
+
+ full
+
+ App Icon & Top Shelf Image
+
+
+
+
+
+
diff --git a/AlternateAppIcons/tvOS/AppDelegate.cs b/AlternateAppIcons/tvOS/AppDelegate.cs
new file mode 100644
index 0000000..36ced59
--- /dev/null
+++ b/AlternateAppIcons/tvOS/AppDelegate.cs
@@ -0,0 +1,134 @@
+namespace AlternateAppIcons;
+
+using System.Runtime.Versioning;
+
+using UserNotifications;
+
+[Register ("AppDelegate")]
+public class AppDelegate : UIApplicationDelegate {
+ UIColor blue = UIColor.FromRGB (81, 43, 212);
+ UIColor green = UIColor.FromRGB (119, 187, 65);
+ UILabel? label;
+ int badgeCount;
+
+ public override UIWindow? Window {
+ get;
+ set;
+ }
+
+ public override bool FinishedLaunching (UIApplication application, NSDictionary launchOptions)
+ {
+ // create a new window instance based on the screen size
+ Window = new UIWindow (UIScreen.MainScreen.Bounds);
+
+ // create a UIViewController with a single UILabel
+ var vc = new UIViewController ();
+
+ var stackView = new UIStackView (Window.Frame);
+ stackView.Axis = UILayoutConstraintAxis.Vertical;
+ stackView.Distribution = UIStackViewDistribution.FillEqually;
+
+ label = new UILabel () {
+ TextColor = blue,
+ TextAlignment = UITextAlignment.Center,
+ Text = "Hello, App Icon Switcher!",
+ AutoresizingMask = UIViewAutoresizing.All,
+ };
+ stackView.AddArrangedSubview (label);
+
+ var primaryIconButton = UIButton.FromType (UIButtonType.Plain);
+ primaryIconButton.SetTitle ("Switch to primary icon", UIControlState.Normal);
+ primaryIconButton.SetTitleColor (blue, UIControlState.Normal);
+ primaryIconButton.PrimaryActionTriggered += async (sender, args) => await UsePrimaryIconAsync ();
+ primaryIconButton.Enabled = UIApplication.SharedApplication.SupportsAlternateIcons;
+ stackView.AddArrangedSubview (primaryIconButton);
+
+ var alternateIconButton = UIButton.FromType (UIButtonType.Plain);
+ alternateIconButton.SetTitle ("Switch to alternate icon", UIControlState.Normal);
+ alternateIconButton.SetTitleColor (green, UIControlState.Normal);
+ alternateIconButton.PrimaryActionTriggered += async (sender, args) => await UseAlternateIconAsync ();
+ alternateIconButton.Enabled = UIApplication.SharedApplication.SupportsAlternateIcons;
+ stackView.AddArrangedSubview (alternateIconButton);
+
+ var incrementBadgeCount = UIButton.FromType (UIButtonType.Plain);
+ incrementBadgeCount.SetTitle ("Increment badge count", UIControlState.Normal);
+ incrementBadgeCount.PrimaryActionTriggered += (sender, args) => SetBadgeCount (badgeCount + 1);
+ incrementBadgeCount.Enabled = UIApplication.SharedApplication.SupportsAlternateIcons;
+ stackView.AddArrangedSubview (incrementBadgeCount);
+
+ var decrementBadgeCount = UIButton.FromType (UIButtonType.Plain);
+ decrementBadgeCount.SetTitle ("Decrement badge count", UIControlState.Normal);
+ decrementBadgeCount.PrimaryActionTriggered += (sender, args) => SetBadgeCount (badgeCount - 1);
+ decrementBadgeCount.Enabled = UIApplication.SharedApplication.SupportsAlternateIcons;
+ stackView.AddArrangedSubview (decrementBadgeCount);
+
+ var view = vc.View!;
+ view.AddSubview (stackView);
+ view.UserInteractionEnabled = true;
+ Window.RootViewController = vc;
+
+ // make the window visible
+ Window.MakeKeyAndVisible ();
+
+ return true;
+ }
+
+ void SetBadgeCount (int count)
+ {
+ if (count >= 0) {
+ if (OperatingSystem.IsTvOSVersionAtLeast (16, 0)) {
+ UNUserNotificationCenter.Current.RequestAuthorization (UNAuthorizationOptions.Badge, [SupportedOSPlatform ("tvos16.0")] (bool granted, NSError error) => {
+ if (granted) {
+#pragma warning disable CA1416 // This call site is reachable on: 'tvOS' 12.2 and later. 'UNUserNotificationCenter.SetBadgeCount(nint, Action?)' is only supported on: 'ios' 16.0 and later, 'maccatalyst' 16.0 and later, 'macOS/OSX' 13.0 and later, 'tvos' 16.0 and later.)
+ UNUserNotificationCenter.Current.SetBadgeCount (count, (error) => {
+#pragma warning restore CA1416
+ InvokeOnMainThread (() => {
+ if (error is null) {
+ label!.Text = $"Updated badge count to {count}";
+ badgeCount = count;
+ } else {
+ label!.Text = $"Updated to update badge count: {error}";
+ }
+ });
+ });
+ } else {
+ InvokeOnMainThread (() => {
+ label!.Text = $"Denied permission to the badge: {error}";
+ });
+ }
+ });
+ } else {
+ UIApplication.SharedApplication.ApplicationIconBadgeNumber = count;
+ badgeCount = count;
+ }
+ } else {
+ label!.Text = $"Can't decrement badge count to below 0.";
+ }
+ }
+
+ async Task UsePrimaryIconAsync ()
+ {
+ label!.Text = $"Switching to primary icon...";
+ try {
+ await UIApplication.SharedApplication.SetAlternateIconNameAsync (null);
+ label!.Text = "Using primary icon";
+ label!.TextColor = blue;
+ } catch (Exception e) {
+ label!.Text = $"Failed to switch to primary icon: {e.Message}";
+ label!.TextColor = UIColor.Red;
+ }
+ }
+
+ async Task UseAlternateIconAsync ()
+ {
+ label!.Text = $"Switching to alternate icon...";
+ try {
+ await UIApplication.SharedApplication.SetAlternateIconNameAsync ("AlternateAppIcons");
+ label!.Text = $"Using alternate icon {UIApplication.SharedApplication.AlternateIconName}";
+ label!.TextColor = green;
+ } catch (Exception e) {
+ label!.Text = $"Failed to switch to alternate icon: {e.Message}";
+ label!.TextColor = UIColor.Red;
+ }
+ }
+}
diff --git a/AlternateAppIcons/tvOS/Assets.xcassets/AlternateAppIcons.imagestack/Back.imagestacklayer/Content.imageset/Contents.json b/AlternateAppIcons/tvOS/Assets.xcassets/AlternateAppIcons.imagestack/Back.imagestacklayer/Content.imageset/Contents.json
new file mode 100644
index 0000000..b04945d
--- /dev/null
+++ b/AlternateAppIcons/tvOS/Assets.xcassets/AlternateAppIcons.imagestack/Back.imagestacklayer/Content.imageset/Contents.json
@@ -0,0 +1,18 @@
+{
+ "images" : [
+ {
+ "filename" : "Icon-green-400x240.png",
+ "idiom" : "tv",
+ "scale" : "1x"
+ },
+ {
+ "filename" : "Icon-green-400x240.png",
+ "idiom" : "tv",
+ "scale" : "2x"
+ }
+ ],
+ "info" : {
+ "author" : "xcode",
+ "version" : 1
+ }
+}
diff --git a/AlternateAppIcons/tvOS/Assets.xcassets/AlternateAppIcons.imagestack/Back.imagestacklayer/Content.imageset/Icon-green-400x240.png b/AlternateAppIcons/tvOS/Assets.xcassets/AlternateAppIcons.imagestack/Back.imagestacklayer/Content.imageset/Icon-green-400x240.png
new file mode 100644
index 0000000..f558229
Binary files /dev/null and b/AlternateAppIcons/tvOS/Assets.xcassets/AlternateAppIcons.imagestack/Back.imagestacklayer/Content.imageset/Icon-green-400x240.png differ
diff --git a/AlternateAppIcons/tvOS/Assets.xcassets/AlternateAppIcons.imagestack/Back.imagestacklayer/Contents.json b/AlternateAppIcons/tvOS/Assets.xcassets/AlternateAppIcons.imagestack/Back.imagestacklayer/Contents.json
new file mode 100644
index 0000000..73c0059
--- /dev/null
+++ b/AlternateAppIcons/tvOS/Assets.xcassets/AlternateAppIcons.imagestack/Back.imagestacklayer/Contents.json
@@ -0,0 +1,6 @@
+{
+ "info" : {
+ "author" : "xcode",
+ "version" : 1
+ }
+}
diff --git a/AlternateAppIcons/tvOS/Assets.xcassets/AlternateAppIcons.imagestack/Contents.json b/AlternateAppIcons/tvOS/Assets.xcassets/AlternateAppIcons.imagestack/Contents.json
new file mode 100644
index 0000000..de59d88
--- /dev/null
+++ b/AlternateAppIcons/tvOS/Assets.xcassets/AlternateAppIcons.imagestack/Contents.json
@@ -0,0 +1,17 @@
+{
+ "info" : {
+ "author" : "xcode",
+ "version" : 1
+ },
+ "layers" : [
+ {
+ "filename" : "Front.imagestacklayer"
+ },
+ {
+ "filename" : "Middle.imagestacklayer"
+ },
+ {
+ "filename" : "Back.imagestacklayer"
+ }
+ ]
+}
diff --git a/AlternateAppIcons/tvOS/Assets.xcassets/AlternateAppIcons.imagestack/Front.imagestacklayer/Content.imageset/Contents.json b/AlternateAppIcons/tvOS/Assets.xcassets/AlternateAppIcons.imagestack/Front.imagestacklayer/Content.imageset/Contents.json
new file mode 100644
index 0000000..b04945d
--- /dev/null
+++ b/AlternateAppIcons/tvOS/Assets.xcassets/AlternateAppIcons.imagestack/Front.imagestacklayer/Content.imageset/Contents.json
@@ -0,0 +1,18 @@
+{
+ "images" : [
+ {
+ "filename" : "Icon-green-400x240.png",
+ "idiom" : "tv",
+ "scale" : "1x"
+ },
+ {
+ "filename" : "Icon-green-400x240.png",
+ "idiom" : "tv",
+ "scale" : "2x"
+ }
+ ],
+ "info" : {
+ "author" : "xcode",
+ "version" : 1
+ }
+}
diff --git a/AlternateAppIcons/tvOS/Assets.xcassets/AlternateAppIcons.imagestack/Front.imagestacklayer/Content.imageset/Icon-green-400x240.png b/AlternateAppIcons/tvOS/Assets.xcassets/AlternateAppIcons.imagestack/Front.imagestacklayer/Content.imageset/Icon-green-400x240.png
new file mode 100644
index 0000000..f558229
Binary files /dev/null and b/AlternateAppIcons/tvOS/Assets.xcassets/AlternateAppIcons.imagestack/Front.imagestacklayer/Content.imageset/Icon-green-400x240.png differ
diff --git a/AlternateAppIcons/tvOS/Assets.xcassets/AlternateAppIcons.imagestack/Front.imagestacklayer/Contents.json b/AlternateAppIcons/tvOS/Assets.xcassets/AlternateAppIcons.imagestack/Front.imagestacklayer/Contents.json
new file mode 100644
index 0000000..73c0059
--- /dev/null
+++ b/AlternateAppIcons/tvOS/Assets.xcassets/AlternateAppIcons.imagestack/Front.imagestacklayer/Contents.json
@@ -0,0 +1,6 @@
+{
+ "info" : {
+ "author" : "xcode",
+ "version" : 1
+ }
+}
diff --git a/AlternateAppIcons/tvOS/Assets.xcassets/AlternateAppIcons.imagestack/Middle.imagestacklayer/Content.imageset/Contents.json b/AlternateAppIcons/tvOS/Assets.xcassets/AlternateAppIcons.imagestack/Middle.imagestacklayer/Content.imageset/Contents.json
new file mode 100644
index 0000000..b04945d
--- /dev/null
+++ b/AlternateAppIcons/tvOS/Assets.xcassets/AlternateAppIcons.imagestack/Middle.imagestacklayer/Content.imageset/Contents.json
@@ -0,0 +1,18 @@
+{
+ "images" : [
+ {
+ "filename" : "Icon-green-400x240.png",
+ "idiom" : "tv",
+ "scale" : "1x"
+ },
+ {
+ "filename" : "Icon-green-400x240.png",
+ "idiom" : "tv",
+ "scale" : "2x"
+ }
+ ],
+ "info" : {
+ "author" : "xcode",
+ "version" : 1
+ }
+}
diff --git a/AlternateAppIcons/tvOS/Assets.xcassets/AlternateAppIcons.imagestack/Middle.imagestacklayer/Content.imageset/Icon-green-400x240.png b/AlternateAppIcons/tvOS/Assets.xcassets/AlternateAppIcons.imagestack/Middle.imagestacklayer/Content.imageset/Icon-green-400x240.png
new file mode 100644
index 0000000..f558229
Binary files /dev/null and b/AlternateAppIcons/tvOS/Assets.xcassets/AlternateAppIcons.imagestack/Middle.imagestacklayer/Content.imageset/Icon-green-400x240.png differ
diff --git a/AlternateAppIcons/tvOS/Assets.xcassets/AlternateAppIcons.imagestack/Middle.imagestacklayer/Contents.json b/AlternateAppIcons/tvOS/Assets.xcassets/AlternateAppIcons.imagestack/Middle.imagestacklayer/Contents.json
new file mode 100644
index 0000000..73c0059
--- /dev/null
+++ b/AlternateAppIcons/tvOS/Assets.xcassets/AlternateAppIcons.imagestack/Middle.imagestacklayer/Contents.json
@@ -0,0 +1,6 @@
+{
+ "info" : {
+ "author" : "xcode",
+ "version" : 1
+ }
+}
diff --git a/AlternateAppIcons/tvOS/Assets.xcassets/App Icon & Top Shelf Image.brandassets/AppIcons-AppStore.imagestack/Back.imagestacklayer/Content.imageset/Contents.json b/AlternateAppIcons/tvOS/Assets.xcassets/App Icon & Top Shelf Image.brandassets/AppIcons-AppStore.imagestack/Back.imagestacklayer/Content.imageset/Contents.json
new file mode 100644
index 0000000..a6e8f99
--- /dev/null
+++ b/AlternateAppIcons/tvOS/Assets.xcassets/App Icon & Top Shelf Image.brandassets/AppIcons-AppStore.imagestack/Back.imagestacklayer/Content.imageset/Contents.json
@@ -0,0 +1,12 @@
+{
+ "images" : [
+ {
+ "filename" : "Icon-blue-1280x768.png",
+ "idiom" : "tv"
+ }
+ ],
+ "info" : {
+ "author" : "xcode",
+ "version" : 1
+ }
+}
diff --git a/AlternateAppIcons/tvOS/Assets.xcassets/App Icon & Top Shelf Image.brandassets/AppIcons-AppStore.imagestack/Back.imagestacklayer/Content.imageset/Icon-blue-1280x768.png b/AlternateAppIcons/tvOS/Assets.xcassets/App Icon & Top Shelf Image.brandassets/AppIcons-AppStore.imagestack/Back.imagestacklayer/Content.imageset/Icon-blue-1280x768.png
new file mode 100644
index 0000000..459f3f2
Binary files /dev/null and b/AlternateAppIcons/tvOS/Assets.xcassets/App Icon & Top Shelf Image.brandassets/AppIcons-AppStore.imagestack/Back.imagestacklayer/Content.imageset/Icon-blue-1280x768.png differ
diff --git a/AlternateAppIcons/tvOS/Assets.xcassets/App Icon & Top Shelf Image.brandassets/AppIcons-AppStore.imagestack/Back.imagestacklayer/Contents.json b/AlternateAppIcons/tvOS/Assets.xcassets/App Icon & Top Shelf Image.brandassets/AppIcons-AppStore.imagestack/Back.imagestacklayer/Contents.json
new file mode 100644
index 0000000..73c0059
--- /dev/null
+++ b/AlternateAppIcons/tvOS/Assets.xcassets/App Icon & Top Shelf Image.brandassets/AppIcons-AppStore.imagestack/Back.imagestacklayer/Contents.json
@@ -0,0 +1,6 @@
+{
+ "info" : {
+ "author" : "xcode",
+ "version" : 1
+ }
+}
diff --git a/AlternateAppIcons/tvOS/Assets.xcassets/App Icon & Top Shelf Image.brandassets/AppIcons-AppStore.imagestack/Contents.json b/AlternateAppIcons/tvOS/Assets.xcassets/App Icon & Top Shelf Image.brandassets/AppIcons-AppStore.imagestack/Contents.json
new file mode 100644
index 0000000..de59d88
--- /dev/null
+++ b/AlternateAppIcons/tvOS/Assets.xcassets/App Icon & Top Shelf Image.brandassets/AppIcons-AppStore.imagestack/Contents.json
@@ -0,0 +1,17 @@
+{
+ "info" : {
+ "author" : "xcode",
+ "version" : 1
+ },
+ "layers" : [
+ {
+ "filename" : "Front.imagestacklayer"
+ },
+ {
+ "filename" : "Middle.imagestacklayer"
+ },
+ {
+ "filename" : "Back.imagestacklayer"
+ }
+ ]
+}
diff --git a/AlternateAppIcons/tvOS/Assets.xcassets/App Icon & Top Shelf Image.brandassets/AppIcons-AppStore.imagestack/Front.imagestacklayer/Content.imageset/Contents.json b/AlternateAppIcons/tvOS/Assets.xcassets/App Icon & Top Shelf Image.brandassets/AppIcons-AppStore.imagestack/Front.imagestacklayer/Content.imageset/Contents.json
new file mode 100644
index 0000000..a6e8f99
--- /dev/null
+++ b/AlternateAppIcons/tvOS/Assets.xcassets/App Icon & Top Shelf Image.brandassets/AppIcons-AppStore.imagestack/Front.imagestacklayer/Content.imageset/Contents.json
@@ -0,0 +1,12 @@
+{
+ "images" : [
+ {
+ "filename" : "Icon-blue-1280x768.png",
+ "idiom" : "tv"
+ }
+ ],
+ "info" : {
+ "author" : "xcode",
+ "version" : 1
+ }
+}
diff --git a/AlternateAppIcons/tvOS/Assets.xcassets/App Icon & Top Shelf Image.brandassets/AppIcons-AppStore.imagestack/Front.imagestacklayer/Content.imageset/Icon-blue-1280x768.png b/AlternateAppIcons/tvOS/Assets.xcassets/App Icon & Top Shelf Image.brandassets/AppIcons-AppStore.imagestack/Front.imagestacklayer/Content.imageset/Icon-blue-1280x768.png
new file mode 100644
index 0000000..459f3f2
Binary files /dev/null and b/AlternateAppIcons/tvOS/Assets.xcassets/App Icon & Top Shelf Image.brandassets/AppIcons-AppStore.imagestack/Front.imagestacklayer/Content.imageset/Icon-blue-1280x768.png differ
diff --git a/AlternateAppIcons/tvOS/Assets.xcassets/App Icon & Top Shelf Image.brandassets/AppIcons-AppStore.imagestack/Front.imagestacklayer/Contents.json b/AlternateAppIcons/tvOS/Assets.xcassets/App Icon & Top Shelf Image.brandassets/AppIcons-AppStore.imagestack/Front.imagestacklayer/Contents.json
new file mode 100644
index 0000000..73c0059
--- /dev/null
+++ b/AlternateAppIcons/tvOS/Assets.xcassets/App Icon & Top Shelf Image.brandassets/AppIcons-AppStore.imagestack/Front.imagestacklayer/Contents.json
@@ -0,0 +1,6 @@
+{
+ "info" : {
+ "author" : "xcode",
+ "version" : 1
+ }
+}
diff --git a/AlternateAppIcons/tvOS/Assets.xcassets/App Icon & Top Shelf Image.brandassets/AppIcons-AppStore.imagestack/Middle.imagestacklayer/Content.imageset/Contents.json b/AlternateAppIcons/tvOS/Assets.xcassets/App Icon & Top Shelf Image.brandassets/AppIcons-AppStore.imagestack/Middle.imagestacklayer/Content.imageset/Contents.json
new file mode 100644
index 0000000..a6e8f99
--- /dev/null
+++ b/AlternateAppIcons/tvOS/Assets.xcassets/App Icon & Top Shelf Image.brandassets/AppIcons-AppStore.imagestack/Middle.imagestacklayer/Content.imageset/Contents.json
@@ -0,0 +1,12 @@
+{
+ "images" : [
+ {
+ "filename" : "Icon-blue-1280x768.png",
+ "idiom" : "tv"
+ }
+ ],
+ "info" : {
+ "author" : "xcode",
+ "version" : 1
+ }
+}
diff --git a/AlternateAppIcons/tvOS/Assets.xcassets/App Icon & Top Shelf Image.brandassets/AppIcons-AppStore.imagestack/Middle.imagestacklayer/Content.imageset/Icon-blue-1280x768.png b/AlternateAppIcons/tvOS/Assets.xcassets/App Icon & Top Shelf Image.brandassets/AppIcons-AppStore.imagestack/Middle.imagestacklayer/Content.imageset/Icon-blue-1280x768.png
new file mode 100644
index 0000000..459f3f2
Binary files /dev/null and b/AlternateAppIcons/tvOS/Assets.xcassets/App Icon & Top Shelf Image.brandassets/AppIcons-AppStore.imagestack/Middle.imagestacklayer/Content.imageset/Icon-blue-1280x768.png differ
diff --git a/AlternateAppIcons/tvOS/Assets.xcassets/App Icon & Top Shelf Image.brandassets/AppIcons-AppStore.imagestack/Middle.imagestacklayer/Contents.json b/AlternateAppIcons/tvOS/Assets.xcassets/App Icon & Top Shelf Image.brandassets/AppIcons-AppStore.imagestack/Middle.imagestacklayer/Contents.json
new file mode 100644
index 0000000..73c0059
--- /dev/null
+++ b/AlternateAppIcons/tvOS/Assets.xcassets/App Icon & Top Shelf Image.brandassets/AppIcons-AppStore.imagestack/Middle.imagestacklayer/Contents.json
@@ -0,0 +1,6 @@
+{
+ "info" : {
+ "author" : "xcode",
+ "version" : 1
+ }
+}
diff --git a/AlternateAppIcons/tvOS/Assets.xcassets/App Icon & Top Shelf Image.brandassets/AppIcons.imagestack/Back.imagestacklayer/Content.imageset/Contents.json b/AlternateAppIcons/tvOS/Assets.xcassets/App Icon & Top Shelf Image.brandassets/AppIcons.imagestack/Back.imagestacklayer/Content.imageset/Contents.json
new file mode 100644
index 0000000..932915c
--- /dev/null
+++ b/AlternateAppIcons/tvOS/Assets.xcassets/App Icon & Top Shelf Image.brandassets/AppIcons.imagestack/Back.imagestacklayer/Content.imageset/Contents.json
@@ -0,0 +1,18 @@
+{
+ "images" : [
+ {
+ "filename" : "Icon-blue-400x240.png",
+ "idiom" : "tv",
+ "scale" : "1x"
+ },
+ {
+ "filename" : "Icon-blue-400x240.png",
+ "idiom" : "tv",
+ "scale" : "2x"
+ }
+ ],
+ "info" : {
+ "author" : "xcode",
+ "version" : 1
+ }
+}
diff --git a/AlternateAppIcons/tvOS/Assets.xcassets/App Icon & Top Shelf Image.brandassets/AppIcons.imagestack/Back.imagestacklayer/Content.imageset/Icon-blue-400x240.png b/AlternateAppIcons/tvOS/Assets.xcassets/App Icon & Top Shelf Image.brandassets/AppIcons.imagestack/Back.imagestacklayer/Content.imageset/Icon-blue-400x240.png
new file mode 100644
index 0000000..c13d206
Binary files /dev/null and b/AlternateAppIcons/tvOS/Assets.xcassets/App Icon & Top Shelf Image.brandassets/AppIcons.imagestack/Back.imagestacklayer/Content.imageset/Icon-blue-400x240.png differ
diff --git a/AlternateAppIcons/tvOS/Assets.xcassets/App Icon & Top Shelf Image.brandassets/AppIcons.imagestack/Back.imagestacklayer/Contents.json b/AlternateAppIcons/tvOS/Assets.xcassets/App Icon & Top Shelf Image.brandassets/AppIcons.imagestack/Back.imagestacklayer/Contents.json
new file mode 100644
index 0000000..73c0059
--- /dev/null
+++ b/AlternateAppIcons/tvOS/Assets.xcassets/App Icon & Top Shelf Image.brandassets/AppIcons.imagestack/Back.imagestacklayer/Contents.json
@@ -0,0 +1,6 @@
+{
+ "info" : {
+ "author" : "xcode",
+ "version" : 1
+ }
+}
diff --git a/AlternateAppIcons/tvOS/Assets.xcassets/App Icon & Top Shelf Image.brandassets/AppIcons.imagestack/Contents.json b/AlternateAppIcons/tvOS/Assets.xcassets/App Icon & Top Shelf Image.brandassets/AppIcons.imagestack/Contents.json
new file mode 100644
index 0000000..de59d88
--- /dev/null
+++ b/AlternateAppIcons/tvOS/Assets.xcassets/App Icon & Top Shelf Image.brandassets/AppIcons.imagestack/Contents.json
@@ -0,0 +1,17 @@
+{
+ "info" : {
+ "author" : "xcode",
+ "version" : 1
+ },
+ "layers" : [
+ {
+ "filename" : "Front.imagestacklayer"
+ },
+ {
+ "filename" : "Middle.imagestacklayer"
+ },
+ {
+ "filename" : "Back.imagestacklayer"
+ }
+ ]
+}
diff --git a/AlternateAppIcons/tvOS/Assets.xcassets/App Icon & Top Shelf Image.brandassets/AppIcons.imagestack/Front.imagestacklayer/Content.imageset/Contents.json b/AlternateAppIcons/tvOS/Assets.xcassets/App Icon & Top Shelf Image.brandassets/AppIcons.imagestack/Front.imagestacklayer/Content.imageset/Contents.json
new file mode 100644
index 0000000..932915c
--- /dev/null
+++ b/AlternateAppIcons/tvOS/Assets.xcassets/App Icon & Top Shelf Image.brandassets/AppIcons.imagestack/Front.imagestacklayer/Content.imageset/Contents.json
@@ -0,0 +1,18 @@
+{
+ "images" : [
+ {
+ "filename" : "Icon-blue-400x240.png",
+ "idiom" : "tv",
+ "scale" : "1x"
+ },
+ {
+ "filename" : "Icon-blue-400x240.png",
+ "idiom" : "tv",
+ "scale" : "2x"
+ }
+ ],
+ "info" : {
+ "author" : "xcode",
+ "version" : 1
+ }
+}
diff --git a/AlternateAppIcons/tvOS/Assets.xcassets/App Icon & Top Shelf Image.brandassets/AppIcons.imagestack/Front.imagestacklayer/Content.imageset/Icon-blue-400x240.png b/AlternateAppIcons/tvOS/Assets.xcassets/App Icon & Top Shelf Image.brandassets/AppIcons.imagestack/Front.imagestacklayer/Content.imageset/Icon-blue-400x240.png
new file mode 100644
index 0000000..c13d206
Binary files /dev/null and b/AlternateAppIcons/tvOS/Assets.xcassets/App Icon & Top Shelf Image.brandassets/AppIcons.imagestack/Front.imagestacklayer/Content.imageset/Icon-blue-400x240.png differ
diff --git a/AlternateAppIcons/tvOS/Assets.xcassets/App Icon & Top Shelf Image.brandassets/AppIcons.imagestack/Front.imagestacklayer/Contents.json b/AlternateAppIcons/tvOS/Assets.xcassets/App Icon & Top Shelf Image.brandassets/AppIcons.imagestack/Front.imagestacklayer/Contents.json
new file mode 100644
index 0000000..73c0059
--- /dev/null
+++ b/AlternateAppIcons/tvOS/Assets.xcassets/App Icon & Top Shelf Image.brandassets/AppIcons.imagestack/Front.imagestacklayer/Contents.json
@@ -0,0 +1,6 @@
+{
+ "info" : {
+ "author" : "xcode",
+ "version" : 1
+ }
+}
diff --git a/AlternateAppIcons/tvOS/Assets.xcassets/App Icon & Top Shelf Image.brandassets/AppIcons.imagestack/Middle.imagestacklayer/Content.imageset/Contents.json b/AlternateAppIcons/tvOS/Assets.xcassets/App Icon & Top Shelf Image.brandassets/AppIcons.imagestack/Middle.imagestacklayer/Content.imageset/Contents.json
new file mode 100644
index 0000000..932915c
--- /dev/null
+++ b/AlternateAppIcons/tvOS/Assets.xcassets/App Icon & Top Shelf Image.brandassets/AppIcons.imagestack/Middle.imagestacklayer/Content.imageset/Contents.json
@@ -0,0 +1,18 @@
+{
+ "images" : [
+ {
+ "filename" : "Icon-blue-400x240.png",
+ "idiom" : "tv",
+ "scale" : "1x"
+ },
+ {
+ "filename" : "Icon-blue-400x240.png",
+ "idiom" : "tv",
+ "scale" : "2x"
+ }
+ ],
+ "info" : {
+ "author" : "xcode",
+ "version" : 1
+ }
+}
diff --git a/AlternateAppIcons/tvOS/Assets.xcassets/App Icon & Top Shelf Image.brandassets/AppIcons.imagestack/Middle.imagestacklayer/Content.imageset/Icon-blue-400x240.png b/AlternateAppIcons/tvOS/Assets.xcassets/App Icon & Top Shelf Image.brandassets/AppIcons.imagestack/Middle.imagestacklayer/Content.imageset/Icon-blue-400x240.png
new file mode 100644
index 0000000..c13d206
Binary files /dev/null and b/AlternateAppIcons/tvOS/Assets.xcassets/App Icon & Top Shelf Image.brandassets/AppIcons.imagestack/Middle.imagestacklayer/Content.imageset/Icon-blue-400x240.png differ
diff --git a/AlternateAppIcons/tvOS/Assets.xcassets/App Icon & Top Shelf Image.brandassets/AppIcons.imagestack/Middle.imagestacklayer/Contents.json b/AlternateAppIcons/tvOS/Assets.xcassets/App Icon & Top Shelf Image.brandassets/AppIcons.imagestack/Middle.imagestacklayer/Contents.json
new file mode 100644
index 0000000..73c0059
--- /dev/null
+++ b/AlternateAppIcons/tvOS/Assets.xcassets/App Icon & Top Shelf Image.brandassets/AppIcons.imagestack/Middle.imagestacklayer/Contents.json
@@ -0,0 +1,6 @@
+{
+ "info" : {
+ "author" : "xcode",
+ "version" : 1
+ }
+}
diff --git a/AlternateAppIcons/tvOS/Assets.xcassets/App Icon & Top Shelf Image.brandassets/Contents.json b/AlternateAppIcons/tvOS/Assets.xcassets/App Icon & Top Shelf Image.brandassets/Contents.json
new file mode 100644
index 0000000..2d6ae25
--- /dev/null
+++ b/AlternateAppIcons/tvOS/Assets.xcassets/App Icon & Top Shelf Image.brandassets/Contents.json
@@ -0,0 +1,32 @@
+{
+ "assets" : [
+ {
+ "size" : "1280x768",
+ "idiom" : "tv",
+ "filename" : "AppIcons-AppStore.imagestack",
+ "role" : "primary-app-icon"
+ },
+ {
+ "size" : "400x240",
+ "idiom" : "tv",
+ "filename" : "AppIcons.imagestack",
+ "role" : "primary-app-icon"
+ },
+ {
+ "size" : "2320x720",
+ "idiom" : "tv",
+ "filename" : "Top Shelf Image Wide.imageset",
+ "role" : "top-shelf-image-wide"
+ },
+ {
+ "size" : "1920x720",
+ "idiom" : "tv",
+ "filename" : "Top Shelf Image.imageset",
+ "role" : "top-shelf-image"
+ }
+ ],
+ "info" : {
+ "version" : 1,
+ "author" : "xcode"
+ }
+}
\ No newline at end of file
diff --git a/AlternateAppIcons/tvOS/Assets.xcassets/App Icon & Top Shelf Image.brandassets/Top Shelf Image Wide.imageset/Contents.json b/AlternateAppIcons/tvOS/Assets.xcassets/App Icon & Top Shelf Image.brandassets/Top Shelf Image Wide.imageset/Contents.json
new file mode 100644
index 0000000..3767d60
--- /dev/null
+++ b/AlternateAppIcons/tvOS/Assets.xcassets/App Icon & Top Shelf Image.brandassets/Top Shelf Image Wide.imageset/Contents.json
@@ -0,0 +1,54 @@
+{
+ "images": [
+ {
+ "idiom": "universal"
+ },
+ {
+ "scale": "1x",
+ "idiom": "universal"
+ },
+ {
+ "scale": "2x",
+ "idiom": "universal"
+ },
+ {
+ "scale": "3x",
+ "idiom": "universal"
+ },
+ {
+ "idiom": "iphone"
+ },
+ {
+ "scale": "1x",
+ "idiom": "iphone"
+ },
+ {
+ "scale": "2x",
+ "idiom": "iphone"
+ },
+ {
+ "subtype": "retina4",
+ "scale": "2x",
+ "idiom": "iphone"
+ },
+ {
+ "scale": "3x",
+ "idiom": "iphone"
+ },
+ {
+ "idiom": "ipad"
+ },
+ {
+ "scale": "1x",
+ "idiom": "ipad"
+ },
+ {
+ "scale": "2x",
+ "idiom": "ipad"
+ }
+ ],
+ "info": {
+ "version": 1,
+ "author": "xcode"
+ }
+}
\ No newline at end of file
diff --git a/AlternateAppIcons/tvOS/Assets.xcassets/App Icon & Top Shelf Image.brandassets/Top Shelf Image.imageset/Contents.json b/AlternateAppIcons/tvOS/Assets.xcassets/App Icon & Top Shelf Image.brandassets/Top Shelf Image.imageset/Contents.json
new file mode 100644
index 0000000..3767d60
--- /dev/null
+++ b/AlternateAppIcons/tvOS/Assets.xcassets/App Icon & Top Shelf Image.brandassets/Top Shelf Image.imageset/Contents.json
@@ -0,0 +1,54 @@
+{
+ "images": [
+ {
+ "idiom": "universal"
+ },
+ {
+ "scale": "1x",
+ "idiom": "universal"
+ },
+ {
+ "scale": "2x",
+ "idiom": "universal"
+ },
+ {
+ "scale": "3x",
+ "idiom": "universal"
+ },
+ {
+ "idiom": "iphone"
+ },
+ {
+ "scale": "1x",
+ "idiom": "iphone"
+ },
+ {
+ "scale": "2x",
+ "idiom": "iphone"
+ },
+ {
+ "subtype": "retina4",
+ "scale": "2x",
+ "idiom": "iphone"
+ },
+ {
+ "scale": "3x",
+ "idiom": "iphone"
+ },
+ {
+ "idiom": "ipad"
+ },
+ {
+ "scale": "1x",
+ "idiom": "ipad"
+ },
+ {
+ "scale": "2x",
+ "idiom": "ipad"
+ }
+ ],
+ "info": {
+ "version": 1,
+ "author": "xcode"
+ }
+}
\ No newline at end of file
diff --git a/AlternateAppIcons/tvOS/Assets.xcassets/Contents.json b/AlternateAppIcons/tvOS/Assets.xcassets/Contents.json
new file mode 100644
index 0000000..4caf392
--- /dev/null
+++ b/AlternateAppIcons/tvOS/Assets.xcassets/Contents.json
@@ -0,0 +1,6 @@
+{
+ "info" : {
+ "version" : 1,
+ "author" : "xcode"
+ }
+}
\ No newline at end of file
diff --git a/AlternateAppIcons/tvOS/Entitlements.plist b/AlternateAppIcons/tvOS/Entitlements.plist
new file mode 100644
index 0000000..9ae5993
--- /dev/null
+++ b/AlternateAppIcons/tvOS/Entitlements.plist
@@ -0,0 +1,6 @@
+
+
+
+
+
+
diff --git a/AlternateAppIcons/tvOS/Info.plist b/AlternateAppIcons/tvOS/Info.plist
new file mode 100644
index 0000000..6ddbb7f
--- /dev/null
+++ b/AlternateAppIcons/tvOS/Info.plist
@@ -0,0 +1,24 @@
+
+
+
+
+ CFBundleDisplayName
+ AlternateAppIcons
+ CFBundleIdentifier
+ com.companyname.AlternateAppIcons
+ CFBundleShortVersionString
+ 1.0
+ CFBundleVersion
+ 1.0
+ UIDeviceFamily
+
+ 3
+
+ UIMainStoryboardFile
+ Main
+ UIRequiredDeviceCapabilities
+
+ arm64
+
+
+
diff --git a/AlternateAppIcons/tvOS/Main.cs b/AlternateAppIcons/tvOS/Main.cs
new file mode 100644
index 0000000..f39ee13
--- /dev/null
+++ b/AlternateAppIcons/tvOS/Main.cs
@@ -0,0 +1,6 @@
+using AlternateAppIcons;
+
+// This is the main entry point of the application.
+// If you want to use a different Application Delegate class from "AppDelegate"
+// you can specify it here.
+UIApplication.Main (args, null, typeof (AppDelegate));
diff --git a/AlternateAppIcons/tvOS/Main.storyboard b/AlternateAppIcons/tvOS/Main.storyboard
new file mode 100644
index 0000000..9a62956
--- /dev/null
+++ b/AlternateAppIcons/tvOS/Main.storyboard
@@ -0,0 +1,25 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/AlternateAppIcons/tvOS/README.md b/AlternateAppIcons/tvOS/README.md
new file mode 100644
index 0000000..051bcb0
--- /dev/null
+++ b/AlternateAppIcons/tvOS/README.md
@@ -0,0 +1,16 @@
+---
+name: Alternate App Icon in tvOS
+description: "Demonstrates how to change the app icon dynamically in a .NET for tvOS app"
+page_type: sample
+languages:
+- csharp
+products:
+- dotnet-macios
+urlFragment: alternateappicons-tvos
+---
+
+# Alternate App Icon in tvOS
+
+Alternate App Icon is a sample app that accompanies the article [Alternate App Icons in .NET for iOS and tvOS](#todo-link).
+
+It demonstrates how to change the app icon at runtime.
diff --git a/AlternateAppIcons/tvOS/ViewController.cs b/AlternateAppIcons/tvOS/ViewController.cs
new file mode 100644
index 0000000..7efd991
--- /dev/null
+++ b/AlternateAppIcons/tvOS/ViewController.cs
@@ -0,0 +1,11 @@
+using ObjCRuntime;
+
+namespace AlternateAppIcons;
+
+public partial class ViewController : UIViewController {
+ protected ViewController (NativeHandle handle) : base (handle)
+ {
+ // This constructor is required if the view controller is loaded from a xib or a storyboard.
+ // Do not put any initialization here, use ViewDidLoad instead.
+ }
+}
diff --git a/AlternateAppIcons/tvOS/ViewController.designer.cs b/AlternateAppIcons/tvOS/ViewController.designer.cs
new file mode 100644
index 0000000..32e9cbe
--- /dev/null
+++ b/AlternateAppIcons/tvOS/ViewController.designer.cs
@@ -0,0 +1,14 @@
+//
+// This file has been generated automatically by Visual Studio to store outlets and
+// actions made in the Xcode designer. If it is removed, they will be lost.
+// Manual changes to this file may not be handled correctly.
+//
+
+namespace AlternateAppIcons;
+
+[Register ("ViewController")]
+partial class ViewController {
+ void ReleaseDesignerOutlets ()
+ {
+ }
+}
diff --git a/AlternateAppIcons/tvOS/screenshot.png b/AlternateAppIcons/tvOS/screenshot.png
new file mode 100644
index 0000000..0d2c494
Binary files /dev/null and b/AlternateAppIcons/tvOS/screenshot.png differ