|
|
|
@ -7,7 +7,7 @@ import Foundation |
|
|
|
import Nimbus |
|
|
|
import Alamofire |
|
|
|
|
|
|
|
class MediaPhotoController: NIToolbarPhotoViewController, NIPhotoAlbumScrollViewDataSource, NIPhotoScrubberViewDataSource { |
|
|
|
class MediaPhotoController: NIToolbarPhotoViewController, NIPhotoAlbumScrollViewDataSource, NIPhotoScrubberViewDataSource, NSURLSessionDelegate { |
|
|
|
|
|
|
|
var items = [MediaItem]() |
|
|
|
var completionHandler: ((Void) -> Void)? |
|
|
|
@ -21,29 +21,41 @@ class MediaPhotoController: NIToolbarPhotoViewController, NIPhotoAlbumScrollView |
|
|
|
|
|
|
|
var timer: NSTimer? |
|
|
|
|
|
|
|
var currentIndex = 80 |
|
|
|
var currentIndex = 100 |
|
|
|
|
|
|
|
lazy var backgroundOperationQueue: NSOperationQueue = { |
|
|
|
var queue = NSOperationQueue() |
|
|
|
queue.name = "Thumb queue" |
|
|
|
queue.maxConcurrentOperationCount = 10 |
|
|
|
return queue |
|
|
|
}() |
|
|
|
var urlSession: NSURLSession? |
|
|
|
|
|
|
|
var sessionOwner = false |
|
|
|
|
|
|
|
let dateFormatter = NSDateFormatter() |
|
|
|
|
|
|
|
lazy var operationQueue: NSOperationQueue = { |
|
|
|
var queue = NSOperationQueue() |
|
|
|
queue.name = "Photo queue" |
|
|
|
queue.maxConcurrentOperationCount = 6 |
|
|
|
queue.maxConcurrentOperationCount = 3 |
|
|
|
return queue |
|
|
|
}() |
|
|
|
|
|
|
|
override func viewDidDisappear(animated: Bool) { |
|
|
|
backgroundOperationQueue.cancelAllOperations() |
|
|
|
operationQueue.cancelAllOperations() |
|
|
|
} |
|
|
|
|
|
|
|
public func URLSession(session: NSURLSession, didBecomeInvalidWithError error: NSError?) { |
|
|
|
print(error) |
|
|
|
} |
|
|
|
|
|
|
|
override func viewDidLoad() { |
|
|
|
super.viewDidLoad() |
|
|
|
|
|
|
|
if urlSession == nil { |
|
|
|
sessionOwner = true |
|
|
|
let configuration = NSURLSessionConfiguration.ephemeralSessionConfiguration(); // backgroundSessionConfigurationWithIdentifier("imageLoad"); |
|
|
|
configuration.HTTPMaximumConnectionsPerHost = 10; |
|
|
|
configuration.timeoutIntervalForRequest = 100; |
|
|
|
configuration.timeoutIntervalForResource = 200; |
|
|
|
urlSession = NSURLSession(configuration: configuration, delegate: self, delegateQueue: nil); |
|
|
|
} |
|
|
|
|
|
|
|
imageCache.totalCostLimit = 1024 * 1024 * 1024 |
|
|
|
|
|
|
|
let backButton = UIBarButtonItem(barButtonSystemItem: .Cancel, target: self, action: Selector("back")) |
|
|
|
@ -57,59 +69,40 @@ class MediaPhotoController: NIToolbarPhotoViewController, NIPhotoAlbumScrollView |
|
|
|
setChromeVisibility(true, animated: true) |
|
|
|
|
|
|
|
self.photoAlbumView.reloadData(); |
|
|
|
self.photoScrubberView.reloadData(); |
|
|
|
|
|
|
|
preload(0, count: 40) |
|
|
|
preload(40, count: 40) |
|
|
|
preload(0, count: 50) |
|
|
|
preload(50, count: 50) |
|
|
|
} |
|
|
|
|
|
|
|
func preload(start: Int, count: Int) { |
|
|
|
let dateFormatter = NSDateFormatter() |
|
|
|
dateFormatter.dateFormat = "HH:mm:ss.SSSZ" |
|
|
|
|
|
|
|
var preview = "" |
|
|
|
let end = start + count |
|
|
|
for var k = start; k < end; k++ { |
|
|
|
let tu = items[k].thumbUrl!.stringByReplacingOccurrencesOfString("?preview=true", withString: "") |
|
|
|
preview += "\(tu);" |
|
|
|
} |
|
|
|
|
|
|
|
preview = preview.stringByAddingPercentEscapesUsingEncoding(NSISOLatin1StringEncoding)! |
|
|
|
|
|
|
|
let u2 = "\(NetworkManager.sharedInstance.baseurl)/service/preload?preview=\(preview)" |
|
|
|
let u3 = NSURL(string: u2) |
|
|
|
|
|
|
|
if let URL = u3 { |
|
|
|
let time = dateFormatter.stringFromDate(NSDate()) |
|
|
|
print("\(time) preload image \(u2)") |
|
|
|
|
|
|
|
let op1 = DataLoadOperation(imageURL: URL, succeeder: { |
|
|
|
da in |
|
|
|
if da.length > 0 { |
|
|
|
let d = da as! NSData |
|
|
|
|
|
|
|
func loadData(d: NSData, start: Int, end: Int) { |
|
|
|
let bytes = Array(UnsafeBufferPointer(start: UnsafePointer<UInt8>(d.bytes), count: d.length)) |
|
|
|
let string1 = NSString(data: d, encoding: NSUTF8StringEncoding) |
|
|
|
print(string1) |
|
|
|
var index = 0 |
|
|
|
let fHi = (Int(bytes[index++]) << 24)+(Int(bytes[index++]) << 16) |
|
|
|
let fHi = (Int(bytes[index++]) << 24) + (Int(bytes[index++]) << 16) |
|
|
|
let f = fHi + (Int(bytes[index++]) << 8) + Int(bytes[index++]) |
|
|
|
// let f = (bytes[index++] << 24)+(bytes[index++] << 16)+(bytes[index++] << 8) + bytes[index++] |
|
|
|
let time = dateFormatter.stringFromDate(NSDate()) |
|
|
|
print("\(time) start \(start) count \(f) size \(d.length)") |
|
|
|
|
|
|
|
var rest = self.items.count - self.currentIndex |
|
|
|
if rest > 40 { |
|
|
|
rest = 40 |
|
|
|
|
|
|
|
if rest > 50 { |
|
|
|
rest = 50 |
|
|
|
} |
|
|
|
|
|
|
|
if rest > 0 { |
|
|
|
self.preload(self.currentIndex, count: rest) |
|
|
|
self.currentIndex += rest |
|
|
|
} else { |
|
|
|
dispatch_async(dispatch_get_main_queue(), { |
|
|
|
() -> Void in |
|
|
|
self.photoScrubberView.reloadData(); |
|
|
|
}) |
|
|
|
} |
|
|
|
|
|
|
|
for var bild = start; bild < end; bild++ { |
|
|
|
let sizeHi = (Int(bytes[index++]) << 24)+(Int(bytes[index++]) << 16) |
|
|
|
let sizeHi = (Int(bytes[index++]) << 24) + (Int(bytes[index++]) << 16) |
|
|
|
let size = (Int(bytes[index++]) << 8) + Int(bytes[index++]) + sizeHi |
|
|
|
|
|
|
|
if size > 0 { |
|
|
|
@ -128,49 +121,45 @@ class MediaPhotoController: NIToolbarPhotoViewController, NIPhotoAlbumScrollView |
|
|
|
} |
|
|
|
index += size |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
func preload(start: Int, count: Int) { |
|
|
|
|
|
|
|
dateFormatter.dateFormat = "HH:mm:ss.SSSZ" |
|
|
|
|
|
|
|
var preview = "" |
|
|
|
var end = start + count |
|
|
|
if end > items.count { |
|
|
|
end = items.count |
|
|
|
} |
|
|
|
}, index: start) |
|
|
|
op1.qualityOfService = NSQualityOfService.Background |
|
|
|
backgroundOperationQueue.addOperation(op1) |
|
|
|
} else { |
|
|
|
print("## Invalid URL: \(u2)") |
|
|
|
for var k = start; k < end; k++ { |
|
|
|
let tu = items[k].thumbUrl!.stringByReplacingOccurrencesOfString("?preview=true", withString: "") |
|
|
|
preview += "\(tu);" |
|
|
|
} |
|
|
|
|
|
|
|
preview = preview.stringByAddingPercentEscapesUsingEncoding(NSISOLatin1StringEncoding)! |
|
|
|
|
|
|
|
let u2 = "\(NetworkManager.sharedInstance.baseurl)/service/preload?preview=\(preview)" |
|
|
|
let u3 = NSURL(string: u2) |
|
|
|
|
|
|
|
// for i in items { |
|
|
|
// if j++ > 1000 { |
|
|
|
// break |
|
|
|
// } |
|
|
|
// |
|
|
|
// let u1 = NSURL(string: i.thumbUrlAbsolute) |
|
|
|
// |
|
|
|
// if let URL = u1 { |
|
|
|
// let time = dateFormatter.stringFromDate(NSDate()) |
|
|
|
// print("\(time) preload image \(i.name)") |
|
|
|
// |
|
|
|
// let op1 = DataLoadOperation(imageURL: URL, succeeder: { |
|
|
|
// d in |
|
|
|
// if d.length > 0 { |
|
|
|
// if let img = UIImage(data: d) { |
|
|
|
// let imageRef = img.CGImage; |
|
|
|
// let bytesPerPixel = CGImageGetBitsPerPixel(imageRef) / 8; |
|
|
|
// let cost = CGImageGetWidth(imageRef) * CGImageGetHeight(imageRef) * bytesPerPixel; |
|
|
|
// self.total += d.length |
|
|
|
// |
|
|
|
// let time = dateFormatter.stringFromDate(NSDate()) |
|
|
|
// print("\(time) preload image loaded \(i.name) cost \(cost) total\(self.total)") |
|
|
|
// self.imageCache.setObject(img, forKey: i.thumbUrlAbsolute, cost: d.length) |
|
|
|
// } |
|
|
|
// } |
|
|
|
// }, index: j) |
|
|
|
if let URL = u3 { |
|
|
|
let time = dateFormatter.stringFromDate(NSDate()) |
|
|
|
print("\(time) preload image \(u2)") |
|
|
|
|
|
|
|
urlSession!.dataTaskWithURL(URL) { |
|
|
|
(da, response, error) in |
|
|
|
if let d = da { |
|
|
|
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0)) { |
|
|
|
() -> Void in |
|
|
|
self.loadData(d, start: start, end: end) |
|
|
|
} |
|
|
|
} |
|
|
|
}.resume() |
|
|
|
// op1.qualityOfService = NSQualityOfService.Background |
|
|
|
// backgroundOperationQueue.addOperation(op1) |
|
|
|
// } else { |
|
|
|
// print("## Invalid URL: \(i.thumbUrlAbsolute)") |
|
|
|
// } |
|
|
|
// } |
|
|
|
} else { |
|
|
|
print("## Invalid URL: \(u2)") |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
override func didReceiveMemoryWarning() { |
|
|
|
@ -194,6 +183,13 @@ class MediaPhotoController: NIToolbarPhotoViewController, NIPhotoAlbumScrollView |
|
|
|
} |
|
|
|
|
|
|
|
func back() { |
|
|
|
imageCache.removeAllObjects() |
|
|
|
operationQueue.cancelAllOperations() |
|
|
|
|
|
|
|
if sessionOwner { |
|
|
|
urlSession!.invalidateAndCancel() |
|
|
|
} |
|
|
|
|
|
|
|
completionHandler!() |
|
|
|
} |
|
|
|
|
|
|
|
@ -246,7 +242,7 @@ class MediaPhotoController: NIToolbarPhotoViewController, NIPhotoAlbumScrollView |
|
|
|
for s in json as! [String] { |
|
|
|
if s.hasSuffix(".jpg") { |
|
|
|
let l = s.length |
|
|
|
let name = NSURL(fileURLWithPath: s ).lastPathComponent! |
|
|
|
let name = NSURL(fileURLWithPath: s).lastPathComponent! |
|
|
|
var pathlen = l - len - name.length |
|
|
|
|
|
|
|
// if (pathlen > 1000) { |
|
|
|
@ -276,6 +272,7 @@ class MediaPhotoController: NIToolbarPhotoViewController, NIPhotoAlbumScrollView |
|
|
|
} |
|
|
|
|
|
|
|
let pc = MediaPhotoController() |
|
|
|
pc.urlSession = self.urlSession! |
|
|
|
|
|
|
|
pc.items = im |
|
|
|
pc.completionHandler = { |
|
|
|
@ -379,7 +376,7 @@ class MediaPhotoController: NIToolbarPhotoViewController, NIPhotoAlbumScrollView |
|
|
|
self.photoScrubberView.didLoadThumbnail(i, atIndex: photoAtIndex); |
|
|
|
} |
|
|
|
} |
|
|
|
}, index: photoAtIndex) |
|
|
|
}, index: photoAtIndex, session: urlSession!) |
|
|
|
op3.qualityOfService = NSQualityOfService.UserInteractive |
|
|
|
operationQueue.addOperation(op3) |
|
|
|
} |
|
|
|
@ -445,19 +442,19 @@ class MediaPhotoController: NIToolbarPhotoViewController, NIPhotoAlbumScrollView |
|
|
|
return nil |
|
|
|
} |
|
|
|
|
|
|
|
var image: UIImage? |
|
|
|
let newItem = items[thumbnailIndex] |
|
|
|
let u1 = NSURL(string: newItem.thumbUrlAbsolute) |
|
|
|
|
|
|
|
var image: UIImage? |
|
|
|
if let URL = u1 { |
|
|
|
|
|
|
|
image = imageCache.objectForKey(newItem.thumbUrlAbsolute) as? UIImage |
|
|
|
image = imageCache.objectForKey(URL.absoluteString) as? UIImage |
|
|
|
|
|
|
|
if (image == nil) { |
|
|
|
let u1 = NSURL(string: newItem.thumbUrlAbsolute) |
|
|
|
if let URL = u1 { |
|
|
|
let op3 = DataLoadOperation(imageURL: URL, succeeder: { |
|
|
|
d in |
|
|
|
urlSession!.dataTaskWithURL(URL) { |
|
|
|
(da, response, error) in |
|
|
|
|
|
|
|
if d.length > 0 { |
|
|
|
if let d = da { |
|
|
|
if let i = UIImage(data: d) { |
|
|
|
// println("thumb image loaded \(newItem.thumbUrlAbsolute)") |
|
|
|
let imageRef = i.CGImage; |
|
|
|
@ -469,13 +466,12 @@ class MediaPhotoController: NIToolbarPhotoViewController, NIPhotoAlbumScrollView |
|
|
|
self.photoScrubberView.didLoadThumbnail(i, atIndex: thumbnailIndex); |
|
|
|
} |
|
|
|
} |
|
|
|
}, index: thumbnailIndex) |
|
|
|
op3.qualityOfService = NSQualityOfService.UserInitiated |
|
|
|
operationQueue.addOperation(op3) |
|
|
|
} else { |
|
|
|
print("## Invalid URL: \(newItem.thumbUrlAbsolute)") |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
else { |
|
|
|
print("## Invalid URL: \(newItem.thumbUrlAbsolute)") |
|
|
|
} |
|
|
|
|
|
|
|
return image |
|
|
|
} |
|
|
|
|