Refresh animation doesn't stop with "self.refreshControl.endRefreshing()" on iOS 10 - ios

This is my code:
func pullToRefresh() {
if Reachability().connectionStatus() == .Online {
self.homewebview.reload()
} else {
self.refreshControl.endRefreshing()
let alert = UIAlertView(title: "No Internet connection", message: "Please check your Internet connection.", delegate: nil, cancelButtonTitle: "Okay")
alert.show()
}
}
When internet connection is not available and the user pulls to refresh an alert should be shown and the animation should stop. That works great on iOS 9. But on iOS 10 Beta 2 the animation doesn't disappear. The user have to pull up to make it disappear. It that an iOS 10 bug or am I doing something wrong?

Related

iOS permission alert issue

I have a view that:
Creates an observer for UIApplicationDidBecomeActiveNotification with invokes a selector
Sequentially asks the user for permissions to: use the camera, location & receiving push notifications.
The view has three UIButtons with state depending on each permission state, which navigate the user to settings if permissions for anything were rejected
Tapping a button which represents a permission with rejected state navigates the user to settings
Once each alert hides, using the observer action, next alert is triggered and all button states are updated to reflect any changes
Once all permissions are granted it pushes next view with the rest of the signup/in flow.
The problem is: on some devices, when running the app from a clean state (app removed and reinstalled), permissions for location & notifications are set to rejected by default, as if the user was presented an alert that was rejected.
I couldn't pinpoint any rational issue behind this, except for leftover settings from some outdated build that don't get deleted when installing a new one. This view seems to be the only place that can possibly trigger these alerts.
Did anyone have a similar issue and can suggest anything?
I would suggest you to try to check for states of location services and notification services before asking user to use it. Since if user is going to disable these the moment you ask him for permission, he will need to go to the settings and enable it there. You should try to detect if user has disabled location/notification/camera.
For camera use:
func accessToCamera(granted: #escaping (() -> Void)) {
if UIImagePickerController.isSourceTypeAvailable(.camera) {
let status = AVCaptureDevice.authorizationStatus(forMediaType: AVMediaTypeAudio)
if status == .authorized {
granted()
} else if status == .denied {
self.cameraPermissionAlert()
} else if status == .notDetermined {
AVCaptureDevice.requestAccess(forMediaType: AVMediaTypeVideo, completionHandler: { (accessAllowed) in
if accessAllowed {
granted()
} else {
self.cameraPermissionAlert()
}
})
} else if status == .restricted {
self.cameraPermissionAlert()
}
} else {
print("Camera not available on this device")
}
}
func cameraPermissionAlert() {
let alert = UIAlertController(title: "Access to camera not available", message: "Please enable access to camera in order to use this feature", preferredStyle: .alert)
alert.addAction(UIAlertAction(title: "Settings", style: .default, handler: { (action) in
if let url = URL(string: UIApplicationOpenSettingsURLString) {
if UIApplication.shared.canOpenURL(url) {
UIApplication.shared.open(url, options: [:], completionHandler: nil)
}
}
}))
alert.addAction(UIAlertAction(title: "Cancel", style: .default, handler: nil))
if let top = UIApplication.topViewController() { // This is extension to UIApplication that finds top view controller and displays it
top.present(alert, animated: true, completion: nil)
}
}
For remote notifications you can use something like this:
Determine on iPhone if user has enabled push notifications
And for location services:
Check if location services are enabled
In both of these cases you can detect if this is disabled or not by user and present user with alert controller that has open settings functionality.

App crashes on Launch in Airplane Mode

