Is this possible to apply the alternative icon to the iOS application? - ios

I need to change the app icon based on region, is this possible?

Yes, this is possible since iOS 10.3.
First, you need to define all alternative icons in your Info.plist file, you can't fetch them dynamically.
In the example below we define 2 alternative icons: "de" and "fr":
<key>CFBundleIcons</key>
<dict>
<key>CFBundleAlternateIcons</key>
<dict>
<key>de</key>
<dict>
<key>CFBundleIconFiles</key>
<array>
<string>ic_de</string>
</array>
<key>UIPrerenderedIcon</key>
<false/>
</dict>
<key>fr</key>
<dict>
<key>CFBundleIconFiles</key>
<array>
<string>ic_fr</string>
</array>
<key>UIPrerenderedIcon</key>
<false/>
</dict>
</dict>
<key>CFBundlePrimaryIcon</key>
<dict>
<key>CFBundleIconFiles</key>
<array>
<string>ic_none</string>
</array>
</dict>
</dict>
Then you can set the icon name based on anything you like (game progress, weather conditions, premium user, etc.). To change the icon use:
UIApplication.shared.setAlternateIconName("de") { (error) in
if let error = error {
print("err: \(error)")
// icon probably wasn't defined in plist file, handle the error
}
}
Result:
The gif is from a Medium article by Julien Quéré.

This feature available in 10.3 (Beta)
Discussion
Use this method to change your app's icon to its primary icon or to one of its alternate icons. You can change the icon only if the value of the supportsAlternateIcons property is true.
You must declare your app's primary and alternate icons using the CFBundleIcons key of your app's Info.plist file. For information about how to configure alternate icons for your app, see the description of the CFBundleIcons key in Information Property List Key Reference.
Take a look at:
apple documentation

Related

How the app icon is added inside my iOS app?

When I look my Info.plist their is nothing about icon in it, but after I deployed the app, I look in it for the the Info.plist and I can see that it's contain :
<key>CFBundleIcons</key>
<dict>
<key>CFBundlePrimaryIcon</key>
<dict>
<key>CFBundleIconFiles</key>
<array>
<string>AppIcon60x60</string>
</array>
<key>CFBundleIconName</key>
<string>AppIcon</string>
</dict>
</dict>
<key>CFBundleIcons~ipad</key>
<dict>
<key>CFBundlePrimaryIcon</key>
<dict>
<key>CFBundleIconFiles</key>
<array>
<string>AppIcon60x60</string>
<string>AppIcon76x76</string>
</array>
<key>CFBundleIconName</key>
<string>AppIcon</string>
</dict>
</dict>
I can see that also the root folder of my app contain 2 files :
AppIcon60x60#2x.png
AppIcon76x76#2x~ipad.png
but nothing in my project, in deployment option, is speaking about those 2 icons. so where they are coming from ? what process add the CFBundleIconFiles key value to the info.plist ?
I want to specify myself the icon (and not from the ide of delphi, I want to update myself the info.plist, and i want to deploy myself the icon), how can I do ?
I only have a partial answer but hopefully will point you in the right direction.
The default info.plist.TemplateiOS.xml contains:
<%VersionInfoPListKeys%>
<%ExtraInfoPListKeys%>
<%StoryboardInfoPListKey%>
Each of these is expanded with information from your project settings. By deleting the corresponding key, you can replace it with your own settings. It might take some trial and error to determine which one inserts the icons.

Flutter - Can not change app icon programmatically using CFBundleAlternateIcons

