Connecting wifi without internet not recognised with NetworkReachabilityManager or Reachability - ios

When trying to check internet connectivity I have a problem.
When using alamofire NetworkReachabilityManager on a wifi with no internet like so:
import Alamofire
class Connectivity {
class func isConnectedToInternet() ->Bool {
return NetworkReachabilityManager()!.isReachable
}
}
This is the implementation:
if Connectivity.isConnectedToInternet() {
print("Yes! internet is available.")
} else {
print("No! internet is not available.")
}
I am getting: "Yes! internet is available." when there is no active internet connection (checked with Safari).
Tried also this one with Reachability:
import Reachability
class ReachabilityManager: NSObject {
var reachability: Reachability!
static let sharedInstance: NetworkManager = { return NetworkManager() }()
override init() {
super.init()
reachability = Reachability()!
NotificationCenter.default.addObserver(
self,
selector: #selector(networkStatusChanged(_:)),
name: .reachabilityChanged,
object: reachability
)
do {
try reachability.startNotifier()
} catch {
print("Unable to start notifier")
}
}
#objc func networkStatusChanged(_ notification: Notification) {
// Do something globally here!
}
static func stopNotifier() -> Void {
do {
try (NetworkManager.sharedInstance.reachability).startNotifier()
} catch {
print("Error stopping notifier")
}
}
static func isReachable(completed: #escaping (NetworkManager) -> Void) {
if (NetworkManager.sharedInstance.reachability).connection != .none {
completed(NetworkManager.sharedInstance)
}
}
static func isUnreachable(completed: #escaping (NetworkManager) -> Void) {
if (NetworkManager.sharedInstance.reachability).connection == .none {
completed(NetworkManager.sharedInstance)
}
}
static func isReachableViaWWAN(completed: #escaping (NetworkManager) -> Void) {
if (NetworkManager.sharedInstance.reachability).connection == .cellular {
completed(NetworkManager.sharedInstance)
}
}
static func isReachableViaWiFi(completed: #escaping (NetworkManager) -> Void) {
if (NetworkManager.sharedInstance.reachability).connection == .wifi {
completed(NetworkManager.sharedInstance)
}
}
}
The implementation is:
NetworkManager.isReachable { networkManagerInstance in
print("Network is available")
}
NetworkManager.isUnreachable { networkManagerInstance in
print("Network is Unavailable")
}
What am I doing wrong?

How did you check connection? did you try to reach any host something like below.
do {
Network.reachability = try Reachability(hostname: "www.google.com")
do {
try Network.reachability?.start()
} catch let error as Network.Error {
print(error)
} catch {
print(error)
}
} catch {
print(error)
}

Related

I want logout a user after 1 hour once they go offline if they come online withn that 1 hour it should stop

I tried saving my time in UserDefaults and adding 1 hour after once they go offline. I tried this too:
if isNetworkAvailable {
print(isNetworkAvailable)
}
else {
DispatchQueue.main.asyncAfter(deadline: .now() + 10.0, execute: {
self.logginout()
})
}
I'm checking my Reachibility through Reachibility pod I have written a network manager like this:
import UIKit
class NetworkManager: NSObject {
var reachability: Reachability!
// Create a singleton instance
static let sharedInstance: NetworkManager = { return NetworkManager() }()
override init() {
super.init()
// Initialise reachability
reachability = Reachability()!
// Register an observer for the network status
NotificationCenter.default.addObserver(
self,
selector: #selector(networkStatusChanged(_:)),
name: .reachabilityChanged,
object: reachability
)
do {
// Start the network status notifier
try reachability.startNotifier()
} catch {
print("Unable to start notifier")
}
}
#objc func networkStatusChanged(_ notification: Notification) {
// Do something globally here!
}
static func stopNotifier() -> Void {
do {
// Stop the network status notifier
try (NetworkManager.sharedInstance.reachability).startNotifier()
} catch {
print("Error stopping notifier")
}
}
// Network is reachable
static func isReachable(completed: #escaping (NetworkManager) -> Void) {
if (NetworkManager.sharedInstance.reachability).connection != .none {
completed(NetworkManager.sharedInstance)
}
}
// Network is unreachable
static func isUnreachable(completed: #escaping (NetworkManager) -> Void) {
if (NetworkManager.sharedInstance.reachability).connection == .none {
completed(NetworkManager.sharedInstance)
}
}
// Network is reachable via WWAN/Cellular
static func isReachableViaWWAN(completed: #escaping (NetworkManager) -> Void) {
if (NetworkManager.sharedInstance.reachability).connection == .cellular {
completed(NetworkManager.sharedInstance)
}
}
// Network is reachable via WiFi
static func isReachableViaWiFi(completed: #escaping (NetworkManager) -> Void) {
if (NetworkManager.sharedInstance.reachability).connection == .wifi {
completed(NetworkManager.sharedInstance)
}
}
}
And in delegate I'm checking it like this:
network.reachability.whenUnreachable = { unreach in
isNetworkAvailable = false
let banner = NotificationBanner(title: "Your offline", subtitle: "Please Connect to internet", style: .danger)
banner.onSwipeUp = {
banner.dismiss()
}
print(time)
banner.show()
}
Is there a way to achieve this? I have written this block inside didLaunchWithOptions.

