Is there anyway to display UIAlertController ONLY when app launches? - swift

so I have the following code in the viewDidAppear section
let theAlert = UIAlertController(title: "SUP", message: "DAWG", preferredStyle: UIAlertControllerStyle.Alert)
theAlert.addAction(UIAlertAction(title: "sup!", style: UIAlertActionStyle.Default, handler: nil))
self.presentViewController(theAlert, animated: true, completion: nil)
Don't mind the messages, I just came up with them randomly :3
Okay, so is there anyway for me to ONLY display this message when the app launches? Because when I come back from another controller, this message pops up again.

Set a flag to indicate if the message has shown or not.
// first check to see if the flag is set
if alertShown == false {
// show the alert
alertShown = true
}
For this behavior to persist through launches, and show only on FIRST launch, save to NSUserDefaults.
// when your app loads, check the NSUserDefaults for your saved value
let userDefaults = NSUserDefaults.standardUserDefaults()
let alertShown = userDefaults.valueForKey("alertShown")
if alertShown == nil {
// if the alertShown key is not found, no key has been set.
// show the alert.
userDefaults.setValue(true, forKey: "alertShown")
}
You can handle both of these in the root view controller viewDidLoad.

Related

How to filter the images shown on the PHPickerViewController to those selected for limited access

How do I filter the images shown on the PHPickerViewController to those that have been selected under limited access by the user? Or do I need to use a different picker? I've been struggling with this for a few days now. Any help would be appreciated. Thanks in advance.
When user taps the button:
1-5 are automatic
The alert appears with Camera or Photo Library
They choose Photo Library
The authorization alert appears with Select Photo…, Allow Access to All Photos or Don’t Allow
They tap Select Photos = .limited
The presentLimitedLibraryPicker is displayed, for the user to choose the photos thay want to allow and taps Done.
Now I want the picker to appear with a filtered choice of the images the user has just chosen. Seems like this would be automatic too. Not...
This only displays the same picker where the user made the selections for limited access.
PHPhotoLibrary.shared().presentLimitedLibraryPicker(from: self)
What goes in the .limited case?
var config = PHPickerConfiguration()
config.selectionLimit = 1
config.filter = PHPickerFilter.any(of: [.images, .livePhotos])
let picker_Photo = PHPickerViewController(configuration: config)
picker_Photo.delegate = self
let libCell = UIAction(title: "Photo Library", image: UIImage(systemName: "photo"), identifier: .none, discoverabilityTitle: .none) { (libAction) in
if UIImagePickerController.isSourceTypeAvailable(.photoLibrary)
{
PHPhotoLibrary.requestAuthorization(for: .readWrite) { status in
switch status
{
case .limited:
DispatchQueue.main.async
{
// PHPhotoLibrary.shared().register(self)
// PHPhotoLibrary.shared().presentLimitedLibraryPicker
self.present(picker_Photo, animated: true, completion: nil)
}
case .authorized:
DispatchQueue.main.async
{
self.present(picker_Photo, animated: true, completion: nil)
}
case .notDetermined:
DispatchQueue.main.async
{
self.present(picker_Photo, animated: true, completion: nil)
}
case .restricted:
self.view.sendConfirmationAlert(theTitle: "Photo Library Restricted",
theMessage: "Photo Library access was previously denied. Please update your Settings to allow access.", buttonTitle: "Ok")
case .denied:
let settingsAlert = UIAlertController(title: "Photo Library Access Denied",
message: "Photo Library access was previously denied. Please update your Settings to allow access.", preferredStyle: .alert)
let settingsAction = UIAlertAction(title: "Go to Settings", style: .default) { ( action ) in
let settingsUrl = URL(string: UIApplication.openSettingsURLString)
UIApplication.shared.open(settingsUrl!, options: [:])
}
let cancelAction = UIAlertAction(title: "Cancel", style: .cancel)
DispatchQueue.main.async
{
settingsAlert.addAction(settingsAction)
settingsAlert.addAction(cancelAction)
self.present(settingsAlert, animated: true)
}
default:
return
}
}
}
}
You are mistaken about what limited access means. It restricts what information you can read and write into the photo library.
But your code does not read from the photo library in the first place. You are saying
config = PHPickerConfiguration()
So this means you have no photo library access at all by way of the picker. You can only get image copies. You therefore do not need any kind of permission to show the picker, and the user limitation makes no difference to you. You can in fact just throw away all your authorization related code; it has no effect. Your picker will work exactly the same without it.
If you needed photo library access by way of the picker, you would have called
https://developer.apple.com/documentation/photokit/phpickerconfiguration/3616114-init
In that case the user limitation would matter to you — when you tried to access an actual PHAsset. But your code never does that. You are asking for a permission you do not need.

