Skip to content

Commit

Permalink
Fix mimeType and casing
Browse files Browse the repository at this point in the history
  • Loading branch information
evermeer committed Dec 3, 2015
1 parent 1adc11d commit 92d11ae
Show file tree
Hide file tree
Showing 10 changed files with 200 additions and 166 deletions.
2 changes: 1 addition & 1 deletion EVURLCache.podspec
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down
3 changes: 3 additions & 0 deletions EVURLCache/AppDelegate.swift
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
57 changes: 44 additions & 13 deletions EVURLCache/Pod/EVURLCache.swift
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@

import Foundation
import ReachabilitySwift
import MobileCoreServices

public class EVURLCache : NSURLCache {

Expand All @@ -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
Expand All @@ -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()) {
Expand Down Expand Up @@ -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 {
Expand All @@ -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)");
Expand Down Expand Up @@ -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))
}
Expand All @@ -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 {
Expand All @@ -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 {
Expand Down
6 changes: 3 additions & 3 deletions Podfile.lock
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
PODS:
- ReachabilitySwift (2.1)
- ReachabilitySwift (2.3)

DEPENDENCIES:
- ReachabilitySwift (from `https://github.com/ashleymills/Reachability.swift`)
Expand All @@ -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
6 changes: 3 additions & 3 deletions Pods/Local Podspecs/ReachabilitySwift.podspec.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 3 additions & 3 deletions Pods/Manifest.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading

0 comments on commit 92d11ae

Please sign in to comment.