I can't move items in viewDidAppear in Swift - ios

I'm having the issue where I have a UIView that displays no internet connection. I want it to dive out of the way when the view is loaded so as not to be seen. It should pop back up and go away when connections are either on and off..The notifier is working and if the connection goes on and off it will move or remove the banner. However when the view first loads it doesn't move the UIView out of the way.
override func viewWillAppear(animated: Bool) {
NSNotificationCenter.defaultCenter().addObserver(self, selector: #selector(self.actOnSpecialNotification(_:)), name: "ReachabilityChangedNotification", object: nil)
print("viewappeard")
self.unableBox.center.y -= view.bounds.height
}
func actOnSpecialNotification(note:NSNotification){
let reachability = note.object as! Reachability
if reachability.isReachable() {
self.unableBox.center.y -= view.bounds.height
print(self.unableBox.center.y)
print(view.bounds.height)
if reachability.isReachableViaWiFi() {
print("Reachable via WiFi")
} else {
print("Reachable via Cellular")
}
} else {
self.unableBox.center.y = view.bounds.height/2
print(self.unableBox.center.y)
print(view.bounds.height)
print("Network not reachable")
}
}

Related

How do i check the wifi switch in between my data uploading

I need an event or like an observer while switching between wifi networks or wifi to cellular and vice versa. Can anybody help me with it? I am uploading a video file and while uploading I am switching between wifi networks or auto-switch between cellular to wifi. So need an event for the same.
It is included in the example on the Reachability github page
//declare this property where it won't go out of scope relative to your listener
let reachability = try! Reachability()
//declare this inside of viewWillAppear
NotificationCenter.default.addObserver(self, selector: #selector(reachabilityChanged(note:)), name: .reachabilityChanged, object: reachability)
do{
try reachability.startNotifier()
}catch{
print("could not start reachability notifier")
}
And the method
#objc func reachabilityChanged(note: Notification) {
let reachability = note.object as! Reachability
switch reachability.connection {
case .wifi:
print("Reachable via WiFi")
case .cellular:
print("Reachable via Cellular")
case .unavailable:
print("Network not reachable")
}
}
To check whether the device is connected or not, you can use NWPathMonitor, like this:
import Network
struct ConnectivityMonitor {
static let monitor = NWPathMonitor()
static func setup() {
ConnectivityMonitor.monitor.pathUpdateHandler = { path in
//path.isExpensive tells you whether the user is using cellular data as opposed to wifi. "true" if cellular data.
if path.status == .satisfied {
//Connected
} else {
//Not connected
}
}
let queue = DispatchQueue(label: "Monitor")
ConnectivityMonitor.monitor.start(queue: queue)
}
}

How to call api after app comes to online from other screen

I am working on iOS application. I have to call api while user online and offline.
I have viewcontroller 1 class and there I am calling api.
override func viewDidLoad() {
super.viewDidLoad()
if let reachability = manager.sharedInstance.internetReachability {
NotificationCenter.default.addObserver( self, selector: #selector( self.reachabilityChanged),name: Notification.Name.reachabilityChanged, object: reachability )
}
}
#IBAction func callAPI(_ sender: Any) {
self.callApi()
}
func callApi() {
//call api
}
#objc private func reachabilityChanged( notification: NSNotification ) {
let reachability = notification.object as! Reachability
switch reachability.connection {
case .wifi:
self.callApi()
case .cellular:
self.callApi()
case .none:
case .unavailable:
}
}
The issue is here if I am in viewcontroller 2 class and app comes to online, The api is not getting trigger in Viewcontroller 1.
The requirement is, If user is offline and comes to online, user is in viewcontroller 2, I have to call that api in viewcontroller 1 without any action, Just by tracking internet is active and I have to call API.
Any suggestions?
The problem is if there is no instance of the view controller 1 existed at the time of connectivity changes, you have no chance to call the API.
If you have no reason having to keep the calling API inside the view controller 1 when connectivity changes, I suggest moving the observer to somewhere that can alive throughout your app's lifetime. The simplest place is in AppDelegate.
What I did,
if no internet then store data in database
make a function in appdelegate e.g callApi()
when app comes to online (internet on) reachabilityChanged( notification: NSNotification ) call, So my code looks like
#objc func reachabilityChanged(note: Notification) {
let reachability = note.object as! Reachability
switch reachability.connection {
case .wifi:
print("Reachable via WiFi")
appDel.UploadUserRecord() //callApi()
case .cellular:
print("Reachable via Cellular")
appDel.UploadUserRecord() //callApi()
case .unavailable:
print("Network not reachable")
case .none:
print("Network none")
}
}
I'm Used Reachability class globally