How to check if email is already in use and if email is in bad format prior to creating the user via Firebase (Swift)

is it possible to check if an email address is already in use before calling the Auth.auth().createUser(withEmail: createEmail...
I have multiple sign up view controllers which users will have to enter an email address, create user name, then enter their name and create a password in that exact order. However these are all separate view controllers besides the name and password ( that one is together in one).
I would like the user to know if the email address entered is in the correct format and or if it is already in use. The only way I figured out how to do it is after the user goes through all of the view controllers then clicks the sign up button which checks for ALL errors.
This is the code I have for the final view controller which creates the user after all the steps are completed ( sign up button pressed)
Auth.auth().createUser(withEmail: createEmail as! String, password: password as! String ) { (user, error) in
// stop activity indicator
self.nextButton.setTitle("Sign Up", for: .normal)
self.activityIndicator.stopAnimating()
if error == nil && user != nil {
print("User Created!")
// If user is created go to Welcome Page
self.performSegue(withIdentifier: "goToWelcomeVC", sender: self)
} else {
// If there is an error creating an account
print("error creating User: \(error!.localizedDescription)")
print(error!._code)
self.handleError(error!)
return
This is the code I am playing around with for the email view controller. ( continue button pressed) ** do not mind to much of the AuthErrorCode, I was trying to find a way to call that and incorporate it into the error checking.. does not seem to be working to well for me.
// TODO check email
let invalidEmail = AuthErrorCode.invalidEmail
let emailTaken = AuthErrorCode.emailAlreadyInUse
}
if (emailTextField.text?.isEmpty)! {
print("textField is empty")
let alert = UIAlertController(title: "Oops!", message: "Please enter an email address.", preferredStyle: .alert)
alert.addAction(UIAlertAction(title: " Try Again", style: UIAlertAction.Style.default, handler: nil))
self.present(alert, animated: true, completion: nil)
} else {
self.performSegue(withIdentifier: "goToCreateUsernameVC", sender: self)
}
}
You need to check out fetchSignInMethodsForEmail. It provides an API to look up all the associated methods of sign-in for the provided email. If the email is not registered, you will get back an empty array.

Detect when iPhone is being unplugged and plugged in

I am just trying to write simple code that detects when the iPhone is unplugged and then plugged in. But being event-driven, instead of using a while loop. This code does work, but doesn't detect if the phone is unplugged and will not update the printed text.
EDIT
In the long run I just want the phone to play a sound whenever the iPhone is unplugged. (Sorry for leaving the end goal out.). I was using this print statements just so I can make sure it was working.
func startCharger()
{
printscreen.text="Started charger protocol"
UIDevice.current.isBatteryMonitoringEnabled=true
if(UIDevice.current.batteryState == .unplugged)
{
printscreen.text="Battery is unplugged"
}
else
{
printscreen.text="Battery is plugged in"
}
}
Quick implementation of Dule' code.
Check if the power is connected.
Copy these functions into your class.
Call isPowerConnected() in the viewDidLoad
func isPowerConnected(){
UIDevice.current.isBatteryMonitoringEnabled = true
NotificationCenter.default.addObserver(
self,
selector: #selector(batteryStateChanged),
name: .UIDeviceBatteryStateDidChange,
object: nil)
}
var chargingVar = "" //Empty Variable
func batteryStateChanged(){
if (UIDevice.current.batteryState == .charging) { //Here we check if the device is charging
UIApplication.shared.isIdleTimerDisabled = true //Here we disable the lock screen time out value
self.chargingVar = "is charging. \u{1F603}" //Here we change the variable to "is charging" 😀
chargingAlaer() //If power is pluged in we send an Alert
}else{
self.chargingVar = "is not charging. \u{1F622} " //Here we change the variable to "is not charging" 😥
chargingAlaer() //If power is not pluged we send an Alert
}
}
func chargingAlaer(){
let alertController = UIAlertController(title: "Charging Status",
message: "Your device \(chargingVar)",
preferredStyle: UIAlertControllerStyle.alert)
let ok = UIAlertAction(title: "OK",
style: UIAlertActionStyle.default,
handler: {(action) -> Void in
})
alertController.addAction(ok)
self.present(alertController, animated: true, completion: nil)
}
You can get a notification on battery state change with UIDeviceBatteryStateDidChange, the code looking something like this:
NotificationCenter.default.addObserver(
self,
selector: #selector(batteryStateChanged),
name: .UIDeviceBatteryStateDidChange,
object: nil)
Of course, you need a method in ViewController (or wherever you want to get notification). In this example:
func batteryStateChanged(){
// Your logic
}

Capture self was never used

I don't post the entire code because it's really too large. Anyway, it's a user registration built this way.
There is a modal whose child is a pageViewController:
the first page is for Login;
the second page is for Registration;
From Login you can reach Registration and, once registered, pageViewController should automatically transition to the first page, so that the user can login with his new credentials.
The process of user registration is managed by a button and Alamofire: once the button is clicked, the values the user inserted in the textfields are validated, then I start a post request, sending data to the server and receiving JSON data back in a while.
It's anything very simple (sorry for speaking too much), but in the end, after I receive the JSON, something strange happens here:
let j = JSON as! NSDictionary
let userStatus = j.object(forKey: "status")!
if((userStatus as! Int) == 0){
//
print("user registerd")
let alert = UIAlertController(title: "Registration ok", message: "Registration OK", preferredStyle:UIAlertControllerStyle.alert)
let okAlert = UIAlertAction(title:"OK", style: .default, handler: {action in v.scrollToPreviousViewController() })
alert.addAction(okAlert)
self.present(alert, animated: true, completion: nil)
What is supposed to do this code? Once the user clicks the alert button, the pageviewcontroller should return with an animation to the login screen.
What happens? It returns back there but without animation.
This led me to think I should avoid "polluting" the global thread reserved to the GUI. And, in fact, I tried to put all the code inside a:
DispatchQueue.main.async { [unowned self] in
without any success.
Then, I tried another thing:
let okAlert = UIAlertAction(title:"OK", style: .default, handler:
{action in DispatchQueue.main.async { [unowned self] in v.scrollToPreviousViewController() }})
I don't perfectly understand why, but this practically works and eliminates the issue with the animation.
But that unowned self there generates a warning: "Capture self was never used". What am I doing wrong?
If you didn't use self inside the async block then you will get this warning obviously. Please try with _ instead of self.
to see what is swift capture list for, check this example ...
var i = 25
var cl = {print(i)}
var clc = {[i] in print(i)}
i = 35
cl() // 35
clc() // 25
the warning message "Capture self was never used" is therefore self-explanatory. you don't need to put self in your capture list, because you don't use it there

NSAlert beginSheetModalForWindow Not Showing Alert

I have a settings view controller that is presented as a sheet. It has a button that saves the settings if they are valid. If the settings are valid the view controller is dismissed. If they are not valid the user gets an alert saying the settings are not valid. My code is as follows:
var settingsValidated = false
#IBAction func dismissSettings(sender: AnyObject) {
if settingsValidated == true {
dismissViewController(self)
} else {
let alert = NSAlert()
alert.messageText = "Warning"
alert.addButtonWithTitle("OK")
alert.informativeText = "Your settings did not validate!"
let window = NSApplication.sharedApplication().mainWindow
let res = alert.beginSheetModalForWindow(window!, completionHandler: nil)
}
}
If settingsValidated is set to true everything works as expected but when I set settingsValidated to false nothing happens. The alert never shows. What am I missing? I do not receive any errors in Xcode.
Please note this question is about OS X NOT iOS.
It's not showing up because you aren't doing anything with the res object! — so remove it:
alert.beginSheetModalForWindow(window!, completionHandler: nil)
↳ NSAlert Class Reference