daltoniam / skeets Goto Github PK
View Code? Open in Web Editor NEWFetch, cache, and display images via HTTP in Swift.
License: Apache License 2.0
Fetch, cache, and display images via HTTP in Swift.
License: Apache License 2.0
Hi, I'm using httpswift with skeets in my apps
with httpswift
I accept all certificate with
var attempted = false
request.auth = {(challenge: NSURLAuthenticationChallenge) in
if !attempted {
attempted = true
return NSURLCredential(forTrust: challenge.protectionSpace.serverTrust)
}
return nil
}
It worked.
but when I loading image
I do the same with
let task = HTTPTask()
var attempted = false
task.auth = {(challenge: NSURLAuthenticationChallenge) in
if !attempted {
attempted = true
return NSURLCredential(forTrust: challenge.protectionSpace.serverTrust)
}
return nil
}
task.download(url, parameters: nil, progress: { (status: Double) in
dispatch_async(dispatch_get_main_queue(), {
self.doProgress(hash, status: status)
})
}, completionHandler: { (response: HTTPResponse) in
if let err = response.error {
dispatch_async(dispatch_get_main_queue(), {
self.doFailure(hash, error: err)
})
}
self.cache.add(hash, url: response.responseObject! as! NSURL)
dispatch_async(dispatch_get_main_queue(), {
if let d = self.cache.fromMemory(hash) {
self.doSuccess(hash, data: d)
}
})
})
in ImageManager.swift file
but I get this error
fatal error: unexpectedly found nil while unwrapping an Optional value
failed to get an image: Error Domain=NSURLErrorDomain Code=-1202 "The certificate for this server is invalid. You might be connecting to a server that is pretending to be “merchant.jamja.vn” which could put your confidential information at risk." UserInfo=0x78f840e0 {NSLocalizedRecoverySuggestion=Would you like to connect to the server anyway?, _kCFStreamErrorCodeKey=-9807, NSErrorFailingURLKey=https://merchant.jamja.vn/image/5555b0b3f3c0620faa69b7f3/thumbnail/, NSErrorFailingURLStringKey=https://merchant.jamja.vn/image/5555b0b3f3c0620faa69b7f3/thumbnail/, _kCFStreamErrorDomainKey=3, NSLocalizedDescription=The certificate for this server is invalid. You might be connecting to a server that is pretending to be “merchant.jamja.vn” which could put your confidential information at risk.}
could you tell me how to load type of image?
thanks
Is the ImageManager queueable? Are multiple manager calls concurrent and finish up 'fcfs' or one after the other?
So to say, what happens if you do something like:
ImageManager.fetch(img1, progress: { (progress: Double) in
}, success: { (data: NSData) in
myImage1 = UIImage(data:data)
//do whatever stuff with image
}, failure: { (error: NSError) in
println(error)
})
ImageManager.fetch(img2, progress: { (progress: Double) in
}, success: { (data: NSData) in
myImage2 = UIImage(data:data)
//do whatever stuff with image
}, failure: { (error: NSError) in
println(error)
})
While using library with UICollectionView, inside UICollectionViewDataSource
func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCellWithReuseIdentifier(reuseIdentifier, forIndexPath: indexPath) as PartCollectionViewCell
cell.backgroundColor = UIColor.whiteColor()
//fetch the image
ImageManager.sharedManager.fetch(imagePath,
progress: { (status: Double) in
},success: { (data: NSData) in
cell.ivIcon.image = UIImage(data: data)
}, failure: { (error: NSError) in
cell.ivIcon.image = nil
})
return cell
}
When collectionview reuses the view then images get mixed up.
Let suppose there is cell A, and code made a request for IMG_URL_1 that is 43KB It will take time to load
CollectionView while scrolling reuses cell A again and this time code made a request for IMG_URL_6 for this cell, and this image is only of 6KB, so it will load faster while IMG_URL_1 still in loading process. First view gets updated with IMG_URL_6 image because it loaded early, but after few mili seconds IMG_URL_1 also get loaded so cell will get updated again with IMG_URL_1 this time. But it should display IMG_URL_6 image instead of IMG_URL_1 image.
Seems like advance is deprecated in Swift 2.0, leading to errors here:
ImageManager.swift:
Line 180&181
Line 206
Error: 'advance' is unavailable: call the 'advanceBy(n)' method on the index
Xcode 7.0 (iOS 9)
private func hash(u: String) -> String {
var url = u
let len = count(url)-1
if url[advance(url.startIndex,len)] == "/" {
url = url[url.startIndex..<advance(url.startIndex,len)]
}
let size: Int = count(url)
var hash: Int64 = Int64(size / 2)
for codeUnit in url.utf8 {
hash = hash + (Int(codeUnit) * 101)
}
return "\(hash)"
}
returns same hash for different urls.
https://allappwestus.blob.core.windows.net/images/caef4757-b825-4daa-bdba-283d90144404.jpg
https://allappwestus.blob.core.windows.net/images/5cbd969d-5432-4140-b1af-6ae0d38b05bf.jpg
I think you should change hash function because this is an example that have same hash so load wrong image:
http://media.isna.ir/content/1423553719742_IMAGE11423544834450.jpg/4
http://www.ana.ir/Media/Image/1394/05/30/635757572028226569.jpg
Hi! First Congrat for your Framework.
Why it has only support for ios 8+?
It's Any way to add support for IOS 7???
Thank you!
if self.pending[hash] == nil {
var holder = Array<BlockHolder>()
holder.append(BlockHolder(progress: progress, success: success, failure: failure))
self.pending[hash] = holder
//next check from disk asynchronously
cache.fromDisk(hash, success: { (d: NSData) in
self.doSuccess(hash, data: d)
}, failure: { (Void) in
//lastly fetch from the network asynchronously
let task = HTTPTask()
task.download(url, parameters: nil, progress: { (status: Double) in
self.doProgress(hash, status: status)
}, success: { (response: HTTPResponse) in
self.cache.add(hash, url: response.responseObject! as NSURL)
self.doSuccess(hash, data: self.cache.fromMemory(hash)!)
}, failure: { (error: NSError, response: HTTPResponse?) in
self.doFailure(hash, error: error)
})
})
} else if var array = self.pending[hash] {
array.append(BlockHolder(progress: progress, success: success, failure: failure))
self.pending[hash] = array
}
Getting error:
fatal error: unexpectedly found nil while unwrapping an Optional value
at line self.doSuccess(hash, data: self.cache.fromMemory(hash)!)
Hi! I want to say that Skeets helped me a lot and I want to thank you for that!
I'm facing one problem when I try to load a table view (2 images per cell/row, about 10 rows displayed on the screen). The first time I run the app all the images go crazy while loading. They show up, then they change (different images displayed one after another in the same position) and even after they are all loaded from the server, they remain shuffled. I'm new to programming and maybe I don't fully understand this, but I just can't find a solution. Do you have any idea why this is happening and how can I fix it?
Thanks!
the cells in my collection view will all sometimes display the same image, despite having a different URL. Or occasionally, odd cells will host the wrong picture. Any idea why this is?
When image is not exist on server Skeets crash and trap in exception:
NSLocalizedDescription=The requested URL was not found on this server.}
fatal error: unexpectedly found nil while unwrapping an Optional value
When downloading the data, cell.textLabel!.text will be present but cell.imageView?.image will not show the images unless i run tableView.reload() again. Any reasons why? This is under protocol, func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell
ImageManager.fetch(user.profilePic, progress: { (progress: Double) in
}, success: { (data: NSData) in
cell.imageView?.image = UIImage(data: data)
println("image loaded")
}, failure: { (error: NSError) in
println("failed to get image: \(error)")
})
Now I get an error on first launch of the app (after install). It's in the ImageManager.swift file in:
private func hash(u: String) -> String {
var url = u
let len = count(url)-1
if url[advance(url.startIndex,len)] == "/" {
url = url[url.startIndex..<advance(url.startIndex,len)]
}
var hash: UInt32 = 0
for codeUnit in url.utf8 {
hash += UInt32(codeUnit)
hash ^= (hash >> 6)
}
hash += (hash << 3)
hash ^= (hash >> 11)
hash += (hash << 15)
return "\(hash)"
}
I get "fatal error: can not decrement startIndex" on the forth line. This doesn't happen every time. I need to reset the simulator and install again a few times until I can reproduce this. But once I get this error, I can't launch the app at all and I need to reinstall again. Any ideas what could cause this?
Let suppose we have URL like this that have space in it,
"http://www.clickreadshare.com/wp-content/uploads/bunny-on-a-bed-big .jpg"
Library return an error like this:
fatal error: unexpectedly found nil while unwrapping an Optional value
return self.requestSerializer.createRequest(NSURL(string: urlVal)!,
method: method, parameters: parameters)
}
I think URL encode needs to be added.
I tried to just cache stuff 'per single run' of the application, so in appDelegate I did
func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
let paths = NSSearchPathForDirectoriesInDomains(.CachesDirectory, .UserDomainMask, true)
ImageManager.sharedManager.cache.diskDirectory = "\(paths[0])/ImageCache"
ImageManager.sharedManager.cache.clearCache()
}
interestingly, this has no effect whatsoever, when I change the picture behind mypath.com/test.png it will display an old cached version from last run
cleandisk 时没有考虑到并行,可以用 barrier
cleancache 也是
In the documentation of Skeets one example shows how to specify the cache path.
//set the cache directory. Only have to do this once since `sharedManager` is a singleton
let paths = NSSearchPathForDirectoriesInDomains(.DocumentDirectory, .UserDomainMask, true)
ImageManager.sharedManager.cache.diskDirectory = "\(paths[0])/ImageCache"
My understanding until now was, that the Document Directory (and its subdirectories) is NOT the right choice to store cache data, it even leads to failing the app review process, due to the fact, that the Document Directory gets backed up to the iCloud and cache data is nothing, which we really want to back up in the cloud.
Unless of course we exclude the Directory, which we specified, from the iCloud backup explicitly.
I thought the NSSearchPathDirectory.CachesDirectory would be the appropriate location to store cache data?
Get the following problem using CocoaPods (0.36.0.beta.2).
[!] Invalid `Skeets.podspec` file: undefined method `dependency=' for #<Pod::Specification name="Skeets">. Updating CocoaPods might fix the issue.
source 'https://github.com/CocoaPods/Specs.git'
# from /Users/valzevul/projects/SkeetsExample/Pods/Skeets/Skeets.podspec:11
# -------------------------------------------
# s.source_files = '*.{h,swift}'
> s.dependency = 'SwiftHTTP'
# end
# -------------------------------------------
Is this a problem of Skeets.podspec or CocoaPods problem?
I am not seeing the image pop in as soon as the println() I have in the success block getting called. Would this be an issue only because its a UITableViewCell? It will eventually show the image, but its like 5-8 seconds later, Im guessing this is a built in double check timeout? But I would think it would pop in as soon as that println() gets called. If i stretch the table down do that the last imageview is off and then back on the screen i will see the image but will still have the activity loader showing meaning the success block didn't finish.
var profileImageUrl:String = "" {
didSet {
//fetch the image
ImageManager.fetch(profileImageUrl,
progress: { (status: Double) in
println("\(status)")
self.ProfileImageLoading.startAnimating()
},success: { (data: NSData) in
println("got image")
self.ProfileImage.image = UIImage(data: data) //set the image data
self.ProfileImage.backgroundColor = UIColor.clearColor()
self.ProfileImageLoading.stopAnimating()
}, failure: { (error: NSError) in
self.ProfileImageLoading.stopAnimating()
})
}
}
Thanks,
Dan
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.