Change App icon programmatically - iphone

I have seen this application on iTunes, it is creating custom icon in iphone. In my application I also want to change icon , specifically what I want to do is in my icon there is one label and programmatically I want to change the value of label.

From the video tutorial of the app, it seems like all they're doing is they created a web page with favicon of the custom icon that you created, then the user would tap "Add To Home Screen" to add the custom web page to the home screen. That should be enough to get you going.

It is possible to change appIcon from iOS 10.3.
Swift 3:
if UIApplication.shared.supportsAlternateIcons{
UIApplication.shared.setAlternateIconName("icon2", completionHandler: { (error) in
print(error ?? "")
})
}
Objective C:
[[UIApplication sharedApplication] setAlternateIconName:#"icon2" completionHandler:^(NSError * _Nullable error) {
//NSLog(#"Error...");
}];
set supportsAlternateIcon to Yes in info.plist. Both primary and secondary icons should be added in CFBundleIcons key of your app's Info.plist file.
//Info.plist
<key>CFBundleIcons</key>
<dict>
<key>CFBundleAlternateIcons</key>
<dict>
<key>Icon1</key>
<dict>
<key>CFBundleIconFiles</key>
<array>
<string>icon1</string>
</array>
<key>UIPrerenderedIcon</key>
<false/>
</dict>
<key>Icon2</key>
<dict>
<key>CFBundleIconFiles</key>
<array>
<string>icon2</string>
</array>
</dict>
</dict>
</dict>
References:
Apple Document: setAlternateIconName(_:completionHandler:)
How to change your app icon dynamically with setAlternateIconName()

This is not possible. Unless your app is of Newsstand category. For newsstand app, change the icon using the code,
UIApplication *app = [UIApplication sharedApplication];
[app setNewsstandIconImage:newsstandImage];
Note: What #Enrico suggests is a different solution. Your app icon will still be there in home screen, a duplicate icon will be created. Which most of the users wont prefer.

Only my two cents.
Adding to plist directly is fine, the net effect is to have a "strange" value (IOS5...) in plist if seen visually in Xcode:
2) on simulator (Xcode 10 beta...) debug console on run you will see:
MobileGestalt.c:890: MGIsDeviceOneOfType is not supported on this platform.
but works
3) don't call directly in AppDelegate. if needed so, call it dispatched:
final func changeIcon(){
let name = "Icon1"
let icon = UIImage(named: name)
if UIApplication.shared.supportsAlternateIcons{
UIApplication.shared.setAlternateIconName(name, completionHandler: { (error) in
print(error ?? "ok")
})
}
}
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
// Override point for customization after application launch.
let when = DispatchTime.now() + 1
DispatchQueue.main.asyncAfter(deadline: when) {
self.changeIcon()
}
return true
}
.....
4) note: icon name is the symbolic name you put in key in upper level, so for example:
<key>CFBundleIcons</key>
<dict>
<key>CFBundleAlternateIcons</key>
<dict>
<key>Icon1</key>
<dict>
<key>CFBundleIconFiles</key>
<array>
<string>logo2_120x120</string>
</array>
<key>UIPrerenderedIcon</key>
<false/>
</dict>
<key>Icon2</key>
<dict>
<key>CFBundleIconFiles</key>
<array>
<string>logo3_120x120</string>
</array>
</dict>
</dict>
</dict>
and do NOT add #2x or similar in plist.

Related

AVPlayer won't let me access URL

