I am trying to set an alternate app icon named MyIcon in my iOS app. I have a MyIcon.png image in my project bundle (not in my Assets folder) and it is declared in my Info.plist like so:
<key>CFBundleIcons</key>
<dict>
<key>CFBundleAlternateIcons</key>
<dict>
<key>MyIcon</key>
<dict>
<key>CFBundleIconFiles</key>
<array>
<string>MyIcon</string>
</array>
<key>UIPrerenderedIcon</key>
<false/>
</dict>
</dict>
</dict>
In my code, I try to change the app icon:
UIApplication.shared.setAlternateIconName("MyIcon")
However, the icon doesn't change and I am instead given this error in the console:
Error Domain=NSCocoaErrorDomain Code=3072 "The operation was cancelled."
How can I fix this issue?
I was getting this error because of two reasons,
First(and highly not because of), I didn't do "Add Files to 'ProjectNameFoo'" by adding png file to project. Otherwise it didn't work. After that it started to see icon.
Secondly(and highly possible reason), I was getting this error because I was trying to change the icon in viewDidLoad. When I try with a delay like the code below it was working whatever second I gave.
override func viewDidLoad() {
super.viewDidLoad()
DispatchQueue.main.asyncAfter(deadline: .now() + 1) {
UIApplication.shared.setAlternateIconName("MyIcon")
}
}
I was stuck with this error for quite a while and tried all sorts of things but couldn't work out what I was doing wrong. I was changing the icon from AppDelegate.application(didFinishLaunchingWithOptions:). Delaying the call with a timer as suggested above did solve it.
It is worth noting that this problem is due to UIKit trying to show a UIAlertController with the message
You have changed the icon for $(PRODUCT_NAME)
and that didn't seem to work at that point. You need to wait until a root view controller is loaded.
This is because this API is not meant to for the developer to update the icon arbitrarily, but for the user to deliverability choose one.
Related
I'm getting this error when trying to run flutter app to IOS devices, this error occurs when launching the application on the device for the first time.
Assuming you don't actually use scenes, this warning can appear for a few reasons. Most common I've noticed is using a LaunchScreen.storyboard sort of thing, they contain scene data. If indeed you don't use scenes. You can get rid of this by being explicit in your Info.plist. Add the following;
<key>UIApplicationSceneManifest</key>
<dict>
<key>UIApplicationSupportsMultipleScenes</key>
<false/>
<key>UISceneConfigurations</key>
<dict/>
</dict>
If you are managing your Info.plist with Targets > Info > Custom iOS Target Properties you would set Application Scene Manifest like the picture
I have two app icons built-in (free and premium), is it possible to replace free icon to premium icon programmatically after in-app purchase is completed successfully?
There is a new solution for this situation.
You can use
setAlternateIconName(_:completionHandler:)
iOS 10.3 is out with xcode 8.3.
10.3+
Update:
Usage is pretty simple, the key is to find out plist usage and note that you can not load assets from xcassets ( at least didnt work for me ). You need to add your icon files to project and prefer 180x180 images for quality.
You need to use "Icon files (iOS 5)", new Icon files does not work.
One last thing, when you change icon on a button click it will popup a Alert window that says 'You have changed the icon for "IcoTest".'
//ViewController.swift
#IBAction func ico1Click(_ sender: Any) {
if UIApplication.shared.supportsAlternateIcons{
UIApplication.shared.setAlternateIconName("Icon2", completionHandler: { (error) in
print(error ?? "")
})
}else{
print("NO NO")
}
}
//Info.plist
<key>CFBundleIcons</key>
<dict>
<key>CFBundleAlternateIcons</key>
<dict>
<key>Icon1</key>
<dict>
<key>CFBundleIconFiles</key>
<array>
<string>alternater1_180x180</string>
</array>
<key>UIPrerenderedIcon</key>
<false/>
</dict>
<key>Icon2</key>
<dict>
<key>CFBundleIconFiles</key>
<array>
<string>alternater2_180x180</string>
</array>
</dict>
</dict>
</dict>
No, the icon is specified in the application bundle, which you must not change. If you change it, your app signature will become invalid (not the same checksum) and thus your app won't run anymore.
No, definitely not. That part of the application bundle is read-only, and also code signed.
The answer regarding the TapOne app is something completely different. It creates "web clips" to web sites or phone numbers. For example, to create an iPhone icon for your website, you would add something like this to your web page header:
<link rel="apple-touch-icon" href="/your-custom-icon.png"/>
There is more info available here: https://developer.apple.com/library/ios/documentation/AppleApplications/Reference/SafariWebContent/ConfiguringWebApplications/ConfiguringWebApplications.html
TapOne and web clips do not programmatically change the icon within an application bundle.
An update: since iOS 10.3 you can update the app icon by having alternate icons defined in the info.plist.
See more at Apple Docs
This is not possible. App icons are not dynamic and they can only be updated by submitting a new updates to your app through iTunes Connect. For more info, read the iTunes Connect Developer Guide. https://itunesconnect.apple.com/docs/iTunesConnect_DeveloperGuide.pdf
I'm afraid not; pretty certain the app icon isn't allowed to conditionally change.
I don't think that's possible without a jailbroken phone. The app icon is contained in the application bundle, which you're not allowed to write to.
I disagree with all the answer above.
Please try the app "OneTap", it will allow you to make your own icon of your new app.
OneTap app is free on Itune.
I was trying to implement this functionallity for the first time, and seemed pretty straight forward, but for some reason is not working for me.
My intention is to open a simple jpeg from the mail app into my application, after that was not working I was just trying to open any kind of document by adding this to the Info.plist.
Same result, my application is not appearing on the list of "Open with..."
<key>CFBundleDocumentTypes</key> <array>
<dict>
<key>CFBundleTypeName</key>
<string>All Docs</string>
<key>CFBundleTypeRole</key>
<string>Viewer</string>
<key>LSHandlerRank</key>
<string>Alternate</string>
<key>LSItemContentTypes</key>
<array>
<string>public.content</string>
</array>
</dict> </array>
I have search already in StackOverFlow and the apple docs, but none of the answers make it work for me, so maybe is something simple that I am missing here...
Why is my iOS app not showing up in other apps' "Open in" dialog?
How do I associate file types with an iPhone application?
How I am testing it (maybe has to do with this):
Have an email with an attachment. Add the settings to the plist and the run the application on my device, hoping that the next time I open the mail app and click on the attachment my app will be on the list.
Well, it seems that is not possible. At least to provide a custom way to open images from the mail app. There is no problem if is from another place, but apple has limited the options on the mail app so we would use the "copy" option as a workaround.
Update:
This question goes in the same direction.
It is now possible to open images from the mail app, it's just somewhat convoluted:
Tap and hold the image.
Tap on Quick Look so the image goes fullscreen.
Tap the image to show the top toolbar.
Tap the open in button at the top right.
Scroll the list to the left to find your app.
I have two app icons built-in (free and premium), is it possible to replace free icon to premium icon programmatically after in-app purchase is completed successfully?
There is a new solution for this situation.
You can use
setAlternateIconName(_:completionHandler:)
iOS 10.3 is out with xcode 8.3.
10.3+
Update:
Usage is pretty simple, the key is to find out plist usage and note that you can not load assets from xcassets ( at least didnt work for me ). You need to add your icon files to project and prefer 180x180 images for quality.
You need to use "Icon files (iOS 5)", new Icon files does not work.
One last thing, when you change icon on a button click it will popup a Alert window that says 'You have changed the icon for "IcoTest".'
//ViewController.swift
#IBAction func ico1Click(_ sender: Any) {
if UIApplication.shared.supportsAlternateIcons{
UIApplication.shared.setAlternateIconName("Icon2", completionHandler: { (error) in
print(error ?? "")
})
}else{
print("NO NO")
}
}
//Info.plist
<key>CFBundleIcons</key>
<dict>
<key>CFBundleAlternateIcons</key>
<dict>
<key>Icon1</key>
<dict>
<key>CFBundleIconFiles</key>
<array>
<string>alternater1_180x180</string>
</array>
<key>UIPrerenderedIcon</key>
<false/>
</dict>
<key>Icon2</key>
<dict>
<key>CFBundleIconFiles</key>
<array>
<string>alternater2_180x180</string>
</array>
</dict>
</dict>
</dict>
No, the icon is specified in the application bundle, which you must not change. If you change it, your app signature will become invalid (not the same checksum) and thus your app won't run anymore.
No, definitely not. That part of the application bundle is read-only, and also code signed.
The answer regarding the TapOne app is something completely different. It creates "web clips" to web sites or phone numbers. For example, to create an iPhone icon for your website, you would add something like this to your web page header:
<link rel="apple-touch-icon" href="/your-custom-icon.png"/>
There is more info available here: https://developer.apple.com/library/ios/documentation/AppleApplications/Reference/SafariWebContent/ConfiguringWebApplications/ConfiguringWebApplications.html
TapOne and web clips do not programmatically change the icon within an application bundle.
An update: since iOS 10.3 you can update the app icon by having alternate icons defined in the info.plist.
See more at Apple Docs
This is not possible. App icons are not dynamic and they can only be updated by submitting a new updates to your app through iTunes Connect. For more info, read the iTunes Connect Developer Guide. https://itunesconnect.apple.com/docs/iTunesConnect_DeveloperGuide.pdf
I'm afraid not; pretty certain the app icon isn't allowed to conditionally change.
I don't think that's possible without a jailbroken phone. The app icon is contained in the application bundle, which you're not allowed to write to.
I disagree with all the answer above.
Please try the app "OneTap", it will allow you to make your own icon of your new app.
OneTap app is free on Itune.
I have a problem with the gloss effect in app icon at iOS 5 beta 5, in iOS 4 it's show the effect not gloss, but iOS5 shows the gloss effect. I put the option Icon already includes gloss effects = YES, but simply does not work, and it appears that the application Google+ also has the same problem
iOS 5 has anew "Icon Files (iOS 5)" key in the Info.plist file. Make sure the "Icon already includes gloss effect" boolean in that dict is set to "YES" too. You may need to clear your build folder before the changes take effect in the simulator. It takes a lot of troubleshooting to get it to work on older projects, so you might try erasing the root level key.
First Settings in a your project info-list set key Icon already inculdes gloss effects to YES Boolean value like below screen shot:
after try project Target settings tick the checkbox in the summary tap in the App Icons section
like below screen shot:
it's worked for me!
Welcome in Advance!
It appears this problem is still not fixed in the GM.
I set UIPrerenderedIcon to YES, but the rendered icon includes gloss effect.
Sorry, I confirmed that this problem is solved in the GM. If you would like to erase gross effect, set "Icon already includes gross effect" under "Primary Icons" under "Icon files (iOS 5)" to YES.
There are 2 keys in the Info.plist governing this.
xCode generated the following code for you, but it doesn't offer a GUI for changing this:
Open your Info.plist file (Right Click > Open As > Source Code).
<key>CFBundleIcons</key>
<dict>
<key>CFBundlePrimaryIcon</key>
<dict>
<key>CFBundleIconFiles</key>
<array>
<string>myIcon.png</string>
</array>
<key>UIPrerenderedIcon</key>
<false/>
</dict>
</dict>
set the UIPrerenderedIcon = true and you are good to go (this is NOT the other UIPrerenderedIcon that also exists in this file as a boolean key!).
Just in case anyone stumbles across this due to a problem using an asset catalog in Xcode 5.0, there is a setting in the Attributes Inspector of the asset catalog that should be checked:
Some of you will do these things and still not have retina display or gloss to reflect these changes.
In XCode 4.3.2 and possibly earlier versions, make sure you check the "Summary" tab in your project settings. There you will find a section called "App Icons" that should show both your Icon.png and Icon#2x.png. Make sure you have the "Prerendered Icon" box checked.
Even after all this, you might not have the retina display working. Check the "Info" tab's "Custom iOS Target Properties" section.
Make sure you delete the "Newstand Icons" section if you aren't going to use them or it will stop your app from passing validation when submitting to the AppStore.
In the release notes for iOS5 Beta 6 it says:
FIXED: The UIPrerenderedIcon key (in the Info.plist file) is not
honored in this beta.
Yes, it's an iOS 5 bug. I'm sure it'll be fixed in the GM.
I had the same problem with an unwanted gloss effect using xCode 5.0. I went through all posted answers. Here is what worked for me:
1) Remove "Icon Already Includes Gloss Effects" from Info.plist. I did this because, although this is set to "YES", which should work properly -- for whatever reason, it wasn't working, so I wanted to remove it before adding the correct code.
Here's how to do it:
Click your project name in the navigator (left column) > then in the Editor (middle column) click info. In the field that states "Icon Includes Gloss Effects", click the minus "-" button to delete. This removes the code that is not working, so you will start with a clean palette.
2) Open your Info.plist file -- In the Navigator (left column), find the info.plist file then (Right Click > Open As > Source Code).
3) Your code will look like this:
<key>CFBundleIcons</key>
<dict>
<key>CFBundlePrimaryIcon</key>
<dict>
<key>CFBundleIconFiles</key>
<array>
<string>Icon-120</string>
<string>Icon-72</string>
<string>Icon-57</string>
</array>
</dict>
Now copy the following 2 lines of code, because you will paste them into the code above:
<key>UIPrerenderedIcon</key>
<true/>
Your final code should look like this:
<dict>
<key>CFBundlePrimaryIcon</key>
<dict>
<key>CFBundleIconFiles</key>
<array>
<string>YourIconFile</string>
</array>
<key>UIPrerenderedIcon</key>
<true/>
</dict>
This is the best answer I can provide. Worked for me.
What worked for me is to change the "Icon already includes gloss effect" boolean under "Icon Files (iOS 5)" first to NO, compile, then set the boolean to YES and compile.
I set “Icon already includes gloss effects = YES”
In the info.plist, search this part:
<key>CFBundleIcons</key>
<dict>
<key>CFBundlePrimaryIcon</key>
<dict>
<key>CFBundleIconFiles</key>
<array>
<string>myIcon.png</string>
</array>
</dict>
</dict>
Now, add this 2 lines:
<key>UIPrerenderedIcon</key>
<false/>
At the end, It must to be:
<key>CFBundleIcons</key>
<dict>
<key>CFBundlePrimaryIcon</key>
<dict>
<key>CFBundleIconFiles</key>
<array>
<string>myIcon.png</string>
</array>
<key>UIPrerenderedIcon</key>
<true/>
</dict>
</dict>