I have an app which is loading a lot of image data from a web server. The data is being saved onto the ipad via:
func saveParsedObject(objectToSave:AnyObject,dataCode:Int)
{
var path:String! = self.convertDataCodeToPath(dataCode)
println( "saveParsedObject - object::\(objectToSave)")
if NSKeyedArchiver.archiveRootObject(objectToSave, toFile: path)
{
println("Success writing parsed object to file!")
}
else
{
println("Unable to write parsed object to file!")
}
}
The data is later opened with :
func loadParsedObject(dataCode:Int) -> AnyObject?
{
var path:String! = self.convertDataCodeToPath(dataCode)
println( " ****** path = \(path) ****** ")
var dataFromDisk:AnyObject?
dataFromDisk = NSKeyedUnarchiver.unarchiveObjectWithFile(path)
println( " ****** dataFromDisk = \(dataFromDisk) ****** ")
return dataFromDisk
}
The image data is saved with this code:
if let imgURLString = imageURLString
{
println(" ////// Image is not nil /////// ")
let imageURL = NSURL(string: imageURLString)
let imageData = NSData(contentsOfURL: imageURL!)
//println(imageData)
if let imgData = imageData
{
self.productImage = UIImage(data: imageData!)
}
else
{
println("Image data = nil")
//println(productName)
}
}
Since the data is not saved with UIImage(contentsOfFile:String)
it is being cached when I later do this:
if let isProductImgNil = productModel.productImage?
{
println(" -- product image is not nil -- ")
// productView is my custom view for my productData which is in my productModel object
productView.backgroundImage.image = productModel.productImage?
//productView.backgroundImage is a UIImageView
//productModel.productImage is a UIImage
}
I found these links and tried to use them in order for the Images to not be cached. However, the problem is far greater. I need to download a Image, save it to the HDD and the load it with contentsOfFile
which accepcts a string not NSData
object and I have no clue how to do this correctly or even if this approach does make sense.
Here are the links:
(1) Swift + Save and Load Image From DocumentDirectory
(2) SO: basic UIImage memory managment
(3) SO: My error but with local images located in .xcassets
Solution 1
Result: This is what I have done in the start (explained in (4)) Data is being cached but not loaded twice, app crashes after some time (explained in (3)
Code above
Solution 2
Result: Data is being cached and loaded again (even worse). Crashes much faster...
Code
Saving data when parsing it (used link (1)):
if let imgURLString = imageURLString
{
println(" ////// Image is not nil /////// ")
let imageURL = NSURL(string: imageURLString)
let imageData = NSData(contentsOfURL: imageURL!)
var selectedImage = UIImage(data:imageData!)
let fileManager = NSFileManager.defaultManager()
var paths = NSSearchPathForDirectoriesInDomains(.DocumentDirectory, .UserDomainMask, true)[0] as String
var filePathToWrite = "\(paths)/\(imageURLString.lastPathComponent)"
var imageData1: NSData = UIImagePNGRepresentation(selectedImage)
fileManager.createFileAtPath(filePathToWrite, contents: imageData1, attributes: nil)
var getImagePath = paths.stringByAppendingPathComponent(imageURLString.lastPathComponent)
finalImagePath = getImagePath
if (fileManager.fileExistsAtPath(getImagePath))
{
println(" --------------- ")
println(" Model - FILE AVAILABLE");
println(getImagePath)
println(" --------------- ")
//Pick Image and Use accordingly
//var imageis: UIImage = UIImage(contentsOfFile: getImagePath)!
//let data: NSData = UIImagePNGRepresentation(imageis)
}
else
{
println(" Model - FILE NOT AVAILABLE");
}
}
And loading data:
let fileManager = NSFileManager.defaultManager()
if (fileManager.fileExistsAtPath(productModel.finalImagePath!))
{
println("FILE AVAILABLE");
productView.backgroundImage.image = UIImage(contentsOfFile:productModel.finalImagePath)!
}
else
{
println(" - - - - - ")
println(productModel.finalImagePath!)
println("FILE NOT AVAILABLE");
}
Take note of:
productView.backgroundImage.image = UIImage(contentsOfFile:productModel.finalImagePath)!
which doesn't help with caching... but loads the image into the view.
Any suggestions are welcome. I am going to try some other stuff in a smaller project because maybe it is a project problem.
I will also try to implement the object pool DP, but somehow I think it is not going to help much since one category has 202 products and the memory jumps to about 250-300 MB. If I open anything else I recieve memory warnings. Few more memory spikes and the app crashes.
I might also try dynamic loading since the products are being loaded into a UIScrollView but that is going to be a lot of work since I don't have much time. And yes I know I should have gone with CoreData, but I didn't have the time to learn it. App has to be done in about 40 days (not much time left) and I am new to swift :). Thanks for your help :).