Is there a standard way to generate a QR code and attach it to a mail item from iOS client app (no server code)?
-
1tried, if you have any useful tutorial it will be great... – user1561181 Aug 21 '12 at 08:54
8 Answers
Since iOS 7, you can use a Core Image filter to generate QR images. See the final tip here:
- (CIImage *)createQRForString:(NSString *)qrString {
NSData *stringData = [qrString dataUsingEncoding: NSISOLatin1StringEncoding];
CIFilter *qrFilter = [CIFilter filterWithName:@"CIQRCodeGenerator"];
[qrFilter setValue:stringData forKey:@"inputMessage"];
return qrFilter.outputImage;
}
-
2
-
1Look in the link for the function: createNonInterpolatedUIImageFromCIImage – quarac Apr 30 '14 at 22:38
-
1You should be using `NSISOLatin1StringEncoding` rather than UTF-8 according to the docs. – T Blank Mar 08 '15 at 05:28
-
Thanks Travis, answer updated with NSISOLatin1StringEncoding, docs are in https://developer.apple.com/library/mac/documentation/GraphicsImaging/Reference/CoreImageFilterReference/index.html#//apple_ref/doc/filter/ci/CIQRCodeGenerator – quarac Mar 09 '15 at 10:08
-
24if the qr code is blurry, try this. CIImage *image = [self createQRForString:qrString]; CGAffineTransform transform = CGAffineTransformMakeScale(5.0f, 5.0f); // Scale by 5 times along both dimensions CIImage *output = [image imageByApplyingTransform: transform]; – kevinl May 13 '15 at 18:24
-
@kevinl: your code work fine on the simulator. But for the real devices it's still blur. What should I do to make it clear? – vichhai Dec 07 '15 at 02:23
-
2I use kevin's solution to make image not blur, it works on real device. – haxpor Mar 27 '18 at 19:24
-
@kevinl To add on to what Kevin has said, you can also apply, to any imageView that may be scaling arbitrarily (like a scrollview zoom), a nearest neighbor interpolation since all visual data in a QR Code is orthogonal, this will cause sharp/crisp edges when scaling, set the .layer.minificationFilter and .layer.magnificationLayer to `kCAFilterNearest` – Albert Renshaw Oct 19 '19 at 21:27
-
1Note: Make Sure you convert the CIImage to a UIImage using CGContext, if you just use `UIImage imageWithCIImage:` you will get a bmp formatted image which causes `contentMode` to fail on certain architectures. For example, on my iPhone-11 (arm64) aspectFit worked with the UIImage from CIImage but on my iPhone-X (armv7s) it failed and fell back to scaleToFill (which makes QR codes not work). Detailed Explanation here: https://stackoverflow.com/a/15886422/2057171 – Albert Renshaw Jun 03 '20 at 22:43
-
1@AlbertRenshaw Thank you! Without doing that I wasn't able to see any image at all inside of a SwiftUI view. – Kilian Sep 23 '21 at 20:07
For Obj-C version that perfectly works for me, I've mixed answers पवन and Teja Kumar Bethina:
NSString *qrString = @"My string to encode";
NSData *stringData = [qrString dataUsingEncoding: NSUTF8StringEncoding];
CIFilter *qrFilter = [CIFilter filterWithName:@"CIQRCodeGenerator"];
[qrFilter setValue:stringData forKey:@"inputMessage"];
[qrFilter setValue:@"H" forKey:@"inputCorrectionLevel"];
CIImage *qrImage = qrFilter.outputImage;
float scaleX = self.qrImageView.frame.size.width / qrImage.extent.size.width;
float scaleY = self.qrImageView.frame.size.height / qrImage.extent.size.height;
qrImage = [qrImage imageByApplyingTransform:CGAffineTransformMakeScale(scaleX, scaleY)];
self.qrImageView.image = [UIImage imageWithCIImage:qrImage
scale:[UIScreen mainScreen].scale
orientation:UIImageOrientationUp];