I am Attempting very simple Xcode OS X program with swift 4.0 - this program builds and runs but I'm getting errors accessing the URL video file. Probably related to privilege or security setting somewhere but can't figure out where. Here is my program under class ViewController: NSViewController:
#IBOutlet var playerView: AVPlayerView!
//var url: URL!
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
// guard let url = URL(string: "https://devimages.apple.com.edgekey.net/samplecode/avfoundationMedia/AVF oundationQueuePlayer_HLS2/master.m3u8")
// else {
// return
// }
let url1 = URL(string: "http://commondatastorage.googleapis.com/gtv-videos-bucket/sample/BigBuckBunny.mp4")
let player = AVPlayer(url: url1!)
// Create a new AVPlayer and associate it with the player view
let playerView = self.playerView
playerView?.player = player
playerView?.player!.play();
}
Also I have modified the info.plist file with the following:
<key>NSAppTransportSecurity</key>
<dict>
<key>NSAllowsArbitraryLoads</key>
<true/>
<key>NSAllowsArbitraryLoadsInWebContent</key>
<true/>
<key>NSExceptionDomains</key>
<dict/>
</dict>
I get the following runtime errors trying to access either of the URLs
above why?
2017-11-05 10:12:21.757333-0800 AVPlayer[54381:5617593] startLogging:
logging starts... 2017-11-05 10:12:21.758024-0800
AVPlayer[54381:5617612] setMessageLoggingBlock: called 2017-11-05
10:12:21.758520-0800 AVPlayer[54381:5617612] initWithSessionInfo: XPC
connection interrupted 2017-11-05 10:12:21.758842-0800
AVPlayer[54381:5617612] startConfigurationWithCompletionHandler:
Failed to get remote object proxy: Error Domain=NSCocoaErrorDomain
Code=4097 "connection to service named com.apple.rtcreportingd"
UserInfo={NSDebugDescription=connection to service named
com.apple.rtcreportingd} 2017-11-05 10:12:21.759003-0800
AVPlayer[54381:5617612] startConfigurationWithCompletionHandler:
Failed to get remote object proxy: Error Domain=NSCocoaErrorDomain
Code=4097 "connection to service named com.apple.rtcreportingd"
UserInfo={NSDebugDescription=connection to service named
com.apple.rtcreportingd} 2017-11-05 10:12:21.925221-0800
AVPlayer[54381:5617654] App Transport Security has blocked a cleartext
HTTP (http://) resource load since it is insecure. Temporary
exceptions can be configured via your app's Info.plist file.
I found your question after you commented on a question I had answered previously, so lets continue here :)
I can get your code working by combining my original answer to that question with the answer provided by #callam above so...give him the credit for the correct answer :)
To summarize, you need to:
Add a AVPlayerView to your Storyboard and connect it to your ViewController
Setup your ViewController
Manage App Transport Security and the outgoing connection.
In greater detail
1. Add a AVPlayerView to your Storyboard and connect it to your ViewController
Drag a AVKit Player View to your view in the storyboard
In your ViewController class, create an outlet for the view:
#IBOutlet weak var playerView: AVPlayerView!
And connect it.
2. Setup your ViewController
Here is my code:
import Cocoa
import AVKit
class ViewController: NSViewController {
#IBOutlet weak var playerView: AVPlayerView!
override func viewDidLoad() {
super.viewDidLoad()
let fileURL = URL(string: "http://commondatastorage.googleapis.com/gtv-videos-bucket/sample/BigBuckBunny.mp4")
let avAsset = AVURLAsset(url: fileURL!, options: nil)
let playerItem = AVPlayerItem(asset: avAsset)
let videoPlayer = AVPlayer(playerItem: playerItem)
playerView.player = videoPlayer
videoPlayer.play()
}
}
Seems familiar no :)
Notice I create the videoPlayer right here, no need to for me to use the let playerView = self.playerView you mention in your comments.
If you just do these two steps, you end up with a player view that cannot play video and errors in your console. So you need to add the final piece to the puzzle, kindly provided by #callam above.
3. Manage App Transport Security and the outgoing connection.
First, if you cannot use a HTTPS connection you must allow HTTP connections in your info.plist file.
Here is my .plist file in its entirety
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>CFBundleDevelopmentRegion</key>
<string>$(DEVELOPMENT_LANGUAGE)</string>
<key>CFBundleExecutable</key>
<string>$(EXECUTABLE_NAME)</string>
<key>CFBundleIconFile</key>
<string></string>
<key>CFBundleIdentifier</key>
<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundleName</key>
<string>$(PRODUCT_NAME)</string>
<key>CFBundlePackageType</key>
<string>APPL</string>
<key>CFBundleShortVersionString</key>
<string>1.0</string>
<key>CFBundleVersion</key>
<string>1</string>
<key>LSMinimumSystemVersion</key>
<string>$(MACOSX_DEPLOYMENT_TARGET)</string>
<key>NSHumanReadableCopyright</key>
<string>Copyright © 2017 :) </string>
<key>NSMainStoryboardFile</key>
<string>Main</string>
<key>NSPrincipalClass</key>
<string>NSApplication</string>
<key>NSAppTransportSecurity</key>
<dict>
<key>NSAllowsArbitraryLoads</key>
<true/>
</dict>
</dict>
</plist>
The important part being the NSAppTransportSecurity part
And then finally, you must enable Outgoing Connections (Client) under Capabilities of your project
If I do that, I end up with this:
But notice though, that I still see errors in the console.
Hope you are able to get to the same result following these steps :)
Even if you enable arbitrary loads, attempts to connect using insecure HTTP fail.
Change the protocol in your URL to https:// or add the domain to NSExceptionDomains.
let url1 = URL(string: "https://commondatastorage.googleapis.com/gtv-videos-bucket/sample/BigBuckBunny.mp4")
https://developer.apple.com/library/content/documentation/General/Reference/InfoPlistKeyReference/Articles/CocoaKeys.html#//apple_ref/doc/uid/TP40009251-SW35
I believe the XPC error can be fixed by selecting Outgoing Connections in your App Capabilities
https://developer.apple.com/library/content/documentation/Miscellaneous/Reference/EntitlementKeyReference/Chapters/EnablingAppSandbox.html