I am currently using Ashley Mill's Reachability Class. If the application launches with network connectivity then I am able to toggle between connectivity availability without any issues and able to display a network connectivity Alert Controller properly. However if the application is launched when the app starts without internet connection/on airplane mode it abruptly crashes.
override func viewDidLoad()
{
super.viewDidLoad()
setUpReachability (nil)
}
func setUpReachability(hostName: String?)
{
do
{
let reachability = try hostName == nil ? Reachability.reachabilityForInternetConnection() : Reachability(hostname: hostName!)
self.reachability = reachability
try! self.reachability?.startNotifier()
}
catch ReachabilityError.FailedToCreateWithAddress(let address)
{
print("\(address)")
return
} catch {}
NSNotificationCenter.defaultCenter().addObserver(self, selector: #selector(ViewController.reachabilityChanged(_:)), name: ReachabilityChangedNotification, object: reachability)
}
func reachabilityChanged(notification: NSNotification)
{
let reachability = notification.object as! Reachability
if reachability.isReachable()
{
if reachability.isReachableViaWiFi()
{
connected = true
}
else
{
connected = true
}
}
else
{
let alert = UIAlertController( title: "No Network Connection Available", message:"Try Again", preferredStyle: .Alert)
alert.addAction(UIAlertAction( title: "Will Do!" , style: .Default) { _ in } )
presentViewController ( alert, animated: true ) {}
connected = false
}
}
What can be done to allow the iPhone application to launch and display an alert saying there is no network connection rather than abruptly crash?
Error Message:
fatal error: unexpectedly found nil while unwrapping an Optional value
But I would think that reachability changed would catch this in the else statement and pop the error message up?
Shouldn't the else in the reachability.isReachableViaWiFi() if statement be:connected = false ?
The error was that I was in fact trying to download data at the launch of the app instead of first allowing the initialization of the app to finish to then send a request to the server to access information.

How to stop uiactivityindicator when i connect to internet

i have one app which contains many map view. And i need to check internet connect is true or false. If false one uialert message will show and uiactivity Indicator will show ( will start).... its working fine..
But when i suddenly connect the internet , that uiactivity indicator in not stoping. Still getting run.
Here my code:
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
ActiviyuInc.hidden = true
showmethod()
}
func showmethod () {
if Reachability.isConnectedToNetwork() == false {
print("Internet connection FAILED")
let alert = UIAlertView(title: "No Internet Connection", message: "Make sure your device is connected to the internet.", delegate: nil, cancelButtonTitle: "OK")
alert.show()
if Reachability.isConnectedToNetwork() == false {
ActiviyuInc.hidden = false
ActiviyuInc.startAnimating()
}
else {
ActiviyuInc.hidden = true
ActiviyuInc.stopAnimating()
}
}
}
When my app in run, that time when i connect to internet , still my uiactivityIndicator is not stoping..
Help me out !!!
Try stopping Activity on main thread,
dispatch_async(dispatch_get_main_queue()) { () -> Void in
ActiviyuInc.hidden = true
ActiviyuInc.stopAnimating()
}
just do this.
if Reachability.isConnectedToNetwork() == false {
print("Internet connection FAILED")
let alert = UIAlertView(title: "No Internet Connection", message: "Make sure your device is connected to the internet.", delegate: nil, cancelButtonTitle: "OK")
alert.show()
ActiviyuInc.hidden = false
ActiviyuInc.startAnimating()
} else {
ActiviyuInc.hidden = true
ActiviyuInc.stopAnimating()
}

Present Alert on ViewController only once

I am having various ViewControllers in my app. On one of them I want a alert to be displayed on load of the VC once to the user.
I have followed the instructions to set a glob var under the import section:
var disalert:Bool = true
and in the function I got:
if disalert {
let actionSheetController: UIAlertController = UIAlertController(title: "How-to use Holiday List", message: "message here", preferredStyle: .Alert)
//Create and add the Cancel action
//Create and an option action
let nextAction: UIAlertAction = UIAlertAction(title: "OK", style: .Default) { action -> Void in
}
actionSheetController.addAction(nextAction)
//Add a text field
//Present the AlertController
self.presentViewController(actionSheetController, animated: true, completion: nil)
disalert = false
}
The alert is not presented whilst the app is open. When I restart the phone or quit the app completely its again there.
Thank you!
If I am reading your question properly, my suggestion would be to user NSUserDefaults to save a key when the user first opens the view. Then just use an IF statement to decide whether an alertView should be displayed.
Before showing the alert, wherever you want to show it, check the value against the "disalert" key in your userDefaults with this statement:
var disalert: Bool = NSUserDefaults.standardUserDefaults.boolForKey("disalert");
if disalert {
// The alert has already been shown so no need to show it again
}
else
{
// The alert hasn't been shown yet. Show it now and save in the userDefaults
// After showing the alert write this line of code
NSUserDefaults.standardUserDefaults.setBool(true, forKey: "disalert")
}
Adeel's code worked for me, with a slight improvement:
var disalert: Bool =
NSUserDefaults.standardUserDefaults().boolForKey("disalert");
if disalert {
// The alert has already been shown so no need to show it again
}
else
{
// The alert hasn't been shown yet. Show it now and save in the userDefaults
// After showing the alert write this line of code
NSUserDefaults.standardUserDefaults.setBool(true, forKey: "disalert")
}
NSUserDefaults cried for the following: NSUserDefaults.standardUserDefaults()

How to create a segue on condition [duplicate]

This question already has an answer here:
segue transition with condition storyboard
(1 answer)
Closed 7 years ago.
I have a login page backed up by Parse. I want to know how to create a segue only if the login has been confirmed through the Parse database, and then direct the user to a new View Controller.
This is the code for the login button:
#IBAction func logginginAction(sender: AnyObject) {
var username = self.usernameField.text
var password = self.passwordField.text
if (count(username.utf16) < 4 || count(password.utf16) < 5 ) {
var alert = UIAlertView(title: "Invalid", message: "Username/Password is too short!!", delegate: self, cancelButtonTitle: "OK")
alert.show()
}
else {
self.actInd.startAnimating()
PFUser.logInWithUsernameInBackground(username, password: password, block: { (user, error) ->
Void in
self.actInd.stopAnimating()
if ((user) != nil) {
}else {
var alert = UIAlertView(title: "Invalid", message: "Please recheck the information you just entered", delegate: self, cancelButtonTitle: "OK")
alert.show()
}
})
}
}
This is simple.
Connect your button to an IBAction, not directly to a segue.
Connect your segue from the view controller, not from the button. Give it a unique identifier.
In your IBAction method check the conditions you want to check, and if they are met, invoke your segue using performSegueWithIdentifier:sender:

Resources