diff --git a/EVURLCache.podspec b/EVURLCache.podspec index d9c9f65..99afb7a 100644 --- a/EVURLCache.podspec +++ b/EVURLCache.podspec @@ -8,7 +8,7 @@ Pod::Spec.new do |s| # s.name = "EVURLCache" -s.version = "2.0.2" +s.version = "2.1.0" s.summary = "NSURLCache subclass for handeling all web requests that use NSURLRequest" s.description = "This is a NSURLCache subclass for handeling all web requests that use NSURLRequest. (This includes UIWebView)" s.homepage = "https://github.com/evermeer/EVURLCache" diff --git a/EVURLCache/AppDelegate.swift b/EVURLCache/AppDelegate.swift index 677d664..c649d5a 100644 --- a/EVURLCache/AppDelegate.swift +++ b/EVURLCache/AppDelegate.swift @@ -22,6 +22,9 @@ class AppDelegate: UIResponder, UIApplicationDelegate { EVURLCache.MAX_FILE_SIZE = 26 // We want more than the default: 2^30 = 1GB EVURLCache.MAX_CACHE_SIZE = 30 + // Use this to force case insensitive filename compare when using a case sensitive filesystem (what OS X can have) + EVURLCache.FORCE_LOWERCASE = true // is already the default. You also have to put all files int he PreCache using lowercase names + // Now activate this cache EVURLCache.activate() return true diff --git a/EVURLCache/Pod/EVURLCache.swift b/EVURLCache/Pod/EVURLCache.swift index e89c15a..3c89e5e 100644 --- a/EVURLCache/Pod/EVURLCache.swift +++ b/EVURLCache/Pod/EVURLCache.swift @@ -8,6 +8,7 @@ import Foundation import ReachabilitySwift +import MobileCoreServices public class EVURLCache : NSURLCache { @@ -19,10 +20,11 @@ public class EVURLCache : NSURLCache { public static var MAX_FILE_SIZE = 24 // The maximum file size that will be cached (2^24 = 16MB) public static var MAX_CACHE_SIZE = 30 // The maximum file size that will be cached (2^30 = 256MB) public static var LOGGING = false // Set this to true to see all caching action in the output log - + public static var FORCE_LOWERCASE = true // Set this to false if you want to use case insensitive filename compare public static var _cacheDirectory: String! public static var _preCacheDirectory: String! + // Activate EVURLCache public class func activate() { // set caching paths _cacheDirectory = NSURL(fileURLWithPath: NSSearchPathForDirectoriesInDomains(NSSearchPathDirectory.DocumentDirectory, NSSearchPathDomainMask.UserDomainMask, true)[0]).URLByAppendingPathComponent(CACHE_FOLDER).absoluteString @@ -33,13 +35,14 @@ public class EVURLCache : NSURLCache { NSURLCache.setSharedURLCache(urlCache) } + // Output log messages if logging is enabled private static func debugLog(message: String) { if LOGGING { NSLog(message) } } - + // Will be called by a NSURLConnection when it's wants to know if there is something in the cache. public override func cachedResponseForRequest(request: NSURLRequest) -> NSCachedURLResponse? { // is caching allowed if ((request.cachePolicy == NSURLRequestCachePolicy.ReloadIgnoringCacheData || request.URL!.absoluteString.hasPrefix("file://") || request.URL!.absoluteString.hasPrefix("data:")) && EVURLCache.networkAvailable()) { @@ -77,17 +80,32 @@ public class EVURLCache : NSURLCache { } catch {} } + // Return the cache response if let content:NSData = NSData(contentsOfFile: storagePath) { - let response = NSURLResponse(URL: request.URL!, MIMEType: "text/html", expectedContentLength: content.length, textEncodingName: nil) - EVURLCache.debugLog("CACHE returning cache response from \(storagePath)"); + let mimeType = getMimeType(storagePath) + let response = NSURLResponse(URL: request.URL!, MIMEType: mimeType, expectedContentLength: content.length, textEncodingName: nil) + EVURLCache.debugLog("CACHE returning cache response: mimeType = \(mimeType), path = \(storagePath)"); return NSCachedURLResponse(response: response, data: content) } EVURLCache.debugLog("CACHE could not be read from \(storagePath)"); return nil } + // Make sure the correct mimetype is returned from the cache + private func getMimeType(path: String) -> String { + var mimeType = "text/html" + if let fileExtension: String = path.componentsSeparatedByString(".").last { + if let uti: CFString = UTTypeCreatePreferredIdentifierForTag(kUTTagClassFilenameExtension, fileExtension as NSString, nil)?.takeRetainedValue() { + if let type = UTTypeCopyPreferredTagWithClass(uti, kUTTagClassMIMEType)?.takeRetainedValue() { + mimeType = type as String + } + } + } + return mimeType + } + // Will be called by NSURLConnection when a request is complete. public override func storeCachedResponse(cachedResponse: NSCachedURLResponse, forRequest request: NSURLRequest) { if let httpResponse = cachedResponse.response as? NSHTTPURLResponse { if httpResponse.statusCode >= 400 { @@ -109,12 +127,8 @@ public class EVURLCache : NSURLCache { // create storrage folder let storagePath: String = EVURLCache.storagePathForRequest(request, rootPath: EVURLCache._cacheDirectory) - if var storageDirectory: String = NSURL(fileURLWithPath: "\(storagePath)").URLByDeletingLastPathComponent?.absoluteString { + if let storageDirectory: String = NSURL(fileURLWithPath: "\(storagePath)").URLByDeletingLastPathComponent?.absoluteString { do { - if storageDirectory.hasPrefix("file:/") { - storageDirectory = storageDirectory.substringFromIndex(storageDirectory.startIndex.advancedBy(5)) - } - try NSFileManager.defaultManager().createDirectoryAtPath(storageDirectory, withIntermediateDirectories: true, attributes: nil) } catch let error as NSError { EVURLCache.debugLog("Error creating cache directory \(storageDirectory)"); @@ -148,22 +162,37 @@ public class EVURLCache : NSURLCache { return storagePath; } - + // build up the complete storrage path for a request plus root folder. public static func storagePathForRequest(request: NSURLRequest, rootPath: String) -> String { var localUrl: String! let host: String = request.URL?.host ?? "default" + + // The filename could be forced by the remote server. This could be used to force multiple url's to the same cache file if let cacheKey = request.valueForHTTPHeaderField(URLCACHE_CACHE_KEY) { - localUrl = "\(rootPath)/\(host)/\(cacheKey)" + localUrl = "\(host)/\(cacheKey)" } else { if let path = request.URL?.relativePath { - localUrl = "\(rootPath)/\(host)\(path)" + localUrl = "\(host)\(path)" + } else { + NSLog("WARNING: Unable to get the path from the request: \(request)") } } + + // Without an extension it's treated as a folder and the file will be called index.html if let storageFile: String = localUrl.componentsSeparatedByString("/").last { if !storageFile.containsString(".") { - localUrl = "\(localUrl)index.html" + localUrl = "/\(localUrl)index.html" } } + + // Force case insensitive compare (OSX filesystem can be case sensitive) + if FORCE_LOWERCASE { + localUrl = "\(rootPath)/\(localUrl.lowercaseString)" + } else { + localUrl = "\(rootPath)/\(localUrl)" + } + + // Cleanup if localUrl.hasPrefix("file:/") { localUrl = localUrl.substringFromIndex(localUrl.startIndex.advancedBy(5)) } @@ -172,6 +201,7 @@ public class EVURLCache : NSURLCache { return localUrl } + // You don't want your cache to be backed up. public static func addSkipBackupAttributeToItemAtURL(url: NSURL) -> Bool { let bufLength = getxattr(url.absoluteString, "com.apple.MobileBackup", nil, 0, 0, 0) if bufLength == -1 { @@ -196,6 +226,7 @@ public class EVURLCache : NSURLCache { return false } + // Check if we have a network connection private static func networkAvailable() -> Bool { let reachability: Reachability do { diff --git a/Podfile.lock b/Podfile.lock index db7e925..55b4283 100644 --- a/Podfile.lock +++ b/Podfile.lock @@ -1,5 +1,5 @@ PODS: - - ReachabilitySwift (2.1) + - ReachabilitySwift (2.3) DEPENDENCIES: - ReachabilitySwift (from `https://github.com/ashleymills/Reachability.swift`) @@ -10,10 +10,10 @@ EXTERNAL SOURCES: CHECKOUT OPTIONS: ReachabilitySwift: - :commit: 89b2431fe262bc5915972472e36d04c067f686bc + :commit: 35aa812197a0f5f964febfe74be6c000edc8f850 :git: https://github.com/ashleymills/Reachability.swift SPEC CHECKSUMS: - ReachabilitySwift: 99bb7acceebb90b2048b4a8fd6539be96454dcb2 + ReachabilitySwift: 2ac9df18a443901f06caae38a9f5431219a4c36a COCOAPODS: 0.39.0 diff --git a/Pods/Local Podspecs/ReachabilitySwift.podspec.json b/Pods/Local Podspecs/ReachabilitySwift.podspec.json index e56c89e..d1f78af 100644 --- a/Pods/Local Podspecs/ReachabilitySwift.podspec.json +++ b/Pods/Local Podspecs/ReachabilitySwift.podspec.json @@ -1,6 +1,6 @@ { "name": "ReachabilitySwift", - "version": "2.1", + "version": "2.3", "homepage": "https://github.com/ashleymills/Reachability.swift", "authors": { "Ashley Mills": "ashleymills@mac.com" @@ -15,9 +15,9 @@ }, "source": { "git": "https://github.com/ashleymills/Reachability.swift.git", - "tag": "v2.1" + "tag": "v2.3" }, - "source_files": "Reachability.swift", + "source_files": "Reachability/Reachability.swift", "frameworks": "SystemConfiguration", "requires_arc": true } diff --git a/Pods/Manifest.lock b/Pods/Manifest.lock index db7e925..55b4283 100644 --- a/Pods/Manifest.lock +++ b/Pods/Manifest.lock @@ -1,5 +1,5 @@ PODS: - - ReachabilitySwift (2.1) + - ReachabilitySwift (2.3) DEPENDENCIES: - ReachabilitySwift (from `https://github.com/ashleymills/Reachability.swift`) @@ -10,10 +10,10 @@ EXTERNAL SOURCES: CHECKOUT OPTIONS: ReachabilitySwift: - :commit: 89b2431fe262bc5915972472e36d04c067f686bc + :commit: 35aa812197a0f5f964febfe74be6c000edc8f850 :git: https://github.com/ashleymills/Reachability.swift SPEC CHECKSUMS: - ReachabilitySwift: 99bb7acceebb90b2048b4a8fd6539be96454dcb2 + ReachabilitySwift: 2ac9df18a443901f06caae38a9f5431219a4c36a COCOAPODS: 0.39.0 diff --git a/Pods/Pods.xcodeproj/project.pbxproj b/Pods/Pods.xcodeproj/project.pbxproj index 52a39eb..ab955f5 100644 --- a/Pods/Pods.xcodeproj/project.pbxproj +++ b/Pods/Pods.xcodeproj/project.pbxproj @@ -7,12 +7,12 @@ objects = { /* Begin PBXBuildFile section */ - 4E520E492532E2D25DD6237C9697BDA5 /* ReachabilitySwift-umbrella.h in Headers */ = {isa = PBXBuildFile; fileRef = F90AA4C0F485C75A1F1B9452D1DA3EC0 /* ReachabilitySwift-umbrella.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 4E520E492532E2D25DD6237C9697BDA5 /* ReachabilitySwift-umbrella.h in Headers */ = {isa = PBXBuildFile; fileRef = 275E6C6BD881C64FF5A9275414CDD168 /* ReachabilitySwift-umbrella.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 623155B1CD911FE2809FBA94C695C073 /* Reachability.swift in Sources */ = {isa = PBXBuildFile; fileRef = B69D4187F1B8F1EEEA7A0121DE67F2B7 /* Reachability.swift */; }; 655CB59A4419AFB7E1D52B92C32D267C /* Pods-dummy.m in Sources */ = {isa = PBXBuildFile; fileRef = 894E5DA93A9F359521A89826BE6DA777 /* Pods-dummy.m */; }; - 6F9103995EBEFA6854FCD9449322389D /* ReachabilitySwift-dummy.m in Sources */ = {isa = PBXBuildFile; fileRef = BB688D2A64BF456D4F61078D40C58933 /* ReachabilitySwift-dummy.m */; }; 90F348F4F598E809140ABC2ACD18C3C4 /* SystemConfiguration.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = CBB0853BD8CE1AE8CF5FE525E44C538C /* SystemConfiguration.framework */; }; + AAB326716AD2049B8AA11D8D70E6C4DA /* ReachabilitySwift-dummy.m in Sources */ = {isa = PBXBuildFile; fileRef = 7B0173D02276968EB9711C6BF944032E /* ReachabilitySwift-dummy.m */; }; D9C341FF57E2D4E5B66F13D3F0F864D2 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D820BA2602BCBFDAEFA60A2883FB8F30 /* Foundation.framework */; }; - DA687E10E66E1084DB0C4FFF5D7CC7D0 /* Reachability.swift in Sources */ = {isa = PBXBuildFile; fileRef = EFEA05C5CFF5D6CB37E083B464FB4043 /* Reachability.swift */; }; FA23B2A8D228E422F5AE8318C71A1574 /* Pods-umbrella.h in Headers */ = {isa = PBXBuildFile; fileRef = 2BCC458FDD5F692BBB2BFC64BB5701FC /* Pods-umbrella.h */; settings = {ATTRIBUTES = (Public, ); }; }; FBBE6A5A0AD900BC96B664AD7E5AF981 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D820BA2602BCBFDAEFA60A2883FB8F30 /* Foundation.framework */; }; /* End PBXBuildFile section */ @@ -28,28 +28,28 @@ /* End PBXContainerItemProxy section */ /* Begin PBXFileReference section */ - 272545E2469044F64271C8762606FB02 /* Info.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + 022DFEACFD5D0041997A86770F17F9C8 /* ReachabilitySwift-prefix.pch */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "ReachabilitySwift-prefix.pch"; sourceTree = ""; }; + 1BB2A29A6FDCDB14FFEAD8642AAFF91B /* Info.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + 275E6C6BD881C64FF5A9275414CDD168 /* ReachabilitySwift-umbrella.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "ReachabilitySwift-umbrella.h"; sourceTree = ""; }; 2BCC458FDD5F692BBB2BFC64BB5701FC /* Pods-umbrella.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "Pods-umbrella.h"; sourceTree = ""; }; - 6BB4FA4FAE8999E396E9DC247CD7430B /* ReachabilitySwift.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = ReachabilitySwift.xcconfig; sourceTree = ""; }; 79A9DEDC89FE8336BF5FEDAAF75BF7FC /* Pods.modulemap */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = "sourcecode.module-map"; path = Pods.modulemap; sourceTree = ""; }; + 7B0173D02276968EB9711C6BF944032E /* ReachabilitySwift-dummy.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = "ReachabilitySwift-dummy.m"; sourceTree = ""; }; 87B213035BAC5F75386F62D3C75D2342 /* Pods-acknowledgements.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; path = "Pods-acknowledgements.plist"; sourceTree = ""; }; 894E5DA93A9F359521A89826BE6DA777 /* Pods-dummy.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = "Pods-dummy.m"; sourceTree = ""; }; 977577C045EDA9D9D1F46E2598D19FC7 /* Pods.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = Pods.debug.xcconfig; sourceTree = ""; }; - AD0E1154A5A2A65E5A25228BDADCF82A /* ReachabilitySwift-prefix.pch */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "ReachabilitySwift-prefix.pch"; sourceTree = ""; }; B1571D7BE35A92C839919332CF4037AA /* ReachabilitySwift.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = ReachabilitySwift.framework; sourceTree = BUILT_PRODUCTS_DIR; }; - B590C17DEAD440DDF62FB124B07F5CEE /* ReachabilitySwift.modulemap */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = "sourcecode.module-map"; path = ReachabilitySwift.modulemap; sourceTree = ""; }; - BA6428E9F66FD5A23C0A2E06ED26CD2F /* Podfile */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text; name = Podfile; path = ../Podfile; sourceTree = SOURCE_ROOT; }; - BB688D2A64BF456D4F61078D40C58933 /* ReachabilitySwift-dummy.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = "ReachabilitySwift-dummy.m"; sourceTree = ""; }; + B69D4187F1B8F1EEEA7A0121DE67F2B7 /* Reachability.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Reachability.swift; path = Reachability/Reachability.swift; sourceTree = ""; }; + BA6428E9F66FD5A23C0A2E06ED26CD2F /* Podfile */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text; name = Podfile; path = ../Podfile; sourceTree = SOURCE_ROOT; xcLanguageSpecificationIdentifier = xcode.lang.ruby; }; + C83B22AA12F333F2726894B4319B4CB2 /* ReachabilitySwift.modulemap */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = "sourcecode.module-map"; path = ReachabilitySwift.modulemap; sourceTree = ""; }; CBB0853BD8CE1AE8CF5FE525E44C538C /* SystemConfiguration.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = SystemConfiguration.framework; path = Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS9.0.sdk/System/Library/Frameworks/SystemConfiguration.framework; sourceTree = DEVELOPER_DIR; }; CBC0F7C552B739C909B650A0F42F7F38 /* Pods-resources.sh */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.script.sh; path = "Pods-resources.sh"; sourceTree = ""; }; CC1729837FA72EDA3F674BB5F8F95139 /* Pods.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods.framework; sourceTree = BUILT_PRODUCTS_DIR; }; D0405803033A2A777B8E4DFA0C1800ED /* Pods-acknowledgements.markdown */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text; path = "Pods-acknowledgements.markdown"; sourceTree = ""; }; D820BA2602BCBFDAEFA60A2883FB8F30 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS9.0.sdk/System/Library/Frameworks/Foundation.framework; sourceTree = DEVELOPER_DIR; }; DA312349A49333542E6F4B36B329960E /* Pods.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = Pods.release.xcconfig; sourceTree = ""; }; + E2D2A444FC528FC0D4C80F57A3D32F88 /* ReachabilitySwift.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = ReachabilitySwift.xcconfig; sourceTree = ""; }; E7F21354943D9F42A70697D5A5EF72E9 /* Pods-frameworks.sh */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.script.sh; path = "Pods-frameworks.sh"; sourceTree = ""; }; E8446514FBAD26C0E18F24A5715AEF67 /* Info.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; - EFEA05C5CFF5D6CB37E083B464FB4043 /* Reachability.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; path = Reachability.swift; sourceTree = ""; }; - F90AA4C0F485C75A1F1B9452D1DA3EC0 /* ReachabilitySwift-umbrella.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "ReachabilitySwift-umbrella.h"; sourceTree = ""; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ @@ -73,15 +73,6 @@ /* End PBXFrameworksBuildPhase section */ /* Begin PBXGroup section */ - 039C1C53E74F28950B135D4928327B21 /* ReachabilitySwift */ = { - isa = PBXGroup; - children = ( - EFEA05C5CFF5D6CB37E083B464FB4043 /* Reachability.swift */, - CA0CFAA025174D7425997AAAF1DD056D /* Support Files */, - ); - path = ReachabilitySwift; - sourceTree = ""; - }; 0D1A9B04773EF0CA51E38942760CD6D4 /* iOS */ = { isa = PBXGroup; children = ( @@ -131,31 +122,31 @@ 9BCD5CBAACE7E3EBED55F693896BB924 /* Pods */ = { isa = PBXGroup; children = ( - 039C1C53E74F28950B135D4928327B21 /* ReachabilitySwift */, + F47FCCB16BA3F38D5553162F93FAF492 /* ReachabilitySwift */, ); name = Pods; sourceTree = ""; }; - B7B80995527643776607AFFA75B91E24 /* Targets Support Files */ = { + A9ED4EC8142E9CD679F2F17116535C39 /* Support Files */ = { isa = PBXGroup; children = ( - 75D98FF52E597A11900E131B6C4E1ADA /* Pods */, + 1BB2A29A6FDCDB14FFEAD8642AAFF91B /* Info.plist */, + C83B22AA12F333F2726894B4319B4CB2 /* ReachabilitySwift.modulemap */, + E2D2A444FC528FC0D4C80F57A3D32F88 /* ReachabilitySwift.xcconfig */, + 7B0173D02276968EB9711C6BF944032E /* ReachabilitySwift-dummy.m */, + 022DFEACFD5D0041997A86770F17F9C8 /* ReachabilitySwift-prefix.pch */, + 275E6C6BD881C64FF5A9275414CDD168 /* ReachabilitySwift-umbrella.h */, ); - name = "Targets Support Files"; + name = "Support Files"; + path = "../Target Support Files/ReachabilitySwift"; sourceTree = ""; }; - CA0CFAA025174D7425997AAAF1DD056D /* Support Files */ = { + B7B80995527643776607AFFA75B91E24 /* Targets Support Files */ = { isa = PBXGroup; children = ( - 272545E2469044F64271C8762606FB02 /* Info.plist */, - B590C17DEAD440DDF62FB124B07F5CEE /* ReachabilitySwift.modulemap */, - 6BB4FA4FAE8999E396E9DC247CD7430B /* ReachabilitySwift.xcconfig */, - BB688D2A64BF456D4F61078D40C58933 /* ReachabilitySwift-dummy.m */, - AD0E1154A5A2A65E5A25228BDADCF82A /* ReachabilitySwift-prefix.pch */, - F90AA4C0F485C75A1F1B9452D1DA3EC0 /* ReachabilitySwift-umbrella.h */, + 75D98FF52E597A11900E131B6C4E1ADA /* Pods */, ); - name = "Support Files"; - path = "../Target Support Files/ReachabilitySwift"; + name = "Targets Support Files"; sourceTree = ""; }; CD5550B449395C1BE55F299DA788425F /* Products */ = { @@ -167,6 +158,15 @@ name = Products; sourceTree = ""; }; + F47FCCB16BA3F38D5553162F93FAF492 /* ReachabilitySwift */ = { + isa = PBXGroup; + children = ( + B69D4187F1B8F1EEEA7A0121DE67F2B7 /* Reachability.swift */, + A9ED4EC8142E9CD679F2F17116535C39 /* Support Files */, + ); + path = ReachabilitySwift; + sourceTree = ""; + }; /* End PBXGroup section */ /* Begin PBXHeadersBuildPhase section */ @@ -211,7 +211,7 @@ isa = PBXNativeTarget; buildConfigurationList = 7FCD49A1A9BAB515A1BB48DAC6D92846 /* Build configuration list for PBXNativeTarget "ReachabilitySwift" */; buildPhases = ( - 591C3E47FAC09D688606C55B1A02DDA9 /* Sources */, + AD04BFDBEBAC70F439AFAF2A8E03FE7B /* Sources */, 1A67545BA556F20F6F903EDD145B6058 /* Frameworks */, 8EC508DF477670198D31587F287569F4 /* Headers */, ); @@ -252,12 +252,12 @@ /* End PBXProject section */ /* Begin PBXSourcesBuildPhase section */ - 591C3E47FAC09D688606C55B1A02DDA9 /* Sources */ = { + AD04BFDBEBAC70F439AFAF2A8E03FE7B /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( - DA687E10E66E1084DB0C4FFF5D7CC7D0 /* Reachability.swift in Sources */, - 6F9103995EBEFA6854FCD9449322389D /* ReachabilitySwift-dummy.m in Sources */, + 623155B1CD911FE2809FBA94C695C073 /* Reachability.swift in Sources */, + AAB326716AD2049B8AA11D8D70E6C4DA /* ReachabilitySwift-dummy.m in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -283,7 +283,7 @@ /* Begin XCBuildConfiguration section */ 6C84BFBB10148321BCAECB2E51B21B3B /* Release */ = { isa = XCBuildConfiguration; - baseConfigurationReference = 6BB4FA4FAE8999E396E9DC247CD7430B /* ReachabilitySwift.xcconfig */; + baseConfigurationReference = E2D2A444FC528FC0D4C80F57A3D32F88 /* ReachabilitySwift.xcconfig */; buildSettings = { "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; CURRENT_PROJECT_VERSION = 1; @@ -444,7 +444,7 @@ }; E44D365BA23701393A7AA7AE7F8EA8FA /* Debug */ = { isa = XCBuildConfiguration; - baseConfigurationReference = 6BB4FA4FAE8999E396E9DC247CD7430B /* ReachabilitySwift.xcconfig */; + baseConfigurationReference = E2D2A444FC528FC0D4C80F57A3D32F88 /* ReachabilitySwift.xcconfig */; buildSettings = { "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; CURRENT_PROJECT_VERSION = 1; diff --git a/Pods/ReachabilitySwift/README.md b/Pods/ReachabilitySwift/README.md index 0badf6c..5138187 100644 --- a/Pods/ReachabilitySwift/README.md +++ b/Pods/ReachabilitySwift/README.md @@ -2,13 +2,20 @@ Replacement for Apple's Reachability re-written in Swift with closures -Inspired by https://github.com/tonymillion/Reachability +Inspired by https://github.com/tonymillion/Reachability -**NOTES:** +## Supporting **Reachability.swift** +Keeping **Reachability.swift** up-to-date is a time consuming task. Making updates, reviewing pull requests, responding to issues and answering emails all take time. If you'd like to help keep me motivated, please download my free app, [Foto Flipper] from the App Store. (To really motivate me, pay $0.99 for the IAP!) -- 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 +And don't forget to **★** the repo. This increases its visibility and encourages others to contribute. + +Thanks +Ash ## Installation +### Manual +Just drop the **Reachability.swift** file into your project. That's it! + ### CocoaPods [CocoaPods][] is a dependency manager for Cocoa projects. To install Reachability.swift with CocoaPods: @@ -26,8 +33,27 @@ Inspired by https://github.com/tonymillion/Reachability [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! +### Carthage +[Carthage][] is a decentralized dependency manager that builds your dependencies and provides you with binary frameworks. +To install Reachability.swift with Carthage: + +1. Install Carthage via [Homebrew][] + ```bash + $ brew update + $ brew install carthage + ``` + +2. Add `github "ashleymills/Reachability.swift"` to your Cartfile. + +3. Run `carthage update`. + +4. Drag `Reachability.framework` from the `Carthage/Build/iOS/` directory to the `Linked Frameworks and Libraries` section of your Xcode project’s `General` settings. + +5. Add `$(SRCROOT)/Carthage/Build/iOS/Reachability.framework` to `Input Files` of Run Script Phase for Carthage. + +[Carthage]: https://github.com/Carthage/Carthage +[Homebrew]: http://brew.sh +[Foto Flipper]: http://itunes.com/apps/fotoflipper ## Example - closures @@ -86,9 +112,9 @@ do { return } -NSNotificationCenter.defaultCenter().addObserver(self, - selector: "reachabilityChanged:", - name: ReachabilityChangedNotification, +NSNotificationCenter.defaultCenter().addObserver(self, + selector: "reachabilityChanged:", + name: ReachabilityChangedNotification, object: reachability) reachability.startNotifier() @@ -117,8 +143,8 @@ and for stopping notifications ```swift reachability.stopNotifier() -NSNotificationCenter.defaultCenter().removeObserver(self, - name: ReachabilityChangedNotification, +NSNotificationCenter.defaultCenter().removeObserver(self, + name: ReachabilityChangedNotification, object: reachability) ``` @@ -128,8 +154,7 @@ 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! +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 - diff --git a/Pods/ReachabilitySwift/Reachability.swift b/Pods/ReachabilitySwift/Reachability/Reachability.swift similarity index 79% rename from Pods/ReachabilitySwift/Reachability.swift rename to Pods/ReachabilitySwift/Reachability/Reachability.swift index 22bb54c..02c0698 100644 --- a/Pods/ReachabilitySwift/Reachability.swift +++ b/Pods/ReachabilitySwift/Reachability/Reachability.swift @@ -25,10 +25,12 @@ ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ +// Reachability.swift version 2.2beta2 + import SystemConfiguration import Foundation -enum ReachabilityError: ErrorType { +public enum ReachabilityError: ErrorType { case FailedToCreateWithAddress(sockaddr_in) case FailedToCreateWithHostname(String) case UnableToSetCallback @@ -68,7 +70,6 @@ public class Reachability: NSObject { } // MARK: - *** Public properties *** - public var whenReachable: NetworkReachable? public var whenUnreachable: NetworkUnreachable? public var reachableOnWWAN: Bool @@ -83,7 +84,6 @@ public class Reachability: NSObject { return .ReachableViaWWAN } } - return .NotReachable } @@ -91,6 +91,8 @@ public class Reachability: NSObject { return "\(currentReachabilityStatus)" } + private var previousFlags: SCNetworkReachabilityFlags? + // MARK: - *** Initialisation methods *** required public init(reachabilityRef: SCNetworkReachability) { @@ -139,7 +141,7 @@ public class Reachability: NSObject { // MARK: - *** Notifier methods *** public func startNotifier() throws { - if notifierRunning { return } + guard !notifierRunning else { return } var context = SCNetworkReachabilityContext(version: 0, info: nil, retain: nil, release: nil, copyDescription: nil) context.info = UnsafeMutablePointer(Unmanaged.passUnretained(self).toOpaque()) @@ -154,77 +156,70 @@ public class Reachability: NSObject { throw ReachabilityError.UnableToSetDispatchQueue } + // Perform an intial check + let flags = reachabilityFlags + reachabilityChanged(flags) + notifierRunning = true } - public func stopNotifier() { - if let reachabilityRef = reachabilityRef { - SCNetworkReachabilitySetCallback(reachabilityRef, nil, nil) - SCNetworkReachabilitySetDispatchQueue(reachabilityRef, nil) - } - notifierRunning = false - } + defer { notifierRunning = false } + guard let reachabilityRef = reachabilityRef else { return } + SCNetworkReachabilitySetCallback(reachabilityRef, nil, nil) + SCNetworkReachabilitySetDispatchQueue(reachabilityRef, nil) + } + // MARK: - *** Connection test methods *** public func isReachable() -> Bool { - return isReachableWithTest({ (flags: SCNetworkReachabilityFlags) -> (Bool) in - return self.isReachableWithFlags(flags) - }) + let flags = reachabilityFlags + return 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 + + let flags = reachabilityFlags + + // Check we're not on the simulator, we're REACHABLE and check we're on WWAN + return isRunningOnDevice && isReachable(flags) && isOnWWAN(flags) } 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 - } - + + let flags = reachabilityFlags + + // Check we're reachable + if !isReachable(flags) { return false } + + // Must be on WiFi if reachable but not on an iOS device (i.e. simulator) + if !isRunningOnDevice { + return true + } + + // Check we're NOT on WWAN + return !isOnWWAN(flags) } // MARK: - *** Private methods *** private var isRunningOnDevice: Bool = { #if (arch(i386) || arch(x86_64)) && os(iOS) return false - #else + #else return true #endif - }() + }() private var notifierRunning = false private var reachabilityRef: SCNetworkReachability? private let reachabilitySerialQueue = dispatch_queue_create("uk.co.ashleymills.reachability", DISPATCH_QUEUE_SERIAL) private func reachabilityChanged(flags: SCNetworkReachabilityFlags) { + + guard previousFlags != flags else { return } + if isReachableWithFlags(flags) { if let block = whenReachable { block(self) @@ -236,47 +231,30 @@ public class Reachability: NSObject { } notificationCenter.postNotificationName(ReachabilityChangedNotification, object:self) + + previousFlags = flags } private func isReachableWithFlags(flags: SCNetworkReachabilityFlags) -> Bool { - let reachable = isReachable(flags) - - if !reachable { + if !isReachable(flags) { 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 { - - if let reachabilityRef = reachabilityRef { - - var flags = SCNetworkReachabilityFlags(rawValue: 0) - let gotFlags = withUnsafeMutablePointer(&flags) { - SCNetworkReachabilityGetFlags(reachabilityRef, UnsafeMutablePointer($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 { @@ -284,23 +262,20 @@ public class Reachability: NSObject { } private func connectionRequired() -> Bool { - return isReachableWithTest({ (flags: SCNetworkReachabilityFlags) -> (Bool) in - return self.isConnectionRequired(flags) - }) + let flags = reachabilityFlags + return isConnectionRequired(flags) } // Dynamic, on demand connection? private func isConnectionOnDemand() -> Bool { - return isReachableWithTest({ (flags: SCNetworkReachabilityFlags) -> (Bool) in - return self.isConnectionRequired(flags) && self.isConnectionOnTrafficOrDemand(flags) - }) + let flags = reachabilityFlags + return isConnectionRequired(flags) && isConnectionOnTrafficOrDemand(flags) } // Is user intervention required? private func isInterventionRequired() -> Bool { - return isReachableWithTest({ (flags: SCNetworkReachabilityFlags) -> (Bool) in - return self.isConnectionRequired(flags) && self.isInterventionRequired(flags) - }) + let flags = reachabilityFlags + return isConnectionRequired(flags) && isInterventionRequired(flags) } private func isOnWWAN(flags: SCNetworkReachabilityFlags) -> Bool { @@ -343,19 +318,19 @@ public class Reachability: NSObject { } private var reachabilityFlags: SCNetworkReachabilityFlags { - if let reachabilityRef = reachabilityRef { - - var flags = SCNetworkReachabilityFlags(rawValue: 0) - let gotFlags = withUnsafeMutablePointer(&flags) { - SCNetworkReachabilityGetFlags(reachabilityRef, UnsafeMutablePointer($0)) - } - - if gotFlags { - return flags - } + + guard let reachabilityRef = reachabilityRef else { return SCNetworkReachabilityFlags() } + + var flags = SCNetworkReachabilityFlags() + let gotFlags = withUnsafeMutablePointer(&flags) { + SCNetworkReachabilityGetFlags(reachabilityRef, UnsafeMutablePointer($0)) + } + + if gotFlags { + return flags + } else { + return SCNetworkReachabilityFlags() } - - return [] } override public var description: String { diff --git a/Pods/Target Support Files/ReachabilitySwift/Info.plist b/Pods/Target Support Files/ReachabilitySwift/Info.plist index 2e78f7a..fb4ddf0 100644 --- a/Pods/Target Support Files/ReachabilitySwift/Info.plist +++ b/Pods/Target Support Files/ReachabilitySwift/Info.plist @@ -15,7 +15,7 @@ CFBundlePackageType FMWK CFBundleShortVersionString - 2.1 + 2.3 CFBundleSignature ???? CFBundleVersion