I am trying to change the app icon through code, but it does not seem to work. Below is my info.plist
<key>CFBundleIcons</key>
<dict>
<key>CFBundlePrimaryIcon</key>
<dict>
<key>CFBundleIconFiles</key>
<array>
<string>icon_60pt</string>
</array>
</dict>
<key>CFBundleAlternateIcons</key>
<dict>
<key>AppIcon-2</key>
<dict>
<key>CFBundleIconFiles</key>
<array>
<string>icon.dark_60pt</string>
</array>
</dict>
</dict>
</dict>
Here is the code I am using to change the icon:
#objc func changeIcon() {
//Check if the app supports alternating icons
guard UIApplication.shared.supportsAlternateIcons else {
return;
}
let name = "icon.dark_60pt"
//Change the icon to a specific image with given name
UIApplication.shared.setAlternateIconName(name) { (error) in
//After app icon changed, print our error or success message
if let error = error {
print("App icon failed to due to \(error.localizedDescription)")
} else {
print("App icon changed successfully.")
}
}
}
And finally, here is the folder with the app icons: App icon folder screenshot
As you can see, I am using the same name everywhere "icon.dark_60pt", but I still get an error "The file doesn’t exist."
App icon failed to due to Error Domain=NSCocoaErrorDomain Code=4 "The file doesn’t exist." UserInfo={_LSLine=191, NSUnderlyingError=0x6000026e85d0 {Error Domain=LSApplicationWorkspaceErrorDomain Code=-105 "iconName not found in CFBundleAlternateIcons entry" UserInfo={_LSLine=179, NSLocalizedDescription=iconName not found in CFBundleAlternateIcons entry, _LSFunction=-[LSAltIconManager _setAlternateIconName:forIdentifier:withIconsDictionary:error:]}}, _LSFunction=-[LSAltIconManager _setAlternateIconName:forIdentifier:withIconsDictionary:error:]}
What am I doing wrong?
I think you have to use the name of the icon, not the name of the file. Change the let name line with this:
let name = "AppIcon-2"
Related
I receive the follow error when trying to login using the iOS Facebook SDK:
Invalid Scopes: public_profile, openid.
I have followed the instructions from here which has resulted in this set up:
info.plist
<plist version="1.0">
<dict>
...
<key>CFBundleURLTypes</key>
<array>
<dict>
<key>CFBundleTypeRole</key>
<string>Editor</string>
<key>CFBundleURLName</key>
<string></string>
<key>CFBundleURLSchemes</key>
<array>
<string>GOOGLE_URL_SCHEME</string>
<string>fbMY_FB_APP_ID</string>
</array>
</dict>
</array>
<key>FacebookAppID</key>
<string>MY_FB_APP_ID</string>
<key>FacebookClientToken</key>
<string>MY_FB_CLIENT_TOEN</string>
<key>FacebookDisplayName</key>
<string>MY_FB_APP_NAME</string>
<key>LSApplicationQueriesSchemes</key>
<array>
<string>fbauth2</string>
<string>fbapi</string>
<string>fb-messenger-share-api</string>
</array>
</dict>
</plist>
AppDelegate.swift
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
FirebaseApp.configure()
ApplicationDelegate.shared.application( application, didFinishLaunchingWithOptions: launchOptions )
return true
}
func application(_ app: UIApplication, open url: URL, options: [UIApplication.OpenURLOptionsKey : Any] = [:]
) -> Bool {
return ApplicationDelegate.shared.application(app, open: url, sourceApplication: options[UIApplication.OpenURLOptionsKey.sourceApplication] as? String, annotation: options[UIApplication.OpenURLOptionsKey.annotation])
}
Login snippet
let loginManager = LoginManager()
loginManager.logIn(permissions: ["public_profile"], from: self) { result, error in
if let error = error {
print("FB Error: \(error)")
} else if let result = result, result.isCancelled {
print("FB Cancelled")
} else {
print("FB Logged In")
}
}
I am on iOS 16.2 using the facebook-ios-sdk version 15.1.0. The same error occurs with FB app in live and development mode. I receive the same error on the simulator and device. I can successfully login on the web when using the FB app JS library. I believe I have followed the instructions correctly. What am I missing?
Edit: Settings Screenshots
Edit:
So I just downloaded this sample from the facebook-ios-sdk. Added my FB App Id to the FacebookAppID field and URL Schemes in the plist. Added the FB Client Token to the plist and updated the bundle identifier to the one listed in the Facebook app, but I get the same error when I run the sample. What the hell is going on? The issue must be in the Facebook app set up, but where? I can't find this issue reported anywhere on the net. Surely someone has seen this before.
I figured it out. I was missing the facebook login from my facebook app products. I found it by accident and now I can login successfully.
What is the best way to create a set of icons influenced by the operating system to display a colored / accent version?
As with the;
selected version
accent version
I have about 10 black versions, but would like to have them adjusted with either selected or system chosen accent color. What should I have to do with my icons to let them coloured by the OS
Any road map?
This code shows you how to add set an alternative icon based on iOS theme, and your settings bundle. I've also added accent1Icon and accent2Icon as examples.
In your Settings.bundle, you need to add a Multi Value - App item to Preference Items (Apple requires that users can change the theme, even if you automatically set it based on their iOS settings):
<dict>
<key>Type</key>
<string>PSMultiValueSpecifier</string>
<key>Values</key>
<array>
<string>0</string>
<string>1</string>
<string>2</string>
<string>3</string>
<string>4</string>
</array>
<key>Title</key>
<string>App Icon Theme</string>
<key>Key</key>
<string>app_icon_theme</string>
<key>DefaultValue</key>
<string>0</string>
<key>Titles</key>
<array>
<string>Use iOS Theme</string>
<string>Dark Theme</string>
<string>Light Theme</string>
<string>Accent1 Theme</string>
<string>Accent2 Theme</string>
</array>
</dict>
Create a class that minimally has your app_icon_theme setting:
class SettingsBundleHelper {
struct SettingsBundleKeys {
static let AppIconThemeKey = "app_icon_theme"
}
}
Add this to your info.plist:
<dict>
<key>CFBundleAlternateIcons</key>
<dict>
<key>darkIcon</key>
<dict>
<key>CFBundleIconFiles</key>
<array>
<string>name-of-dark-icon</string>
</array>
<key>UIPrerenderedIcon</key>
<false/>
</dict>
<key>accent1Icon</key>
<dict>
<key>CFBundleIconFiles</key>
<array>
<string>name-of-accent1-icon</string>
</array>
<key>UIPrerenderedIcon</key>
<false/>
</dict>
<key>accent2Icon</key>
<dict>
<key>CFBundleIconFiles</key>
<array>
<string>name-of-accent2-icon</string>
</array>
<key>UIPrerenderedIcon</key>
<false/>
</dict>
</dict>
<key>CFBundlePrimaryIcon</key>
<dict>
<key>CFBundleIconFiles</key>
<array>
<string>AppIcon</string>
</array>
<key>UIPrerenderedIcon</key>
<false/>
</dict>
</dict>
Create a folder in your project called Alternate Icons and save a name-of-dark-icon#2x.png and name-of-dark-icon#3x.png in it.
YourProject
|
+-- Alternate Icons (folder)
|
+-- name-of-dark-icon#2x.png
+-- name-of-dark-icon#3x.png
+-- name-of-accent1-icon#2x.png
+-- name-of-accent1-icon#3x.png
+-- name-of-accent2-icon#2x.png
+-- name-of-accent2-icon#3x.png
You could run the changeIcon code in your AppDelegate applicationDidBecomeActive (or elsewhere). If you choose to run it there, you'll need to add this to your AppDelegate file:
enum AppIconTheme: String {
case UseiOSTheme = "0"
case DarkTheme = "1"
case LightTheme = "2"
case Accent1Theme = "3"
case Accent2Theme = "4"
}
func applicationDidBecomeActive(_ application: UIApplication) {
// update icon if dark mode
if #available(iOS 12.0, *) {
var theme = AppIconTheme.UseiOSTheme
if let iconTheme = UserDefaults.standard.string(forKey: SettingsBundleHelper.SettingsBundleKeys.AppIconThemeKey) {
if let themeSettings = AppIconTheme(rawValue: iconTheme) {
theme = themeSettings
}
}
print(theme as Any)
switch (theme) {
case .UseiOSTheme:
if UIApplication.shared.windows[0].rootViewController?.traitCollection.userInterfaceStyle == .dark {
self.changeIcon(to: "darkIcon")
} else {
self.changeIcon(to: nil)
}
case .LightTheme:
self.changeIcon(to: nil)
case .DarkTheme:
self.changeIcon(to: "darkIcon")
case .Accent1Theme:
self.changeIcon(to: "accent1Icon")
case .Accent2Theme:
self.changeIcon(to: "accent2Icon")
}
} else {
// Fallback on earlier versions
var theme = AppIconTheme.UseiOSTheme
if let iconTheme = UserDefaults.standard.string(forKey: SettingsBundleHelper.SettingsBundleKeys.AppIconThemeKey) {
theme = AppIconTheme(rawValue: iconTheme)!
}
print(theme as Any)
switch (theme) {
case .UseiOSTheme:
self.changeIcon(to: nil)
case .LightTheme:
self.changeIcon(to: nil)
case .DarkTheme:
self.changeIcon(to: "darkIcon")
case .Accent1Theme:
self.changeIcon(to: "accent1Icon")
case .Accent2Theme:
self.changeIcon(to: "accent2Icon")
}
}
}
func changeIcon(to name: String?) {
//Check if the app supports alternating icons
guard UIApplication.shared.supportsAlternateIcons else {
return;
}
if UIApplication.shared.alternateIconName != name {
//Change the icon to a specific image with given name
// if name is nil, the app icon will be the default app icon
UIApplication.shared.setAlternateIconName(name) { (error) in
//After app icon changed, print our error or success message
if let error = error {
print("App icon failed to due to \(error.localizedDescription)")
} else {
print("App icon changed successfully.")
}
}
}
}
Here is the documentation from Apple on setAlternativeIcon:
https://developer.apple.com/documentation/uikit/uiapplication/2806818-setalternateiconname
Someone pointed out that this was a duplicate question, Yes partly, I followed the advice in the other post and added the URLScheme as shown below, Also as suggested i forgot to add to my other target so i did and the URL twitter-13145245245624 Now what happens is my app redirects the user to their Twitter App and asks for permission to have my app use their info, once tapping the ok button user is redirected back to my app but still no Composer populates the View to Tweet. Still confused. Thanks for all the help.
let composer = TWTRComposer()
composer.setText("just setting up my Twitter Kit")
composer.setImage(UIImage(named: "twitterkit"))
// Called from a UIViewController
composer.show(from: self) { (result) in
if (result == .done) {
print("Successfully composed Tweet")
} else {
print("Cancelled composing")
}
}
This is my info.plist, however, I have no issue with posting to Facebook.
Any thoughts?
<key>CFBundleURLTypes</key>
<array>
<dict>
<key>CFBundleURLSchemes</key>
<array>
<string>twitterkit-xxxxxxxxxx</string>
<string>fbxxxxxx</string>
</array>
</dict>
</array>
<key>LSApplicationQueriesSchemes</key>
<array>
<string>twitter</string>
<string>twitterauth</string>
</array>
Regards
J
The issue to my above question was that I did not have the below method in AppDelegate as so. This Solved my problem.
-(BOOL)application:(UIApplication*)app openURL:(nonnull NSURL *)url options:(nonnull NSDictionary<UIApplicationOpenURLOptionsKey,id> *)options{
return [[TWTRTwitter sharedInstance]application:app openURL:url options:options];
}
I have an iOS app written in Swift. In this app I'm trying to load an item from a DynamoDB table, but for some reason, I couldn't load any item, even though all the details were correct.
I have installed the AWS SDK using CocoaPods, after I followed all the instructions in order to correctly install it. I have installed the following libraries: AWSCognito, AWSCognitoIdentityProvider, AWSDynamoDB, AWSS3, AWSSNS.
After that, I have added my AWS credentials in the Info.plist file:
<key>AWS</key>
<dict>
<key>DynamoDBObjectMapper</key>
<dict>
<key>Default</key>
<dict>
<key>Region</key>
<string>USEast1</string>
</dict>
</dict>
<key>DynamoDB</key>
<dict>
<key>Default</key>
<dict>
<key>Region</key>
<string>USEast1</string>
</dict>
</dict>
<key>CredentialsProvider</key>
<dict>
<key>CognitoIdentity</key>
<dict>
<key>Default</key>
<dict>
<key>Region</key>
<string>USEast1</string>
<key>PoolId</key>
<string>myPoolId</string>
</dict>
</dict>
</dict>
</dict>
I've created a mapper file called Contact.swift:
import UIKit
import AWSDynamoDB
class Contact: AWSDynamoDBObjectModel, AWSDynamoDBModeling {
var id: String?
var name: String?
class func dynamoDBTableName() -> String {
return "Contacts"
}
class func hashKeyAttribute() -> String {
return "id"
}
}
Then, I've added the following code in ViewController.swift file, inside the viewDidLoad method. The code should get an item from a table, save its attributes, and set its name attribute to be the title of the screen:
import UIKit
import AWSDynamoDB
class ViewController: UIViewController {
//MARK: Properties
struct GlobalVars {
static let dynamoDBObjectMapper = AWSDynamoDBObjectMapper.default()
static let id: String = "id"
static var name: String?
}
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
GlobalVars.dynamoDBObjectMapper.load(Contact.self, hashKey: GlobalVars.id, rangeKey: nil).continueWith(block: {(task: AWSTask<AnyObject>!) -> Any? in
if let error = task.error as NSError? {
print("The request failed. Error: \(error)")
} else if let taskResult = task.result as? Contact {
// Save the information
GlobalVars.name = taskResult.name
// Set title to the name
self.navigationItem.title = GlobalVars.name!
}
return nil
})
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
}
The problem is that the app crashes when I'm trying to assign the GlobalVars.name variable to the navigation bar title. It crashes with the following message: Fatal error: Unexpectedly found nil while unwrapping an Optional value.
I've tried to print taskResult.name instead, but it just printed nil.
But it didn't print anything to the console. I've added the following code to the Info.plist file, but that didn't work also:
<key>NSAppTransportSecurity</key>
<dict>
<key>NSExceptionDomains</key>
<dict>
<key>amazonaws.com</key>
<dict>
<key>NSThirdPartyExceptionMinimumTLSVersion</key>
<string>TLSv1.0</string>
<key>NSThirdPartyExceptionRequiresForwardSecrecy</key>
<false/>
<key>NSIncludesSubdomains</key>
<true/>
</dict>
<key>amazonaws.com.cn</key>
<dict>
<key>NSThirdPartyExceptionMinimumTLSVersion</key>
<string>TLSv1.0</string>
<key>NSThirdPartyExceptionRequiresForwardSecrecy</key>
<false/>
<key>NSIncludesSubdomains</key>
<true/>
</dict>
</dict>
When I'm checking in the variables area at the bottom of the editor, I can see that all of the item's attributes are nil.
After a deep search, I've noticed something very weird. When I changed the name of the table to a table which doesn't exist, I have received the following message in the console:
The request failed. Error: Error Domain=com.amazonaws.AWSDynamoDBErrorDomain Code=7 "(null)" UserInfo={__type=com.amazonaws.dynamodb.v20120810#ResourceNotFoundException, message=Requested resource not found}
When I'm running it with a correct table name, but with a wrong hash key which refers to an item which doesn't exist in the table, I don't get anything. It doesn't crashes or prints a message to the console. It just keeps running like I'm don't asking for anything from the DynamoDB table.
What can I do about it? I've already searched all over the internet but I couldn't find anything about it yet... Could you please help me solving that?
So apparently, due to a change in Swift 4 behavior change of inferencing #objc, I was supposed to add #objcMembers before the class declaration in the Contact.swift file
I am trying to login with Facebook with Parse in iOS9 but the application keep opening Safari instead of Facebook app in real device. and even in Safari when I try to use the keyboard to enter the email and password of Facebook account the page reload so it's impossible to login and give the permission to the app. The user should open safari and login first in Facebook then open my app and then give permission. I think it's not the best user experience since the user have already a Facebook app.
I have followed all the steps I will list them here:
Add Fraleworks
Link Binaries
Updaded info.plist
<key>CFBundleURLTypes</key>
<array>
<dict>
<key>CFBundleURLSchemes</key>
<array>
<string>fb907580375984874</string>
</array>
</dict>
</array>
<key>CFBundleVersion</key>
<string>1</string>
<key>FacebookAppID</key>
<string>907580375984874</string>
<key>FacebookDisplayName</key>
<string>Appname</string>
<key>LSApplicationQueriesSchemes</key>
<array>
<string>fbapi</string>
<string>fbapi20130214</string>
<string>fbapi20130410</string>
<string>fbapi20130702</string>
<string>fbapi20131010</string>
<string>fbapi20131219</string>
<string>fbapi20140410</string>
<string>fbapi20140116</string>
<string>fbapi20150313</string>
<string>fbapi20150629</string>
<string>fbauth</string>
<string>fbauth2</string>
<string>fb-messenger-api20140430</string>
</array>
<key>LSRequiresIPhoneOS</key>
<true/>
<key>NSAppTransportSecurity</key>
<dict>
<key>NSExceptionDomains</key>
<dict>
<key>akamaihd.net</key>
<dict>
<key>NSExceptionRequiresForwardSecrecy</key>
<false/>
<key>NSIncludesSubdomains</key>
<true/>
</dict>
<key>facebook.com</key>
<dict>
<key>NSExceptionRequiresForwardSecrecy</key>
<false/>
<key>NSIncludesSubdomains</key>
<true/>
</dict>
<key>fbcdn.net</key>
<dict>
<key>NSExceptionRequiresForwardSecrecy</key>
<false/>
<key>NSIncludesSubdomains</key>
<true/>
</dict>
</dict>
</dict>
App Delegate
import UIKit
import Parse
import FBSDKCoreKit
import ParseFacebookUtilsV4
#UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {
var window: UIWindow?
func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
Parse.setApplicationId("appID", clientKey: "MyKey")
PFFacebookUtils.initializeFacebookWithApplicationLaunchOptions(launchOptions)
return true
}
func application(application: UIApplication, openURL url: NSURL, sourceApplication: String?, annotation: AnyObject) -> Bool {
return FBSDKApplicationDelegate.sharedInstance().application(application,openURL: url,sourceApplication: sourceApplication, annotation: annotation)
}
func applicationDidBecomeActive(application: UIApplication) {
FBSDKAppEvents.activateApp()
}
}
Login code:
#IBAction func loginButtonClicked(sender: AnyObject) {
if let _ = FBSDKAccessToken.currentAccessToken() {
print("connected already")
} else {
PFFacebookUtils.logInInBackgroundWithReadPermissions(["public_profile", "email", "user_friends", "user_birthday" , "user_education_history","user_photos"]) {
(user: PFUser?, error: NSError?) -> Void in
if let user = user {
if user.isNew {
print("User signed up and logged in through Facebook!")
} else {
print("User logged in through Facebook!")
}
} else {
print("Uh oh. The user cancelled the Facebook login.")
}
}
}
}
Using a webview to log users in is now the default behaviour of the Facebook SDK for iOS 9 and according to Facebook team, this approach gives a better user experience as it avoids the additional dialogues being shown between app transitions.
In apps that use the newest SDK (v4.6 and v3.24), we will surface a
flow using Safari View Controller (SVC) instead of fast-app-switching
(FAS) because of additional dialog interstitials that add extra steps
to the login process in FAS on iOS 9. Additionally, data that we've
seen from more than 250 apps indicate that this is the best experience
for people in the long run
Read more on Facebook