- 1,117
- 11
- 20
Using Swift 2
import UIKit
import CoreImage
func createQRFromString(str: String) -> CIImage? {
let stringData = str.dataUsingEncoding(NSUTF8StringEncoding)
let filter = CIFilter(name: "CIQRCodeGenerator")
filter?.setValue(stringData, forKey: "inputMessage")
filter?.setValue("H", forKey: "inputCorrectionLevel")
return filter?.outputImage
}
if let img = createQRFromString("Hello world program created by someone") {
let somImage = UIImage(CIImage: img, scale: 1.0, orientation: UIImageOrientation.Down)
}
Swift 3.0
import UIKit
import CoreImage
func createQRFromString(_ str: String) -> CIImage? {
let stringData = str.data(using: String.Encoding.utf8)
let filter = CIFilter(name: "CIQRCodeGenerator")
filter?.setValue(stringData, forKey: "inputMessage")
filter?.setValue("H", forKey: "inputCorrectionLevel")
if let img = createQRFromString("Hello world program created by someone") {
let somImage = UIImage(ciImage: img, scale: 1.0, orientation: UIImageOrientation.down)
}
return filter?.outputImage
}
if let img = createQRFromString("Hello world program created by someone") {
let somImage = UIImage(ciImage: img, scale: 1.0, orientation: UIImageOrientation.down)
}
Swift 4.2
private func createQRFromString(str: String) -> CIImage? {
let stringData = str.data(using: .utf8)
let filter = CIFilter(name: "CIQRCodeGenerator")
filter?.setValue(stringData, forKey: "inputMessage")
filter?.setValue("H", forKey: "inputCorrectionLevel")
return filter?.outputImage
}
var qrCode: UIImage? {
if let img = createQRFromString(str: "Hello world program created by someone") {
let someImage = UIImage(
ciImage: img,
scale: 1.0,
orientation: UIImage.Orientation.down
)
return someImage
}
return nil
}
Xcode 12.4 or Swift version >= 5.2
import UIKit
import CoreImage
func createQRFromString(str: String) -> CIImage? {
let stringData = str.data(using: .utf8)
let filter = CIFilter(name: "CIQRCodeGenerator")
filter?.setValue(stringData, forKey: "inputMessage")
filter?.setValue("H", forKey: "inputCorrectionLevel")
return filter?.outputImage
}
if let img = createQRFromString(str: "Hello world program created by someone") {
let somImage = UIImage(ciImage: img, scale: 1.0, orientation: .down)
}

- 3,199
- 1
- 25
- 32
It has been a while since this question was asked and a number of almost perfect answers have been given already. However I had to tweak and combine several answers to get it working perfectly for AppleTV 4K, iPhone X and iPadPro using Xcode 9.2 in 2018. Here's the code if anyone needs it.
@IBOutlet weak var qrCodeBox: UIImageView!
func createQRFromString(_ str: String, size: CGSize) -> UIImage {
let stringData = str.data(using: .utf8)
let qrFilter = CIFilter(name: "CIQRCodeGenerator")!
qrFilter.setValue(stringData, forKey: "inputMessage")
qrFilter.setValue("H", forKey: "inputCorrectionLevel")
let minimalQRimage = qrFilter.outputImage!
// NOTE that a QR code is always square, so minimalQRimage..width === .height
let minimalSideLength = minimalQRimage.extent.width
let smallestOutputExtent = (size.width < size.height) ? size.width : size.height
let scaleFactor = smallestOutputExtent / minimalSideLength
let scaledImage = minimalQRimage.transformed(
by: CGAffineTransform(scaleX: scaleFactor, y: scaleFactor))
return UIImage(ciImage: scaledImage,
scale: UIScreen.main.scale,
orientation: .up)
}
override func viewDidLoad() {
super.viewDidLoad()
let myQRimage = createQRFromString("https://www.apple.com",
size: qrCodeBox.frame.size)
qrCodeBox.image = myQRimage
}

