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