How can we use Alamofire NetworkReachabilityManager in a singleton?

How to solve this issue in swift. I have to check the network connection. If the internet is not connected to the device I have to show this offlineViewController. if it is connected then it shows Normal screen.
I am using this class to control network change -> Reachability.swift :
import Foundation
import SystemConfiguration
class Reachability {
var hostname: String?
var isRunning = false
var isReachableOnWWAN: Bool
var reachability: SCNetworkReachability?
var reachabilityFlags = SCNetworkReachabilityFlags()
let reachabilitySerialQueue = DispatchQueue(label: "ReachabilityQueue")
init?(hostname: String) throws {
guard let reachability = SCNetworkReachabilityCreateWithName(nil, hostname) else {
throw Network.Error.failedToCreateWith(hostname)
}
self.reachability = reachability
self.hostname = hostname
isReachableOnWWAN = true
}
init?() throws {
var zeroAddress = sockaddr_in()
zeroAddress.sin_len = UInt8(MemoryLayout<sockaddr_in>.size)
zeroAddress.sin_family = sa_family_t(AF_INET)
guard let reachability = withUnsafePointer(to: &zeroAddress, {
$0.withMemoryRebound(to: sockaddr.self, capacity: 1) {
SCNetworkReachabilityCreateWithAddress(nil, $0)
}}) else {
throw Network.Error.failedToInitializeWith(zeroAddress)
}
self.reachability = reachability
isReachableOnWWAN = true
}
var status: Network.Status {
return !isConnectedToNetwork ? .unreachable :
isReachableViaWiFi ? .wifi :
isRunningOnDevice ? .wwan : .unreachable
}
var isRunningOnDevice: Bool = {
#if (arch(i386) || arch(x86_64)) && os(iOS)
return false
#else
return true
#endif
}()
deinit { stop() }
}
extension Reachability {
func start() throws {
guard let reachability = reachability, !isRunning else { return }
var context = SCNetworkReachabilityContext(version: 0, info: nil, retain: nil, release: nil, copyDescription: nil)
context.info = Unmanaged<Reachability>.passUnretained(self).toOpaque()
guard SCNetworkReachabilitySetCallback(reachability, callout, &context) else { stop()
throw Network.Error.failedToSetCallout
}
guard SCNetworkReachabilitySetDispatchQueue(reachability, reachabilitySerialQueue) else { stop()
throw Network.Error.failedToSetDispatchQueue
}
reachabilitySerialQueue.async { self.flagsChanged() }
isRunning = true
}
func stop() {
defer { isRunning = false }
guard let reachability = reachability else { return }
SCNetworkReachabilitySetCallback(reachability, nil, nil)
SCNetworkReachabilitySetDispatchQueue(reachability, nil)
self.reachability = nil
}
var isConnectedToNetwork: Bool {
return isReachable &&
!isConnectionRequiredAndTransientConnection &&
!(isRunningOnDevice && isWWAN && !isReachableOnWWAN)
}
var isReachableViaWiFi: Bool {
return isReachable && isRunningOnDevice && !isWWAN
}
/// Flags that indicate the reachability of a network node name or address, including whether a connection is required, and whether some user intervention might be required when establishing a connection.
var flags: SCNetworkReachabilityFlags? {
guard let reachability = reachability else { return nil }
var flags = SCNetworkReachabilityFlags()
return withUnsafeMutablePointer(to: &flags) {
SCNetworkReachabilityGetFlags(reachability, UnsafeMutablePointer($0))
} ? flags : nil
}
/// compares the current flags with the previous flags and if changed posts a flagsChanged notification
func flagsChanged() {
guard let flags = flags, flags != reachabilityFlags else { return }
reachabilityFlags = flags
NotificationCenter.default.post(name: .flagsChanged, object: self)
}
/// The specified node name or address can be reached via a transient connection, such as PPP.
var transientConnection: Bool { return flags?.contains(.transientConnection) == true }
/// The specified node name or address can be reached using the current network configuration.
var isReachable: Bool { return flags?.contains(.reachable) == true }
/// The specified node name or address can be reached using the current network configuration, but a connection must first be established. If this flag is set, the kSCNetworkReachabilityFlagsConnectionOnTraffic flag, kSCNetworkReachabilityFlagsConnectionOnDemand flag, or kSCNetworkReachabilityFlagsIsWWAN flag is also typically set to indicate the type of connection required. If the user must manually make the connection, the kSCNetworkReachabilityFlagsInterventionRequired flag is also set.
var connectionRequired: Bool { return flags?.contains(.connectionRequired) == true }
/// The specified node name or address can be reached using the current network configuration, but a connection must first be established. Any traffic directed to the specified name or address will initiate the connection.
var connectionOnTraffic: Bool { return flags?.contains(.connectionOnTraffic) == true }
/// The specified node name or address can be reached using the current network configuration, but a connection must first be established.
var interventionRequired: Bool { return flags?.contains(.interventionRequired) == true }
/// The specified node name or address can be reached using the current network configuration, but a connection must first be established. The connection will be established "On Demand" by the CFSocketStream programming interface (see CFStream Socket Additions for information on this). Other functions will not establish the connection.
var connectionOnDemand: Bool { return flags?.contains(.connectionOnDemand) == true }
/// The specified node name or address is one that is associated with a network interface on the current system.
var isLocalAddress: Bool { return flags?.contains(.isLocalAddress) == true }
/// Network traffic to the specified node name or address will not go through a gateway, but is routed directly to one of the interfaces in the system.
var isDirect: Bool { return flags?.contains(.isDirect) == true }
/// The specified node name or address can be reached via a cellular connection, such as EDGE or GPRS.
var isWWAN: Bool { return flags?.contains(.isWWAN) == true }
/// The specified node name or address can be reached using the current network configuration, but a connection must first be established. If this flag is set
/// The specified node name or address can be reached via a transient connection, such as PPP.
var isConnectionRequiredAndTransientConnection: Bool {
return (flags?.intersection([.connectionRequired, .transientConnection]) == [.connectionRequired, .transientConnection]) == true
}
}
func callout(reachability: SCNetworkReachability, flags: SCNetworkReachabilityFlags, info: UnsafeMutableRawPointer?) {
guard let info = info else { return }
DispatchQueue.main.async {
Unmanaged<Reachability>.fromOpaque(info).takeUnretainedValue().flagsChanged()
}
}
extension Notification.Name {
static let flagsChanged = Notification.Name("FlagsChanged")
}
struct Network {
static var reachability: Reachability?
enum Status: String, CustomStringConvertible {
case unreachable, wifi, wwan
var description: String { return rawValue }
}
enum Error: Swift.Error {
case failedToSetCallout
case failedToSetDispatchQueue
case failedToCreateWith(String)
case failedToInitializeWith(sockaddr_in)
}
}
And I add this code to AppDelegate.swift :
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
do {
Network.reachability = try Reachability(hostname: "www.google.com")
do {
try Network.reachability?.start()
} catch let error as Network.Error {
print(error)
} catch {
print(error)
}
} catch {
print(error)
}
return true
}
And I add this code to viewDidLoad() in the class I want to control the network:
NotificationCenter.default.addObserver(self, selector: #selector(statusManager), name: .flagsChanged, object: Network.reachability)
You can make checks in this function when the network changes.
func statusManager(_ notification: NSNotification) {
guard let status = Network.reachability?.status else { return }
if status == .wifi || status == .wwan {
offlineViewController.dismiss(animated: true, completion: nil)
}
print("Status:", status)
print("HostName:", Network.reachability?.hostname ?? "nil")
print("Reachable:", Network.reachability?.isReachable ?? "nil")
print("Wifi:", Network.reachability?.isReachableViaWiFi ?? "nil")
}
import Alamofire
struct Connectivity {
static let sharedInstance = NetworkReachabilityManager()!
static var isConnectedToInternet:Bool {
return self.sharedInstance.isReachable
}
}
Usage :
if Connectivity.isConnectedToInternet {
return true
} else {
self.setErrorMessage(message: "No internet connection", view: view)
return false
}
NetworkManager Class
class NetworkManager {
//shared instance
static let shared = NetworkManager()
let reachabilityManager = Alamofire.NetworkReachabilityManager(host: "www.google.com")
let offlineViewController = OfflineViewController()
let currentViewController: UIViewController?
func startNetworkReachabilityObserver() {
reachabilityManager?.listener = { status in
switch status {
case .notReachable:
offlineViewController.dismiss(animated: false, completion: nil)
currentViewController.present(offlineViewController, animated: true, completion: nil)
print("The network is not reachable")
case .unknown :
print("It is unknown whether the network is reachable")
case .reachable(.ethernetOrWiFi):
offlineViewController.dismiss(animated: true, completion: nil)
print("The network is reachable over the WiFi connection")
case .reachable(.wwan):
offlineViewController.dismiss(animated: true, completion: nil)
print("The network is reachable over the WWAN connection")
}
}
// start listening
reachabilityManager?.startListening()
}
}
Start Network Reachability Observer
#UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
// add network reachability observer on app start
NetworkManager.shared.startNetworkReachabilityObserver()
return true
}
}
On each ViewController need to detect network
override func viewDidLoad() {
super.viewDidLoad()
NetworkManager.shared.currentViewController = self
}
Here I use Alamofire version 5.2
NetworkReachabilityManager handler
import Alamofire
class NetworkReachability{
let sceneDelegate: SceneDelegate = {
let scene = UIApplication.shared.connectedScenes.first
let sd = scene?.delegate as? SceneDelegate
return sd ?? SceneDelegate()
}()
var manager:NetworkReachabilityManager?
init(
manager:NetworkReachabilityManager? = NetworkReachabilityManager()
) {
self.manager = manager
self.managerHandler()
}
private func managerHandler(){
self.manager?.startListening(onUpdatePerforming: { (status) in
switch status{
case .unknown:
self.sceneDelegate.showOfflineViewController()
case .notReachable:
print("Not Reachable")
self.sceneDelegate.showOfflineViewController()
case .reachable(.cellular),.reachable(.ethernetOrWiFi):
print("Reachable")
self.sceneDelegate.hideOfflineViewController()
}
})
}
}
SceneDelegate
import UIKit
class SceneDelegate: UIResponder, UIWindowSceneDelegate {
var window: UIWindow?
var offlineWindow:UIWindow?
private var networkReachability:NetworkReachability?
func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {
guard let _ = (scene as? UIWindowScene) else { return }
self.networkReachability = NetworkReachability()
}
}
extension SceneDelegate{
func showOfflineViewController(){
guard let offlineWindow = window?.windowScene else { return }
let offlineViewController = OfflineViewController
self.offlineWindow = UIWindow(windowScene: offlineWindow)
self.offlineWindow?.rootViewController = offlineViewController
self.offlineWindow?.makeKeyAndVisible()
}
func hideOfflineViewController(){
UIView.animate(withDuration: 0.3) {
self.offlineWindow?.alpha = 0
} completion: { (_) in
self.offlineWindow?.isHidden = true
self.offlineWindow = nil
}
}
}