Question about how to run code the same on all screens in an app in Swift

I have written code to check the status of a network connection. I used the Reachability library.
let reachability = Reachability()!
reachability.whenReachable = { reachability in
if reachability.connection == .wifi {
print("Reachable via WiFi")
CustomActivityIndicator.shared.hide(uiView: self.view)
} else {
print("Reachable via Cellular")
CustomActivityIndicator.shared.hide(uiView: self.view)
}
}
reachability.whenUnreachable = { _ in
print("Not reachable")
CustomActivityIndicator.shared.show(uiView: self.view, labelText: "Not reachable", backgroundColor: self.color, textColor: .white, animated: false, duration: 0)
}
do {
try reachability.startNotifier()
} catch {
print("Unable to start notifier")
}
I also wrote code that notifies the user via the CustomActivityIndicator when the network is disconnected and hides the CustomActivityIndicator when reconnected.
Where should I put the code so that it works on all screens of the app?
The best approach is: create a base view controller and inherit all your view controllers from the BaseViewController and wrote the common code i.e Reachability in this context in that base class.

update the Viewcontroller based on Network Availblilty in swift

I am new to ios development, i have to check the internet network based on that i will show the view controllers, i used this code for test the network.
class Connectivity {
class func isConnectedToInternet() ->Bool {
return NetworkReachabilityManager()!.isReachable
}
}
if Connectivity.isConnectedToInternet() {
print("Yes! internet is available.")
// do some tasks..
}
else {
}
with this code i am getting network network status, my aim is when the application launch time if don't have network show the default page, if enable the network automatically it will show the main page please help me.
try this code
let reachability = Reachability()!
NotificationCenter.default.addObserver(self, selector: #selector(reachabilityChanged(note:)), name: .reachabilityChanged, object: reachability)
do{
try reachability.startNotifier()
}catch{
print("could not start reachability notifier")
}
#objc func reachabilityChanged(note: Notification) {
let reachability = note.object as! Reachability
switch reachability.connection {
case .wifi:
print("Reachable via WiFi")
case .cellular:
print("Reachable via Cellular")
case .none:
print("Network not reachable")
}
}

access reachability with enough time to return true state

i have a reachability class which is checked from within my VC code as below:
func setupReachability (hostName:String?, useClosures: Bool) {
let reachability = hostName == nil ? Reachability() : Reachability(hostname: hostName!)
self.reachability = reachability
try! self.reachability?.startNotifier()
if useClosures {
reachability?.whenReachable = { reachability in
DispatchQueue.main.async {
self.connected = true
print("Reachable....")
}
}
reachability?.whenUnreachable = { reachability in
DispatchQueue.main.async {
self.connected = false
print("Not Connected....")
}
}
} else {
NotificationCenter.default.addObserver(self, selector: Selector(("reachabilityChanged:")), name: ReachabilityChangedNotification, object: reachability)
}
}
this is initialised from within viewDidLoad:
setupReachability(hostName: nil, useClosures: true)
print(self.connected)
the problem i am having is that it always returns false and i need this to load with enough time that it returns true (if it is really connected) at this point. I'm struggling to figure out where to place my setupReachability function and initialise it so that it can be accessed from anywhere in the app and return its connected state. Ive tried placing this in a separate class but can't seem to get it working or access the connected state. Any tips on how to achieve this?

Resources