1

I'm generating a QR Code to put into a UIImage. I'm running the generation function asynchronously but for some reason the app crashes when I run it on my phone, but doesn't crash in the simulator. I'm not really sure what's going on... Any ideas?

Setup Image

let QR = UIImageView()

dispatch_async(dispatch_get_global_queue(Int(QOS_CLASS_USER_INITIATED.value), 0)) { // 1

   var img = self.generateQRImage(self.arr[sender.tag],withSizeRate: self.screenWidth-40)
   dispatch_async(dispatch_get_main_queue()) { // 2
       QR.image = img
   }
}

QR.frame = CGRectMake(0,0,screenWidth-40,screenWidth-40)
QR.center = CGPoint(x:screenWidth/2,y:screenHeight/2)
sView.addSubview(QR)

Generate QR

func generateQRImage(stringQR:NSString, withSizeRate rate:CGFloat) -> UIImage
    {
        var filter:CIFilter = CIFilter(name:"CIQRCodeGenerator")
        filter.setDefaults()

        var data:NSData = stringQR.dataUsingEncoding(NSUTF8StringEncoding)!
        filter.setValue(data, forKey: "inputMessage")

        var outputImg:CIImage = filter.outputImage

        var context:CIContext = CIContext(options: nil)
        var cgimg:CGImageRef = context.createCGImage(outputImg, fromRect: outputImg.extent())

        var img:UIImage = UIImage(CGImage: cgimg, scale: 1.0, orientation: UIImageOrientation.Up)!

        var width  = img.size.width * rate
        var height = img.size.height * rate

        UIGraphicsBeginImageContext(CGSizeMake(width, height))
        var cgContxt:CGContextRef = UIGraphicsGetCurrentContext()
        CGContextSetInterpolationQuality(cgContxt, kCGInterpolationNone)
        img.drawInRect(CGRectMake(0, 0, width, height))
        img = UIGraphicsGetImageFromCurrentImageContext()
        UIGraphicsEndImageContext()
        return img
    }
SpaceShroomies
  • 1,635
  • 2
  • 17
  • 23
  • 1
    what the error message say and the what stack trace show? – Icaro May 24 '15 at 10:34
  • 2015-05-24 18:37:41.084 Klikr[279:8851] BSXPCMessage received error for message: Connection interrupted 2015-05-24 18:37:49.401 Klikr[279:8851] Terminating since there is no system app. – SpaceShroomies May 24 '15 at 10:38
  • Have a look in this post it may answer your question http://stackoverflow.com/questions/26065808/bsxpcmessage-received-error-for-message-connection-interrupted – Icaro May 24 '15 at 10:41

1 Answers1

1

The intent of withSizeRate is clearly to be a scaling factor to apply to the QR image (which is 27x27). But you are using the screen width as the multiplier. That results in an exceedingly large image (once it's uncompressed, used in image view; don't go by the size of the resulting JPEG/PNG file). The theoretical internal, uncompressed representation of this image is extremely large (300 mb on iPhone 6 and nearly 400 mb on iPhone 6+). When I ran it through the iPhone 6 simulator, memory usage actually spiked to 2.4 gb:

enter image description here

I would suggest using a smaller scaling factor. Or just create an image that is precisely the size of the imageview (though use zero for the scale with UIGraphicsBeginImageContextWithOptions).


For example, you could simply pass the CGSize of the image view to generateQRImage, and adjust the method like so:

func generateQRImage(stringQR: String, size: CGSize) -> UIImage {
    let filter = CIFilter(name:"CIQRCodeGenerator")
    filter.setDefaults()

    let data = stringQR.dataUsingEncoding(NSUTF8StringEncoding)!
    filter.setValue(data, forKey: "inputMessage")

    let outputImage = filter.outputImage

    let context = CIContext(options: nil)
    let cgImage = context.createCGImage(outputImage, fromRect: outputImage.extent())

    var image = UIImage(CGImage: cgImage, scale: 1.0, orientation: UIImageOrientation.Up)!

    let width  = size.width
    let height = size.height

    UIGraphicsBeginImageContextWithOptions(CGSizeMake(width, height), true, 0)
    let cgContext = UIGraphicsGetCurrentContext()
    CGContextSetInterpolationQuality(cgContext, kCGInterpolationNone)
    image.drawInRect(CGRectMake(0, 0, width, height))
    image = UIGraphicsGetImageFromCurrentImageContext()
    UIGraphicsEndImageContext()

    return image
}
Rob
  • 415,655
  • 72
  • 787
  • 1,044