Run methods on app installation - ios

I want to prepopulate my database on app installation in the app store, so I have methods to retrieve data to put them in core data. It is possible ? Here is a method like onInstallation ?

No you can not run code after installation.
Only on first start of your app can your run code, this would be the place to setup some data that your app needs.
If the data is not subject to change I would suggest you create the data store for CoreData with all the initial data and copy this on first run from the main bundle to the directory where you store your CoreData store.
If you need to fetch data you might want to display a screen to the user explaining that you setting up the app and that this might take some time depending on the user data connection.

Not on install as far as I am aware, but how you could do is:
1 - in the AppDelegate.swift
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
if UserDefaults.standard.value(forKey: "alreadyLaunch") as? Bool == nil || UserDefaults.standard.value(forKey: "alreadyLaunch") as? Bool == false{
//populate your database
} else {
//do nothing
}
return true
}
2 - After populating the database, add:
UserDefaults.standard.set(true, forKey: "alreadyLaunch")

Related

Is it good idea to store value in userDefaults on sign in and check user status every time when App open?

When user Sign In, I'm storing some value into userDefaults and checking user at main screen is it already logged in or not .
Is it good idea to use userDefaults or there any other Method to check user logged in status.
Yes, you can save access token or user id in Userdefaults and check whether the user logged in or not.It is used to navigate to Home page or anyother if the user has already logged in.You can write a code for navigation in your Appdelegate.
If a piece of data is not sensitive (e.g., default font size), store it in NSUserDefaults.
If it needs to be secure from casual snooping (e.g., user's password), store it in the Keychain.
If it needs to be secure from the user (e.g., registration code), you will need to roll your own encryption, then store the data wherever you like.
In normal iPhones and iPads it's secure to store in UserDeafaults but in jailbroken devices one can get those data easily. That's why it's preferred to store sensitive data into Keychain.
Yes, UserDefaults is the best way to store information that isn't large.
You can store your users preferences in UserDefaults.
Generally, in you didFinishLaunching method in AppDelegate, you can do something like this:
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
if UserDefaults.standard.value(forKey: "userId") != nil {
/// etc.
}
return true
}
I would rather suggest Keychain instead of UserDefaults.
A keychain is an encrypted container that holds passwords for
multiple applications and secure services. Apple Inc. uses keychains
as password management system in Mac OS and iOS.
Having said that, all the sensitive information should go to the Keychain.
As per your point on checking user status each time, it is the right way to go. Mobile apps don't generally show login screen each time unless it is a critical app like that of banking.
var isUserLoggedIn: Bool {
return UserDefaults.standard.value(forKey: "userDetail") != nil
}
var currentUser : [String:Any] {
set{
guard let unwrappedKey = newValue else{
return
}
UserDefaults.standard.set(unwrappedKey, forKey: "userDetail")
UserDefaults.standard.synchronize()
} get {
guard let userDict = UserDefaults.standard.object(forKey:"userDetail") else {
return nil
}
return userDict
}
}
func removeCurrentUser(){
if UserDefaults.standard.value(forKey: "userDetail") != nil {
UserDefaults.standard.removeObject(forKey: "userDetail")
UserDefaults.standard.synchronize()
}
}
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
if isUserLoggedIn {
//etc..
}
return true
}
Now you can check user login or not using isUserLoggedIn property.
You can also create user model class.

SKStoreReviewController is being displayed the first time user launches the app

In my iOS app I'm using SKStoreReviewController to request users to rate the app. The Apple documentation says to put the code for requesting the "Rate Us" popup anywhere we want, and they will govern when it will be actually displayed.
I wrote the following code in the first view of the app:
func requestReview() {
SKStoreReviewController.requestReview()
}
The problem is that the popup is displayed to my app's users as soon as they first launch the app, which makes no sense. Is there any way to control the popup's appearance and avoid showing it before certain amount of uses of the app?
SKStoreReviewController.requestReview() will display the popup for the first few times (to be exact, for the first 3 times in a year).
Create a variable that you increment each time in your application delegate's didFinishLaunchingWithOptions method and save it to UserDefaults. After that, you can check whether a user opened the app enough times.
AppDelegate
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
var appLaunches = UserDefaults.standard.integer(forKey: "appLaunches")
appLaunches += 1
UserDefaults.standard.set(appLaunches, forKey: "appLaunches")
return true
}
The view controller where you want to display the store review controller
let appLaunches = UserDefaults.standard.integer(forKey: "appLaunches")
if appLaunches >= [enough number of app launches] {
SKStoreReviewController.requestReview()
}