- 667
- 4
- 10
-
There's actually a small bug here. You have to multiply `scaledImage` by `UIScreen.main.scale` or the final UIImage will be too small. For example on an iPhone X with screen scale of 3.0, if you try and make a 300x300 QR code the final UIImage will be 100x100 if you use this code as-is. – Ben Baron Mar 14 '19 at 00:33
Code to generate QR image in Swift 2.0.
let reqStr = “string to convert as QR code”
let data = reqStr.dataUsingEncoding(NSISOLatin1StringEncoding, allowLossyConversion: false)
let filter = CIFilter(name: "CIQRCodeGenerator")
filter!.setValue(data, forKey: "inputMessage")
let qrImage:CIImage = filter!.outputImage!
//qrImageView is a IBOutlet of UIImageView
let scaleX = qrImageView.frame.size.width / qrImage.extent.size.width
let scaleY = qrImageView.frame.size.height / qrImage.extent.size.height
let resultQrImage = qrImage.imageByApplyingTransform(CGAffineTransformMakeScale(scaleX, scaleY))
qrImageView.image = UIImage(CIImage: resultQrImage)

- 3,486
- 26
- 34
...which will let me generate links...
First, you need to find a short link service, e.g. bit.ly or goo.by, to make a long link shorter and thus reduce QR Code size.
To perform this task automatically you will have to use some web service.
...then generate a QR code...
ZXing is a popular open source QR Code generator also available for iOS

- 27
- 5
-
-
You are sure to ZXing libarary avaliable for QR Code in iOS? @Avivo – Yogendra Patel Jun 02 '17 at 04:40
-
[ZXingObjC](https://github.com/TheLevelUp/ZXingObjC) is an Objective C implementation of ZXing. It should be usable with Swift by using a bridging header file. – jpat827 Sep 27 '17 at 14:07
If you don't mind using public api, here is an easy 10 seconds method. http://goqr.me/api
Just fill in the data parameter, and load the image from the response. Cheers.

- 1,491
- 18
- 17
I created a NSString Category for Obj-C, taking Mike Demidov awesome answer
NString+GGQRCode.h
#import <Foundation/Foundation.h>
#import <UIKit/UIKit.h>
@interface NSString (GGQRCode)
-(UIImage *)qrCodeImage:(CGFloat)width height:(CGFloat)height;
-(UIImage *)qrCodeImage:(CGFloat)width height:(CGFloat)height scale:(CGFloat)scale orientation:(UIImageOrientation)orientation;
@end
NString+GGQRCode.m
#import "NSString+GGQRCode.h"
@implementation NSString (GGQRCode)
-(UIImage *)qrCodeImage:(CGFloat)width height:(CGFloat)height
{
return [self qrCodeImage:width height:height scale:[UIScreen mainScreen].scale orientation:UIImageOrientationUp];
}
-(UIImage *)qrCodeImage:(CGFloat)width height:(CGFloat)height scale:(CGFloat)scale orientation:(UIImageOrientation)orientation
{
NSData *stringData = [self dataUsingEncoding: NSUTF8StringEncoding];
CIFilter *qrFilter = [CIFilter filterWithName:@"CIQRCodeGenerator"];
[qrFilter setValue:stringData forKey:@"inputMessage"];
[qrFilter setValue:@"H" forKey:@"inputCorrectionLevel"];
CIImage *qrImage = qrFilter.outputImage;
float scaleX = width / qrImage.extent.size.width;
float scaleY = height / qrImage.extent.size.height;
qrImage = [qrImage imageByApplyingTransform:CGAffineTransformMakeScale(scaleX, scaleY)];
return [UIImage imageWithCIImage:qrImage scale:scale orientation:orientation];
}
@end

- 500
- 6
- 8