user5899631
user5899631

Reputation:

Crash when loading images from coreData

When I launch my app I download several photos from my server which are then saved to coreData like so (I followed this tutorial: Saving Picked Image to CoreData )

extension NewsFeedViewController {



    func getContext() {
        saveQueue.sync {


        let appDelegate = UIApplication.shared.delegate as! AppDelegate
        self.managedContext = appDelegate.persistentContainer.viewContext
        }
    }
}

extension NewsFeedViewController {

    func prepareImageForSaving(image:UIImage) {

        // use date as unique id
        let date : Double = NSDate().timeIntervalSince1970

        // dispatch with gcd.
        convertQueue.async() {
            print("dd")
            // create NSData from UIImage
            guard let imageData = UIImageJPEGRepresentation(image, 1) else {
                // handle failed conversion
                print("jpg error")
                return
            }


            // scale image, I chose the size of the VC because it is easy


            // send to save function
            self.saveImage(imageData: imageData as NSData, date: date)

        }
    }
}

extension NewsFeedViewController {

    func saveImage(imageData:NSData, date: Double) {


        saveQueue.async(flags: .barrier) {

            // create new objects in moc
            guard let moc = self.managedContext else {

                return
            }

            guard let fullRes = NSEntityDescription.insertNewObject(forEntityName: "Blogger", into: moc) as? FullRes else {
                // handle failed new object in moc
                print("moc error")
                return
            }

            //set image data of fullres
            fullRes.imageData = imageData as Data


            // save the new objects
            do {

                 try moc.save()

            } catch {
                fatalError("Failure to save context: \(error)")
            }

            // clear the moc
            moc.refreshAllObjects()
        }

    }

}


extension NewsFeedViewController {

    func loadImages(_ fetched:@escaping (_ images:[FullRes]?) -> Void) {

        saveQueue.async() {
            guard let moc = self.managedContext else {
                return
            }

            let fetchRequest :NSFetchRequest<NSFetchRequestResult> = NSFetchRequest(entityName: "FullRes")
            //let fetchRequest = NSFetchRequest(entityName: "FullRes")//NSFetchRequest(entityName: "FullRes")
            print(fetchRequest)

            do {

                let results = try moc.fetch(fetchRequest)
                let imageData = results as? [FullRes]
                DispatchQueue.main.async() {
                    fetched(imageData)

                }
            } catch let error as NSError {
                print("Could not fetch \(error), \(error.userInfo)")
                return
            }
        }
    }

}

In that code I am preparing the image to be saved - saving it, and then in other parts of my code(not posted here) and checking if there is a internet connection. If there isn't load the images, so I call the loadImages() function which I have posted above.

When calling it I get this error:

enter image description here

If anyone can help me with this, it's much appreciated!!

Upvotes: 1

Views: 163

Answers (2)

David Seek
David Seek

Reputation: 17132

There is no problem in your code. I have implemented your exact code and it is working perfectly. You should now try to isolate your problem. Try to comment functions that are using the Internet like functions handling logged in users and downloading content in general.

Also check your AppDelegate for functions that might cause an early crash once your App starts without internet.

Always try to catch exceptions caused by missing reachability.

For that purpose I'm using the following function:

import Foundation
import SystemConfiguration

open class Reachability {

    class func isConnectedToNetwork() -> Bool {

        var zeroAddress = sockaddr_in()
        zeroAddress.sin_len = UInt8(MemoryLayout.size(ofValue: zeroAddress))
        zeroAddress.sin_family = sa_family_t(AF_INET)

        guard let defaultRouteReachability = withUnsafePointer(to: &zeroAddress , {
            $0.withMemoryRebound(to: sockaddr.self, capacity: 1) {zeroSockAddress in
                SCNetworkReachabilityCreateWithAddress(nil, zeroSockAddress)
            }
        }) else {
            return false
        }

        var flags : SCNetworkReachabilityFlags = []
        if !SCNetworkReachabilityGetFlags(defaultRouteReachability, &flags) {
            return false
        }

        let isReachable = flags.contains(.reachable)
        let needsConnection = flags.contains(.connectionRequired)
        return (isReachable && !needsConnection)
    }

} 

Called by:

if Reachability.isConnectedToNetwork() == true {
    //execute your code
} else {
    //catch print
}

Upvotes: 0

user5899631
user5899631

Reputation:

I changed the let fetchRequest to this

let fetchRequest: NSFetchRequest<NSFetchRequestResult> = FullRes.fetchRequest()

Upvotes: 1

Related Questions