How to make app update available to users in the form of an attractive screen? [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 5 years ago.
Improve this question
I was recently using "Make My Trip" app. I found a very attractive app update pop up screen appearing whenever I launch the app. It says to update the app. I want to incorporate that in my app update too. Please tell me how can I do it.
I am attaching a screenshot here for your consideration.
You can get all App info from iTunes store lookup API: http://itunes.apple.com/lookup?bundleId=YOUR_BUNDLE_ID, in this you can get App version on App Store.
Make your design screen as you want to show your App users, Then compare your App version on App store & user's device, if both version not equal then show the update version screen.
Below is the complete implementation to compare app version on App store & device:
func isUpdateAvailableOnStore() -> Bool {
let infoDictionary = Bundle.main.infoDictionary
let bundleId = infoDictionary!["CFBundleIdentifier"] as! String
let url = URL(string: "http://itunes.apple.com/lookup?bundleId=\(bundleId)")
let infoData = try? Data(contentsOf: url!)
let appInfo = (try? JSONSerialization.jsonObject(with: infoData! , options: [])) as? [String: Any]
if let resultCount = appInfo!["resultCount"] as? Int, resultCount == 1 {
if let results = appInfo!["results"] as? [[String:Any]] {
if let appStoreVersion = results[0]["version"] as? String{
let currentAppVersion = infoDictionary!["CFBundleShortVersionString"] as? String
if !(appStoreVersion == currentAppVersion) {
return true
}
}
}
}
return false
}
Call this function in you func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool function of AppDelegate.
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
// Your code here
if self.isUpdateAvailableOnStore(){
// SHOW YOUR UPDATE SCREEN TO USER'S
}else{
// APP VERSION IS UPDATED ON DEVICE
}
return true
}
simple, first you have to create design to show new updates screen is available in each build you upload.
then make api that fill info in updates screen and store flag in device locally, so whenever user open your app new update screen showed.
Yes for this you need to call new version api every time when user open your app or you can use push notification to pass as well.
You have to create to API 1st) api is return currently uploaded version on app store and 2nd) api is to get data that you want to show in your new updates available screen
step 1 : create screen design of update screen in your application.
step 2 : create API that return current version in app store, call this api in your app and check version is same or not.
step 3 : if version is not same than call Data API and store them in locally.
step 4 : if new updates data is available and version not same than show your new updates available screen when user open your app.
step 5 : after user updates app then check version and remove previous loaded data.

How do you save global arrays in the applicationWillTerminate and reload them in the application function?

So I have been trying to make an app for my Mobile Apps Development class and I need to find a solution to a problem that I'm having when I save a global array called "events".
Here I tried to reload the saved event class in AppDelegate but it didn't change in the main screen view controller:
func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
//Override point for customization after application launch.
//Load the events that were saved when application was terminated
let eventKey = NSUserDefaults.standardUserDefaults()
Global.events = (eventKey.arrayForKey("savedEvents") as? [Event])!
return true
}
Here is the function that is called when someone quits the app:
func applicationWillTerminate(application: UIApplication) {
// Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:.
let myEvents = Global.events
NSUserDefaults.standardUserDefaults().setObject(myEvents, forKey: "savedEvents")
NSUserDefaults.standardUserDefaults().synchronize()
}
This might just be an error in the viewcontroller that displays this array but if you see something wrong with the code please let me know.
Two problems:
In iOS, there is no such thing as "someone quits the app", and thus what you're doing is unlikely to work, because applicationWillTerminate is never called. Save when the application is deactivated or backgrounded.
An array of Event cannot magically be saved in user defaults, because Event is not a Property List type. You will need to make Event archivable and archive the array.

Parse Seamless Login

I have created an app using parse with Swift , when a user opens the app (not from the background) the login screen shows for a split second before moving to the main view. I wan't it to go straight to the main screen if the user is logged in.
I have tried putting the following code nearly everywhere.
if PFUser.currentUser() != nil {
}
I tried NSUserDefaults to check if the user is logged in, in the app delegate didFinishLaunching, couldn't get it to work.
Any help would be greatly appreciated , thanks.
You need to put the check into your "AppDelegate.swift" file.
Then depending on if the user is logged in or not load the MAIN viewcontroller or the LOGIN viewcontroller.
func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
// Other stuff you need to setup the app...
if PFUser.currentUser() == nil
{
//Load the Login ViewController
}
else
{
//Load the Main ViewController
}
return true
}

Resources