I've been trying to change my app icon using CFBundleAlternateIcons, but nothing happens.
I'm actually using a plugin for the Flutter SDK - flutter_dynamic_icon, when I change the icon using the plugin, it show a popup says 'You have changed the icon for MyApp' but nothing changes.
My question seems to be a repeat of this question: [https://stackoverflow.com/questions/64426880/xcode-ios-cfbundlealternateicons-not-changing] which already has an answer but it doesn't work for me.
I'm also trying to do the same as this article on medium: [https://medium.com/flutter-community/programatically-change-ios-app-icon-in-flutter-c9e84bc541a2] and the result is the same as when I used flutter_dynamic_icon.
Here is my info.plist:
<key>CFBundleIcons</key>
<dict>
<key>CFBundleAlternateIcons</key>
<dict>
<key>teamfortress</key>
<dict>
<key>UIPrerenderedIcon</key>
<false/>
<key>CFBundleIconFiles</key>
<array>
<string>teamfortress</string>
</array>
</dict>
<key>chills</key>
<dict>
<key>UIPrerenderedIcon</key>
<false/>
<key>CFBundleIconFiles</key>
<array>
<string>chills</string>
</array>
</dict>
<key>photos</key>
<dict>
<key>CFBundleIconFiles</key>
<array>
<string>photos</string>
</array>
</dict>
<key>UIPrerenderedIcon</key>
<false/>
</dict>
</dict>
I think something is wrong with my info.plist.
Has anyone experienced this problem?. Please help me, thanks a lot.
I've figured out the answer recently, for some reasons, my app can only be able to change app icon dynamically when I add icon images directly in Runner folder in Xcode and run flutter project from it.
Hope it's helpful for you if you're encountering with above problem.

How can an app’s icon change dynamically in iOS 10.3, like iOS's clock app? [duplicate]

I need to change the app icon based on region, is this possible?
Yes, this is possible since iOS 10.3.
First, you need to define all alternative icons in your Info.plist file, you can't fetch them dynamically.
In the example below we define 2 alternative icons: "de" and "fr":
<key>CFBundleIcons</key>
<dict>
<key>CFBundleAlternateIcons</key>
<dict>
<key>de</key>
<dict>
<key>CFBundleIconFiles</key>
<array>
<string>ic_de</string>
</array>
<key>UIPrerenderedIcon</key>
<false/>
</dict>
<key>fr</key>
<dict>
<key>CFBundleIconFiles</key>
<array>
<string>ic_fr</string>
</array>
<key>UIPrerenderedIcon</key>
<false/>
</dict>
</dict>
<key>CFBundlePrimaryIcon</key>
<dict>
<key>CFBundleIconFiles</key>
<array>
<string>ic_none</string>
</array>
</dict>
</dict>
Then you can set the icon name based on anything you like (game progress, weather conditions, premium user, etc.). To change the icon use:
UIApplication.shared.setAlternateIconName("de") { (error) in
if let error = error {
print("err: \(error)")
// icon probably wasn't defined in plist file, handle the error
}
}
Result:
The gif is from a Medium article by Julien Quéré.
This feature available in 10.3 (Beta)
Discussion
Use this method to change your app's icon to its primary icon or to one of its alternate icons. You can change the icon only if the value of the supportsAlternateIcons property is true.
You must declare your app's primary and alternate icons using the CFBundleIcons key of your app's Info.plist file. For information about how to configure alternate icons for your app, see the description of the CFBundleIcons key in Information Property List Key Reference.
Take a look at:
apple documentation

Facebook SDK: app not registered as a URL Scheme

I am using the Facebook SDK found here, and am trying the sample that is provided (in the folder FacebookiOSSample).
If I simply replace the AppId here with my specific AppId, then I can no longer Share. (I replaced it in both the AppDelegate file and the info.plist file). I now receive the following error:
FBSDKLog: Invalid use of FBAppCall, fb**** is not registered as a URL
Scheme. Did you set 'FacebookUrlSchemeSuffix' in your plist?
Otherwise this works fine with the sample's original AppId which points to something named IFaceTouch.
What could be wrong with the setup of my app, how do I register my AppId?
Follow these three steps:
Create a key called FacebookAppID with a string value, and add the app ID there.
Create a key called FacebookDisplayName with a string value, and add the Display Name you configured in the App Dashboard.
Create an array key called URL types with a single array sub-item called URL Schemes. Give this a single item with your app ID prefixed with fb. This is used to ensure the application will receive the callback URL of the web-based OAuth flow.
The finished .plist should look something like this:
Source Link:
In terms of raw keys and values you should have CFBundleURLTypes and CFBundleURLSchemes. Hope that helps!
there is another section below the info - URL Types
check that the values there, under the URL Schemes field match the value in the URL types -> URL Schemes in the property list above.
(and also match the FacebookAppID)
For iOS 9
If you have an error: 'LSApplicationQueriesSchemes'
Based on Bear with me answer, you will also have to add those lines:
<key>LSApplicationQueriesSchemes</key>
<array>
<string>fbauth2</string>
</array>
See this.
You should end up with those lines at the end of your .plist files:
<key>CFBundleURLTypes</key>
<array>
<dict>
<key>CFBundleURLSchemes</key>
<array>
<string>fb2R3234544534554</string>
</array>
</dict>
</array>
<key>FacebookAppID</key>
<string>2R3234544534554</string>
<key>FacebookDisplayName</key>
<string>stevejeff</string>
<key>NSAppTransportSecurity</key>
<dict>
<key>NSExceptionDomains</key>
<dict>
<key>facebook.com</key>
<dict>
<key>NSIncludesSubdomains</key>
<true/>
<key>NSThirdPartyExceptionRequiresForwardSecrecy</key>
<false/>
</dict>
<key>fbcdn.net</key>
<dict>
<key>NSIncludesSubdomains</key>
<true/>
<key>NSThirdPartyExceptionRequiresForwardSecrecy</key>
<false/>
</dict>
<key>akamaihd.net</key>
<dict>
<key>NSIncludesSubdomains</key>
<true/>
<key>NSThirdPartyExceptionRequiresForwardSecrecy</key>
<false/>
</dict>
</dict>
</dict>
<key>LSApplicationQueriesSchemes</key>
<array>
<string>fbauth2</string>
</array>
</dict>
</plist>
* If you're using v4.6.0 or higher of the SDK, you only need to add:* (Thanks mohsinj)
<key>LSApplicationQueriesSchemes</key>
<array>
<string>fbapi</string>
<string>fb-messenger-api</string>
<string>fbauth2</string>
<string>fbshareextension</string>
</array>
1- In Xcode, right-click your project's Info.plist file and select Open As -> Source Code.
2- Insert the following XML snippet into the body of your file just before the final </dict> element.
<key>CFBundleURLTypes</key>
<array>
<dict>
<key>CFBundleURLSchemes</key>
<array>
<string>fb{your-app-id}</string>
</array>
</dict>
</array>
<key>FacebookAppID</key>
<string>{your-app-id}</string>
<key>FacebookDisplayName</key>
<string>{your-app-name}</string>
<key>LSApplicationQueriesSchemes</key>
<array>
<string>fbapi</string>
<string>fb-messenger-share-api</string>
<string>fbauth2</string>
<string>fbshareextension</string>
</array>
3- Replace {your-app-id}, and {your-app-name} with your app's App's ID and name found on the Facebook App Dashboard.
Go to this Link Select Your App, And configure your info.plist
Had this issue but was because i missed the prefix fb with the app id for the url scheme section.
If you are using multiple social auth the place URL schema is like as below.
<key>CFBundleURLTypes</key>
<array>
<dict>
<key>CFBundleURLSchemes</key>
<array>
<string>fb7876940600009</string>
<string>com.googleusercontent.apps.76235222224-hfvusdel7p8eavfvn</string>
</array>
</dict>
</array>
<key>FacebookAppID</key>
<string>7876983017</string>
<key>FacebookClientToken</key>
<string>e29fbf1f15a5b5be028dcb</string>
<key>FacebookDisplayName</key>
<string>xdfxdffmate</string>
Today i solved this bug by just removing space from FacebookDisplayName.
make sure you don't have any space in FacebookDisplayName
I don't know if your problem is the same as mine. But it took me some time to find it and i will put it here so that it can help anyone.. The problem was that google sign in used the same info.plist attribute name and it was overriding the ones of facebook.. So i could see this in X-Code and put them together, now everything works fine! (URL Types attribute).
In my case i already had LSApplicationQueriesSchemes and CFBundleURLTypes keys in my info.plist, When I again added them separately in info.plist. it didn't read the second one and doesn't recognize. So add values into the previous LSApplicationQueriesSchemes and CFBundleURLTypes keys solved my issue.
if you used login with google and implemented already put both in same url schema
<key>CFBundleURLTypes</key>
<array>
<dict>
<key>CFBundleTypeRole</key>
<string>Editor</string>
<key>CFBundleURLSchemes</key>
<array>
<string>https</string>
<string>fbXXXXXXXXXXXXXX</string> //facebook app id
<string>com.googleusercontent.apps.XXXXXXXXX-XXXXXXXXXXXXXXX</string> // Google Url Schemal
</array>
</dict>
</array>

Creating a custom template in Xcode - how can I make a required option based on a checkbox?

I am trying to create a custom template in Xcode. In my TemplateInfo.plist, for key Options, I have the code pasted below. This template will be for a class that more often than not (but not always) will use delegation when events occur.
The issue I am having is with the value at the very bottom, RequiredOptions. I want the text box to be enabled only if the withProtocol checkbox is checked. However, I can't figure out what value and type of value to use. I have tried the following:
<true/> (as below) - The text box is always enabled.
<string>YES</string> - The text box is always disabled.
<integer>1</integer> - The text box is always enabled.
Does anyone have any ideas for what else I could try? Better yet, does anyone know of a decent reference for Xcode templates?
I have already read through Apple's plist manual pages and the article at this website.
<array>
<dict>
<key>Description</key>
<string>The name of the class to create</string>
<key>Identifier</key>
<string>productName</string>
<key>Name</key>
<string>Class</string>
<key>NotPersisted</key>
<true/>
<key>Required</key>
<true/>
<key>Type</key>
<string>text</string>
</dict>
<dict>
<key>Default</key>
<string>false</string>
<key>Identifier</key>
<string>withXIB</string>
<key>Name</key>
<string>With XIB for user interface</string>
<key>Type</key>
<string>checkbox</string>
</dict>
<dict>
<key>Description</key>
<string>Choose whether or not a delegate skeleton is included.</string>
<key>Default</key>
<string>false</string>
<key>Identifier</key>
<string>withProtocol</string>
<key>Name</key>
<string>With delegate skeleton</string>
<key>Type</key>
<string>checkbox</string>
</dict>
<dict>
<key>Description</key>
<string>The name of the protocol used for delegation.</string>
<key>Identifier</key>
<string>protocolName</string>
<key>Name</key>
<string>Protocol</string>
<key>NotPersisted</key>
<true/>
<key>Required</key>
<true/>
<key>Type</key>
<string>text</string>
<key>RequiredOptions</key>
<dict>
<key>withProtocol</key>
<true/>
</dict>
</dict>
</array>
I fixed my own problem by replacing <true/> with <string>true</string>.
Correct way of adding a required option based on a checkbox
The key of the RequiredOptions dictionary must be the identifier of the other option, and the value of the dictionary must be the array of subset of values from the option that allow the current option to be enabled.
<key>RequiredOptions</key>
<dict>
<key>withXIB</key>
<array>
<string>true</string>
</array>
</dict>
In your case, true gets the job done.
Tested on Xcode 12 ✅

Resources