get Users up

This commit is contained in:
2015-09-13 23:37:18 +02:00
parent baba7de448
commit 79628c8824
56 changed files with 4513 additions and 36 deletions
+21
View File
@@ -0,0 +1,21 @@
/*
Copyright (c) 2014, Ashley Mills
All rights reserved.
Redistribution and use in source, with or without modification, is permitted provided that the following condition is met:
1. Redistributions of source code must retain the above copyright notice, this
list of conditions and the following disclaimer.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.
*/
+86
View File
@@ -0,0 +1,86 @@
# Reachability.swift
Replacement for Apple's Reachability re-written in Swift with closures
Inspired by https://github.com/tonymillion/Reachability
**NOTES:**
- As of Swift 1.2, you cannot convert Swift closures into C-function pointers, meaning we can't set an `SCNetworkReachabilityCallBack`. To get around this, this reachability replacement uses a `dispatch_source` firing at 1/2 second intervals.
- If an application has the privacy option “Use cellular data” turned off, the Reachability class still reports isReachable() to be true. There is currently no (non-private) API to detect this. If you need this feature, please raise file a [bug report](https://bugreport.apple.com) with Apple to get this fixed. See devforums thread for details: https://devforums.apple.com/message/1059332#1059332
## Installation
### CocoaPods
[CocoaPods][] is a dependency manager for Cocoa projects. To install Reachability.swift with CocoaPods:
1. Make sure CocoaPods is [installed][CocoaPods Installation].
2. Update your Podfile to include the following:
``` ruby
use_frameworks!
pod 'ReachabilitySwift', git: 'https://github.com/ashleymills/Reachability.swift'
```
3. Run `pod install`.
[CocoaPods]: https://cocoapods.org
[CocoaPods Installation]: https://guides.cocoapods.org/using/getting-started.html#getting-started
### Manual
Just drop the **Reachability.swift** file into your project. That's it!
## Example - closures
let reachability = Reachability.reachabilityForInternetConnection()
reachability.whenReachable = { reachability in
if reachability.isReachableViaWiFi() {
println("Reachable via WiFi")
} else {
println("Reachable via Cellular")
}
}
reachability.whenUnreachable = { reachability in
println("Not reachable")
}
reachability.startNotifier()
## Example - notifications
let reachability = Reachability.reachabilityForInternetConnection()
NSNotificationCenter.defaultCenter().addObserver(self, selector: "reachabilityChanged:", name: ReachabilityChangedNotification, object: reachability)
reachability.startNotifier()
and
func reachabilityChanged(note: NSNotification) {
let reachability = note.object as! Reachability
if reachability.isReachable() {
if reachability.isReachableViaWiFi() {
println("Reachable via WiFi")
} else {
println("Reachable via Cellular")
}
} else {
println("Not reachable")
}
}
## Want to help?
Got a bug fix, or a new feature? Create a pull request and go for it!
## Let me know!
If you use **Reachability.swift**, please let me know about your app and I'll put a link [here…](https://github.com/ashleymills/Reachability.swift/wiki/Apps-using-Reachability.swift) and tell your friends!
Cheers,
Ash
+373
View File
@@ -0,0 +1,373 @@
/*
Copyright (c) 2014, Ashley Mills
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice, this
list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.
*/
import SystemConfiguration
import Foundation
public let ReachabilityChangedNotification = "ReachabilityChangedNotification"
public class Reachability: NSObject, Printable {
public typealias NetworkReachable = (Reachability) -> ()
public typealias NetworkUnreachable = (Reachability) -> ()
public enum NetworkStatus: Printable {
case NotReachable, ReachableViaWiFi, ReachableViaWWAN
public var description: String {
switch self {
case .ReachableViaWWAN:
return "Cellular"
case .ReachableViaWiFi:
return "WiFi"
case .NotReachable:
return "No Connection"
}
}
}
// MARK: - *** Public properties ***
public var whenReachable: NetworkReachable?
public var whenUnreachable: NetworkUnreachable?
public var reachableOnWWAN: Bool
public var notificationCenter = NSNotificationCenter.defaultCenter()
public var currentReachabilityStatus: NetworkStatus {
if isReachable() {
if isReachableViaWiFi() {
return .ReachableViaWiFi
}
if isRunningOnDevice {
return .ReachableViaWWAN
}
}
return .NotReachable
}
public var currentReachabilityString: String {
return "\(currentReachabilityStatus)"
}
// MARK: - *** Initialisation methods ***
public required init(reachabilityRef: SCNetworkReachability) {
reachableOnWWAN = true
self.reachabilityRef = reachabilityRef
}
public convenience init(hostname: String) {
let ref = SCNetworkReachabilityCreateWithName(nil, (hostname as NSString).UTF8String).takeRetainedValue()
self.init(reachabilityRef: ref)
}
public class func reachabilityForInternetConnection() -> Reachability {
var zeroAddress = sockaddr_in(sin_len: __uint8_t(0), sin_family: sa_family_t(0), sin_port: in_port_t(0), sin_addr: in_addr(s_addr: 0), sin_zero: (0, 0, 0, 0, 0, 0, 0, 0))
zeroAddress.sin_len = UInt8(sizeofValue(zeroAddress))
zeroAddress.sin_family = sa_family_t(AF_INET)
let ref = withUnsafePointer(&zeroAddress) {
SCNetworkReachabilityCreateWithAddress(kCFAllocatorDefault, UnsafePointer($0)).takeRetainedValue()
}
return Reachability(reachabilityRef: ref)
}
public class func reachabilityForLocalWiFi() -> Reachability {
var localWifiAddress: sockaddr_in = sockaddr_in(sin_len: __uint8_t(0), sin_family: sa_family_t(0), sin_port: in_port_t(0), sin_addr: in_addr(s_addr: 0), sin_zero: (0, 0, 0, 0, 0, 0, 0, 0))
localWifiAddress.sin_len = UInt8(sizeofValue(localWifiAddress))
localWifiAddress.sin_family = sa_family_t(AF_INET)
// IN_LINKLOCALNETNUM is defined in <netinet/in.h> as 169.254.0.0
let address: Int64 = 0xA9FE0000
localWifiAddress.sin_addr.s_addr = in_addr_t(address.bigEndian)
let ref = withUnsafePointer(&localWifiAddress) {
SCNetworkReachabilityCreateWithAddress(kCFAllocatorDefault, UnsafePointer($0)).takeRetainedValue()
}
return Reachability(reachabilityRef: ref)
}
// MARK: - *** Notifier methods ***
public func startNotifier() -> Bool {
reachabilityObject = self
let reachability = self.reachabilityRef!
previousReachabilityFlags = reachabilityFlags
if let timer = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, 0, 0, timer_queue) {
dispatch_source_set_timer(timer, dispatch_walltime(nil, 0), 500 * NSEC_PER_MSEC, 100 * NSEC_PER_MSEC)
dispatch_source_set_event_handler(timer, { [unowned self] in
self.timerFired()
})
dispatch_timer = timer
dispatch_resume(timer)
return true
} else {
return false
}
}
public func stopNotifier() {
reachabilityObject = nil
if let timer = dispatch_timer {
dispatch_source_cancel(timer)
dispatch_timer = nil
}
}
// MARK: - *** Connection test methods ***
public func isReachable() -> Bool {
return isReachableWithTest({ (flags: SCNetworkReachabilityFlags) -> (Bool) in
return self.isReachableWithFlags(flags)
})
}
public func isReachableViaWWAN() -> Bool {
if isRunningOnDevice {
return isReachableWithTest() { flags -> Bool in
// Check we're REACHABLE
if self.isReachable(flags) {
// Now, check we're on WWAN
if self.isOnWWAN(flags) {
return true
}
}
return false
}
}
return false
}
public func isReachableViaWiFi() -> Bool {
return isReachableWithTest() { flags -> Bool in
// Check we're reachable
if self.isReachable(flags) {
if self.isRunningOnDevice {
// Check we're NOT on WWAN
if self.isOnWWAN(flags) {
return false
}
}
return true
}
return false
}
}
// MARK: - *** Private methods ***
private var isRunningOnDevice: Bool = {
#if (arch(i386) || arch(x86_64)) && os(iOS)
return false
#else
return true
#endif
}()
private var reachabilityRef: SCNetworkReachability?
private var reachabilityObject: AnyObject?
private var dispatch_timer: dispatch_source_t?
private lazy var timer_queue: dispatch_queue_t = {
return dispatch_queue_create("uk.co.joylordsystems.reachability_timer_queue", nil)
}()
private var previousReachabilityFlags: SCNetworkReachabilityFlags?
func timerFired() {
let currentReachabilityFlags = reachabilityFlags
if let _previousReachabilityFlags = previousReachabilityFlags {
if currentReachabilityFlags != previousReachabilityFlags {
dispatch_async(dispatch_get_main_queue(), { [unowned self] in
self.reachabilityChanged(currentReachabilityFlags)
self.previousReachabilityFlags = currentReachabilityFlags
})
}
}
}
private func reachabilityChanged(flags: SCNetworkReachabilityFlags) {
if isReachableWithFlags(flags) {
if let block = whenReachable {
block(self)
}
} else {
if let block = whenUnreachable {
block(self)
}
}
notificationCenter.postNotificationName(ReachabilityChangedNotification, object:self)
}
private func isReachableWithFlags(flags: SCNetworkReachabilityFlags) -> Bool {
let reachable = isReachable(flags)
if !reachable {
return false
}
if isConnectionRequiredOrTransient(flags) {
return false
}
if isRunningOnDevice {
if isOnWWAN(flags) && !reachableOnWWAN {
// We don't want to connect when on 3G.
return false
}
}
return true
}
private func isReachableWithTest(test: (SCNetworkReachabilityFlags) -> (Bool)) -> Bool {
var flags: SCNetworkReachabilityFlags = 0
let gotFlags = SCNetworkReachabilityGetFlags(reachabilityRef, &flags) != 0
if gotFlags {
return test(flags)
}
return false
}
// WWAN may be available, but not active until a connection has been established.
// WiFi may require a connection for VPN on Demand.
private func isConnectionRequired() -> Bool {
return connectionRequired()
}
private func connectionRequired() -> Bool {
return isReachableWithTest({ (flags: SCNetworkReachabilityFlags) -> (Bool) in
return self.isConnectionRequired(flags)
})
}
// Dynamic, on demand connection?
private func isConnectionOnDemand() -> Bool {
return isReachableWithTest({ (flags: SCNetworkReachabilityFlags) -> (Bool) in
return self.isConnectionRequired(flags) && self.isConnectionOnTrafficOrDemand(flags)
})
}
// Is user intervention required?
private func isInterventionRequired() -> Bool {
return isReachableWithTest({ (flags: SCNetworkReachabilityFlags) -> (Bool) in
return self.isConnectionRequired(flags) && self.isInterventionRequired(flags)
})
}
private func isOnWWAN(flags: SCNetworkReachabilityFlags) -> Bool {
#if os(iOS)
return flags & SCNetworkReachabilityFlags(kSCNetworkReachabilityFlagsIsWWAN) != 0
#else
return false
#endif
}
private func isReachable(flags: SCNetworkReachabilityFlags) -> Bool {
return flags & SCNetworkReachabilityFlags(kSCNetworkReachabilityFlagsReachable) != 0
}
private func isConnectionRequired(flags: SCNetworkReachabilityFlags) -> Bool {
return flags & SCNetworkReachabilityFlags(kSCNetworkReachabilityFlagsConnectionRequired) != 0
}
private func isInterventionRequired(flags: SCNetworkReachabilityFlags) -> Bool {
return flags & SCNetworkReachabilityFlags(kSCNetworkReachabilityFlagsInterventionRequired) != 0
}
private func isConnectionOnTraffic(flags: SCNetworkReachabilityFlags) -> Bool {
return flags & SCNetworkReachabilityFlags(kSCNetworkReachabilityFlagsConnectionOnTraffic) != 0
}
private func isConnectionOnDemand(flags: SCNetworkReachabilityFlags) -> Bool {
return flags & SCNetworkReachabilityFlags(kSCNetworkReachabilityFlagsConnectionOnDemand) != 0
}
func isConnectionOnTrafficOrDemand(flags: SCNetworkReachabilityFlags) -> Bool {
return flags & SCNetworkReachabilityFlags(kSCNetworkReachabilityFlagsConnectionOnTraffic | kSCNetworkReachabilityFlagsConnectionOnDemand) != 0
}
private func isTransientConnection(flags: SCNetworkReachabilityFlags) -> Bool {
return flags & SCNetworkReachabilityFlags(kSCNetworkReachabilityFlagsTransientConnection) != 0
}
private func isLocalAddress(flags: SCNetworkReachabilityFlags) -> Bool {
return flags & SCNetworkReachabilityFlags(kSCNetworkReachabilityFlagsIsLocalAddress) != 0
}
private func isDirect(flags: SCNetworkReachabilityFlags) -> Bool {
return flags & SCNetworkReachabilityFlags(kSCNetworkReachabilityFlagsIsDirect) != 0
}
private func isConnectionRequiredOrTransient(flags: SCNetworkReachabilityFlags) -> Bool {
let testcase = SCNetworkReachabilityFlags(kSCNetworkReachabilityFlagsConnectionRequired | kSCNetworkReachabilityFlagsTransientConnection)
return flags & testcase == testcase
}
private var reachabilityFlags: SCNetworkReachabilityFlags {
var flags: SCNetworkReachabilityFlags = 0
let gotFlags = SCNetworkReachabilityGetFlags(reachabilityRef, &flags) != 0
if gotFlags {
return flags
}
return 0
}
override public var description: String {
var W: String
if isRunningOnDevice {
W = isOnWWAN(reachabilityFlags) ? "W" : "-"
} else {
W = "X"
}
let R = isReachable(reachabilityFlags) ? "R" : "-"
let c = isConnectionRequired(reachabilityFlags) ? "c" : "-"
let t = isTransientConnection(reachabilityFlags) ? "t" : "-"
let i = isInterventionRequired(reachabilityFlags) ? "i" : "-"
let C = isConnectionOnTraffic(reachabilityFlags) ? "C" : "-"
let D = isConnectionOnDemand(reachabilityFlags) ? "D" : "-"
let l = isLocalAddress(reachabilityFlags) ? "l" : "-"
let d = isDirect(reachabilityFlags) ? "d" : "-"
return "\(W)\(R) \(c)\(t)\(i)\(C)\(D)\(l)\(d)"
}
deinit {
stopNotifier()
reachabilityRef = nil
whenReachable = nil
whenUnreachable = nil
}
}