Delegated functions not working outside of UIViewController

I'm using the Startscream Websocket framework. Everything works fine as long as I keep all of the code in a UIViewController as seen here. But as soon as a create a wrapper class for Startscream all of the delegated functions stop working. Also my local websocket server is not getting a connection.
How can I get the code working inside a wrapper class?
MyService.swift:
import Starscream
public class MyService: WebSocketDelegate {
var socket = WebSocket(url: URL(string: "ws://localhost:3900/websocket")!)
func connect() {
socket.delegate = self
socket.connect()
print("Connecting")
}
// MARK: Websocket Delegate Methods.
public func websocketDidConnect(socket: WebSocket) {
print("websocket is connected")
}
public func websocketDidDisconnect(socket: WebSocket, error: NSError?) {
if let e = error {
print("websocket is disconnected: \(e.localizedDescription)")
} else {
print("websocket disconnected")
}
}
public func websocketDidReceiveMessage(socket: WebSocket, text: String) {
print("Received text: \(text)")
}
public func websocketDidReceiveData(socket: WebSocket, data: Data) {
print("Received data: \(data.count)")
}
// MARK: Write Text Action
#IBAction func writeText(_ sender: UIBarButtonItem) {
socket.write(string: "hello there!")
}
// MARK: Disconnect Action
#IBAction func disconnect(_ sender: UIBarButtonItem) {
if socket.isConnected {
sender.title = "Connect"
socket.disconnect()
} else {
sender.title = "Disconnect"
socket.connect()
}
}
}
ViewController.swift:
import UIKit
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
let service = MyService()
service.connect()
}
}
The reference to Service in ViewController was not stored anywhere so as soon as the function was run it was cleaned up. This is how I fixed it:
class ViewController: UIViewController {
var service = MyService()
override func viewDidLoad() {
super.viewDidLoad()
service.connect()
}
...
I'm not sure what is wrong with your code, it can be an endpoint issue, or WS is not allocated somehow. I have same code with Starscream working in Swift 3, here is the main part of my class.
class ConnectionManager {
private var savedSocket: WebSocket?
fileprivate var socket: WebSocket {
if let saved = savedSocket {
return saved
}
let wsURL = URL(string: UserDefaultsManager.wsURLString)!
savedSocket = WebSocket(url: wsURL)
return savedSocket!
}
func startSession() {
if (socket.isConnected) { return }
socket.headers = headers
socket.delegate = self
socket.connect()
}
func endSession() {
if (socket.isConnected) {
socket.disconnect()
}
}
}
extension ConnectionManager: WebSocketDelegate {
func websocketDidConnect(socket: WebSocket) {
}
func websocketDidDisconnect(socket: WebSocket, error: NSError?){
if let e = error {
log.error("websocket is disconnected with ERROR: \(e.localizedDescription)")
} else {
log.error("websocket disconnected")
}
}
func websocketDidReceiveMessage(socket: WebSocket, text: String){
}
func websocketDidReceiveData(socket: WebSocket, data: Data){
}
}
My code is not a best practise for sure, but it works without any problem. Try to use my version, maybe it will work for you.

How to change protocol to typealias or closure

In my code I do not want to use protocol I want use closures but I couldn't get it done because I am new on Swift.
Here is the example of class
class SplashPresenterImp: SplashPresenter, OnFinishedListener {
private var interactor: SplashInteractor
private var splashNetworkProtocol: SplashNetworkProtocol
init() {
interactor = SplashNetworking()
}
func startDownloadConfigs(splashNetworkProtocol: SplashNetworkProtocol){
if interactor != nil {
interactor.loadConfigs(listener: self)
self.splashNetworkProtocol = splashNetworkProtocol
}
}
func startDownloadDictionary(splashNetworkProtocol: SplashNetworkProtocol) {
if interactor != nil {
interactor.loadDictionary(listener: self)
self.splashNetworkProtocol = splashNetworkProtocol
}
}
func onFinishedGetDictionary(dictionary: Dictionary) {
//save dictionary
if splashNetworkProtocol != nil {
splashNetworkProtocol.onSuccess()
}
}
func onFinishedGetConfigs(config: Config) {
//save configs
if splashNetworkProtocol != nil {
splashNetworkProtocol.onSuccess()
}
}
func onFinishedWithError(error: AMError) {
if splashNetworkProtocol != nil {
splashNetworkProtocol.onError(error: error)()
}
}
}
Here is the protocol
protocol SplashNetworkProtocol: class {
func onSuccess()
func onError(error: AMError)
}
What I want to have on my viewcontroller to have closure when downloadConfig is complete to start downloadDictionary.
I know how it handle on Java here is the code
mPresenter.startDownloadConfigs(new SplashNetworkProtocol() {
#Override
public void onSuccess() {
downloadDictionary();
}
#Override
public void onError(final AMError error) {
}
});
I want to have same result in swift. Is anyone can give me advice how to do this?
More clearly I want get rid of SplashNetworkProtocol and use only closure.
swift result should be this
mPresenter.startDownloadConfigs(onSuccess: {} onError{}
Should be as simple as:
func startDownloadDictionary(onSuccess: () -> Void, onError: () -> Void)
But even better to use a single closure that handles both success and error. For instance, with an error as an optional parameter:
func startDownloadDictionary(onCompletion: (Error?) -> Void)
A full example:
func someOtherFunc() {
startDownloadDictionary(onCompletion: {(error) -> Void in
if let error = error {
print(error.localizedDescription)
}
//no error
})
}
func startDownloadDictionary(onCompletion: (Error?) -> Void)
{
//dostuff
var error: Error?
// if error happens, create it
onCompletion(error)
}
If you need help with Swift closure syntax, this is a good resource:
http://fuckingswiftblocksyntax.com/

xcode 8.3 error with generics

protocol PubSubEvent {
associatedtype EventResult
static func eventName() -> String
func event() -> EventResult
func send()
}
class BGEventBus: EventBus {
static let sharedInstance = BGEventBus()
init() {
super.init(queue: OperationQueue())
}
}
class BGEventBusEvent: PubSubEvent {
typealias EventResult = BGEventBusEvent
class func eventName() -> String {
return String(describing: self)
}
func send() {
BGEventBus.sharedInstance.send(event: self)
}
func event() -> BGEventBusEvent.EventResult {
return self
}
}
class BGDidLoginEvent: BGEventBusEvent {
typealias EventResult = BGDidLoginEvent
var password: String?
var facebookToken: String?
init(password: String? = nil, facebookToken: String? = nil) {
self.password = password
self.facebookToken = facebookToken
}
}
class EventBus {
var queue: OperationQueue
init(queue: OperationQueue) {
self.queue = queue
}
func send(event: AnyObject) {
}
func handleEvent<T: PubSubEvent>(target:EventBusObservable, handleBlock: ((T.EventResult) -> Void)!) where T.EventResult == T {
}
}
class EventBusObserver {
var objectProtocol: NSObjectProtocol?
func addObserver(forName name: NSNotification.Name?, object obj: Any?, queue: OperationQueue?, using block: #escaping (Notification) -> Swift.Void) {
self.objectProtocol = NotificationCenter.default.addObserver(forName: name, object: obj, queue: queue, using: block)
}
deinit {
if let obj = self.objectProtocol {
NotificationCenter.default.removeObserver(obj)
}
self.objectProtocol = nil
print("deinit observer!")
}
}
protocol EventBusObservable {
func handleBGEvent<T: PubSubEvent>(handleBlock: ((T.EventResult) -> Void)!) where T.EventResult == T
}
extension EventBusObservable {
func handleBGEvent<T>(handleBlock: ((T) -> Void)!) where T : PubSubEvent, T.EventResult == T {
BGEventBus.sharedInstance.handleEvent(target: self, handleBlock:handleBlock)
}
}
class sample: EventBusObservable {
func test() {
self.handleBGEvent { (event: BGDidLoginEvent) in
}
}
}
Hello guys I updated the Xcode to 8.3 and now I'm getting some errors like this:
Cannot convert value of type '(BGDidLoginEvent) -> ()' to expected argument type '((_) -> Void)!''
can anybody help me?
here the sample file https://drive.google.com/open?id=0B1zPtsTG7crPQncxYnEyWTBpSXM
I think you have to write the generic requirement exactly the same way every time. So, in EventBus:
class EventBus {
// ...
func handleEvent<T>(target:EventBusObservable, handleBlock: ((T) -> Void)!) where T : PubSubEvent, T.EventResult == T {
}
}
In EventBusObservable:
protocol EventBusObservable {
func handleBGEvent<T>(handleBlock: ((T) -> Void)!) where T : PubSubEvent, T.EventResult == T
}
In the EventBusObservable extension:
extension EventBusObservable {
func handleBGEvent<T>(handleBlock: ((T) -> Void)!) where T : PubSubEvent, T.EventResult == T {
BGEventBus.sharedInstance.handleEvent(target: self, handleBlock: handleBlock)
}
}
That compiles. Finally we are left with your class sample. This one wasn't so easy; I found I had to declare event as a BGEventBusEvent:
class sample: EventBusObservable {
func test() {
self.handleBGEvent {
(event:BGEventBusEvent) in
}
}
}

Resources