Exclusive iOS UTI

I'm trying to create / export an exclusive UTI type for my iOS app (very similar to how Instagram exclusively handles the UTI com.instagram.exclusivegram).
Basically, I want com.photoapp.photo to be what an app can use if they want to be able to open the photo in any app registered for taking photos (similar to Instagram's com.instagram.photo). Then I want com.photoapp.exclusive to only be able to open in my app (similar to com.instagram.exclusivegram).
What I'm running into on my device is that even when using com.photoapp.exclusive, the UIDocumentController prompts me to open it in either PhotoApp or DropBox where it should just be PhotoApp.
I have my app that registers the UTI as well as an example app I'm using to check on the opening ability. The code I'm using in the example app is below:
if ([[UIApplication sharedApplication] canOpenURL:[NSURL URLWithString:#"photoapp://"]]) {
NSData *imageData = UIImageJPEGRepresentation([UIImage imageNamed:#"derp.png"], 1.0);
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *fullPathToFile = [[paths objectAtIndex:0] stringByAppendingPathComponent:#"photoapp.pae"];
[imageData writeToFile:fullPathToFile atomically:NO];
interactionController = [UIDocumentInteractionController interactionControllerWithURL:[NSURL fileURLWithPath:[NSString stringWithFormat:#"file://%#", fullPathToFile]]];
interactionController.UTI = #"com.photoapp.exclusive";
interactionController.delegate = self;
[interactionController presentOpenInMenuFromRect:self.view.frame inView:self.view animated:YES];
}
And here is what I have in my plist file for my app:
<key>UTExportedTypeDeclarations</key>
<array>
<dict>
<key>UTTypeDescription</key>
<string>Exclusive PhotoApp Photo</string>
<key>UTTypeConformsTo</key>
<array>
<string>com.photoapp.photo</string>
</array>
<key>UTTypeIdentifier</key>
<string>com.photoapp.exclusive</string>
<key>UTTypeTagSpecification</key>
<dict>
<key>public.filename-extension</key>
<string>pae</string>
</dict>
</dict>
<dict>
<key>UTTypeTagSpecification</key>
<dict>
<key>public.filename-extension</key>
<string>pa</string>
</dict>
<key>UTTypeIdentifier</key>
<string>com.photoapp.photo</string>
<key>UTTypeDescription</key>
<string>PhotoApp Photo</string>
<key>UTTypeConformsTo</key>
<array>
<string>public.png</string>
<string>public.jpeg</string>
</array>
</dict>
</array>
<key>UIFileSharingEnabled</key>
<true/>
<key>CFBundleDocumentTypes</key>
<array>
<dict>
<key>LSItemContentTypes</key>
<array>
<string>com.photoapp.exclusive</string>
<string>com.photoapp.photo</string>
</array>
<key>CFBundleTypeName</key>
<string>Photo</string>
<key>LSHandlerRank</key>
<string>Default</string>
</dict>
</array>
As soon as you specify a UTI such as public.png or public.jpeg, all apps that specify that they can open files of these types will be able to open your file. So, if you do not specify any type conformance at all in your com.photoapp.exclusive UTI, no apps will appear to support it.

How do I add a menu item to the share menu in iOS

I'm just getting into iOS development, but something I'm going to have to do early on is add a button to the system menus like how Dropbox has added its button when interacting with email attachments.
This application will be for video so adding a button on the share menu for quicktime players would be ideal.
I've scoured the documentation and have only found the UIMenuItem class. Is this what I want or is there another way to implement this functionality?
Set project-info.plist -> add new item (UTExportedTypeDeclarations)
<key>UTExportedTypeDeclarations</key>
<array>
<dict>
<key>UTTypeConformsTo</key>
<array>
<string>com.apple.quicktime-movie</string>
</array>
<key>UTTypeIdentifier</key>
<string>com.company.project</string>
<key>UTTypeTagSpecification</key>
<dict/>
</dict>
</array>
Coding your ButtonClick event in .m file
-(IBAction)actionClick:(id)sender{
UIDocumentInteractionController *documentController =
[UIDocumentInteractionController interactionControllerWithURL:
[NSURL fileURLWithPath:MOVIE_FILE_PATH]];
documentController.delegate = self;
documentController.UTI = #"com.apple.quicktime-movie";
[documentController presentOpenInMenuFromRect:CGRectZero
inView:self.view
animated:YES];
}

Custom URL schema doesn't open app

I have a problem with custom URL schema. I think I've configured it properly but it doesn't open the app if it is closed, if the app is in "background" (i.e. I can see it double tapping the home button) the app is opened when I tap on the link.
<key>CFBundleURLTypes</key>
<array>
<dict>
<key>CFBundleURLName</key>
<string>com.test</string>
<key>CFBundleURLSchemes</key>
<array>
<string>test</string>
<string>test1</string>
</array>
</dict>
</array>
the link is
TEST
other applications work fine but not mine.
Thanks,
Matteo
Do you return NO; anywhere in your - (BOOL)application:(UIApplication *)application openURL:(NSURL *)url sourceApplication:(NSString *)sourceApplication annotation:(id)annotation method?
I can't think of anything that would cause it to not open, aside from returning NO.

Changing Data in a Plist

Hey, alright so I have a .plist that looks like;
<plist version="1.0">
<dict>
<key>Item 0</key>
<dict>
<key>Name</key>
<string>Jero</string>
<key>Initiative</key>
<integer>0</integer>
<key>EditThis</key>
<false/>
</dict>
</dict>
</plist>
In the app I have it so that when one of the rows (The data is put in a UITableView) is selected it pushes to a new view controller. I would like also to set the 'EditThis' boolean to yes, so the edit view controller can learn which to edit. However I can't seem to figure out how to change the value. Any help is much appreciated.
Load the plist into a mutable dictionary:
NSMutableDictionary *plist = [NSMutableDictionary dictionaryWithContentsOfFile:#"file.plist"];
[plist setObject:[NSNumber numberWithBool:YES] forKey:#"EditThis"];
[plist writeToFile:#"file.plist" atomically:YES];