Upgrade to Pro — share decks privately, control downloads, hide ads and more …

「QRコード読み取り?楽勝ですよ😙」=>「AVFoundationを信じたおれがバカだった😇」 / iOSDC 2018

monoqlo
September 01, 2018

「QRコード読み取り?楽勝ですよ😙」=>「AVFoundationを信じたおれがバカだった😇」 / iOSDC 2018

iOSDC 2018 2018/09/01 14:40〜 Track B レギュラートーク(15分)

monoqlo

September 01, 2018
Tweet

More Decks by monoqlo

Other Decks in Programming

Transcript

  1. @monoqlo
    QRίʔυಡΈऔΓʁ
    ָউͰ͢Α
    AVFoundationΛ৴ͨ͡
    ͓Ε͕όΧͩͬͨ

    View full-size slide

  2. ḪΔ͜ͱ
    ಥવͰ͕͢

    View full-size slide

  3. 2017 ೥ 3 ݄ ๭೔

    View full-size slide

  4. ָউͰ͢Α✌✌
    QRίʔυಡΈऔΔ
    ΞϓϦͭ͘ΕΔʁ

    View full-size slide

  5. ͜ͷ࣌ߟ͍͑ͯͨ͜ͱ

    View full-size slide

  6. AVFoundation Ͱ༨༟Ͱ͠ΐ
    • AVCaptureSession
    • AVCaptureMetadataOutput
    • AVMetadataMachineReadableCodeObject
    • etc…

    View full-size slide

  7. QRίʔυ
    ౉͞Εͨ

    View full-size slide

  8. https://www.55truck.com/shaken.html

    View full-size slide

  9. https://www.55truck.com/shaken.html

    View full-size slide

  10. "8/-/1/-/- /- /999999/02”
    "2/- //160114/1001/BKG-NKR85” "AN/0168/- /- /0381/13/09”
    "2/඼઒ɹɹ̔̌̌ͤ̒̐̎” “̒/1/NKR85-7011300/4JJ1/1"

    View full-size slide

  11. http://mangalifewin.takeshobo.co.jp/rensai/popute3/

    View full-size slide

  12. "8/-/1/-/- /- /999999/02”
    "2/- //160114/1001/BKG-NKR85” "AN/0168/- /- /0381/13/09”
    "2/඼઒ɹɹ̔̌̌ͤ̒̐̎” “̒/1/NKR85-7011300/4JJ1/1"

    View full-size slide

  13. "2/- //160114/1001/BKG-NKR85AN/0168/- /- /0381/13/098/-/1/-/- /- /999999/02”
    "2/඼઒ɹɹ̔̌̌ͤ̒̐̎̒/1/NKR85-7011300/4JJ1/1”

    View full-size slide

  14. φχϞϊ
    ͜Ε͸…

    View full-size slide

  15. http://www.qrcode.com

    View full-size slide

  16. ΋ͬͱ QRίʔυ Λ஌Ζ͏

    View full-size slide

  17. ৘ใٕज़ʵࣗಈೝࣝٴͼσʔλऔಘٕज़ʵ
    ̧̦ίʔυόʔίʔυγϯϘϧମܥ࢓༷
    JIS ن֨ X0510

    View full-size slide

  18. http://www.jisc.go.jp/

    View full-size slide


  19. 115 ϖʔδ…

    View full-size slide

  20. QRίʔυͷ࢓૊Έ
    ௒μΠδΣετ൛

    View full-size slide

  21. ࠇനϞδϡʔϧͷೝࣝ
    START
    ܕࣜ৘ใͷ෮߸
    ܕ൪ͷܾఆ
    ϚεΫॲཧͷղআ
    σʔλ & ޡΓగਖ਼ίʔυޠͷ෮ݩ

    View full-size slide

  22. ޡΓగਖ਼
    ޡΓݕग़
    σʔλΛ෮߸
    σʔλೖख
    END
    ޡΓφγ
    ޡΓΞϦ

    View full-size slide

  23. “Ϟʔυ” ղऍ
    ෮߸͢ΔͨΊʹॏཁͳͷ͕

    View full-size slide

  24. “Ϟʔυ” ͱ͸

    View full-size slide

  25. • ECI
    • ߏ଄త࿈઀
    • FNC1
    • (ऴ୺ύλʔϯ)
    • ਺ࣈ
    • ӳ਺ࣈ
    • 8ϏοτόΠτ
    • ׽ࣈ
    Ϟʔυ = σʔλΛ֨ೲ͢Δܗࣜ
    • ѹॖޮ཰޲্Λ໨తͱ͠ɺଟ਺ͷϞʔυ͕ఆٛ͞Ε͍ͯΔ
    • QRίʔυੜ੒࣌ɺσʔλʹ߹Θͤͯ࠷దͳ΋ͷΛબ୒͢Δ
    • ϔομʔͱͯ͠จࣈ਺ࢦࣔࢠͱͱ΋ʹσʔλʹ෇Ճ͢Δ
    • ૊Έ߹Θͤͯ࢖༻Մʢex. ӳ਺ࣈ + ׽ࣈʣ
    ߏ଄త࿈઀

    View full-size slide

  26. • ਺ࣈ
    • ӳ਺ࣈ
    • 8ϏοτόΠτ
    • ׽ࣈ
    • ECI
    • ߏ଄త࿈઀
    • FNC1
    • (ऴ୺ύλʔϯ)
    Ϟʔυ = σʔλΛ֨ೲ͢Δܗࣜ
    • ѹॖޮ཰޲্Λ໨తͱ͠ɺଟ਺ͷϞʔυ͕ఆٛ͞Ε͍ͯΔ
    • QRίʔυੜ੒࣌ɺσʔλʹ߹Θͤͯ࠷దͳ΋ͷΛબ୒͢Δ
    • ϔομʔͱͯ͠จࣈ਺ࢦࣔࢠͱͱ΋ʹσʔλʹ෇Ճ͢Δ
    • ૊Έ߹Θͤͯ࢖༻Մʢex. ӳ਺ࣈ + ׽ࣈʣ
    ߏ଄త࿈઀

    View full-size slide

  27. ߏ଄త࿈઀
    Ϟʔυ

    View full-size slide

  28. ϔομʔ࢓༷
    1. Ϟʔυࢦࣔࢠʢ0011ʣɿ4bit
    2. γϯϘϧྻࢦࣔࢠɿ8bit
    1. γϯϘϧҐஔɿ4bit
    2. ࿈݁͞ΕΔγϯϘϧͷ߹ܭ਺ɿ4bit
    3. ύϦςΟɿ8bit
    ෼ׂલͷσʔλΛόΠτ͝ͱʹXORԋࢉͨ͠஋

    View full-size slide

  29. ϓϩύςΟ
    var corners: [CGPoint]
    A Swift array of corner points.
    var stringValue: String?
    Returns the error corrected
    data decoded into a human-
    readable string.

    View full-size slide

  30. ͦΜͳ΋ͷͳ͍
    AVMetadataMachineReadableCodeObject ʹ

    View full-size slide

  31. ࠇനϞδϡʔϧͷೝࣝ
    START
    ܕࣜ৘ใͷ෮߸
    ܕ൪ͷܾఆ
    ϚεΫॲཧͷղআ
    σʔλ & ޡΓగਖ਼ίʔυޠͷ෮ݩ

    View full-size slide

  32. ޡΓగਖ਼
    ޡΓݕग़
    σʔλΛ෮߸
    σʔλೖख
    END
    ޡΓφγ
    ޡΓΞϦ
    AVMetadataMachine
    ReadableCodeObject
    ͷ stringValue ͸
    ෳ߹ޙͷίϨ

    View full-size slide

  33. ϥΠϒϥϦΛ୳͢
    ߏ଄త࿈઀Λ͏·͘ѻ͑Δ

    View full-size slide


  34. None
    Swift ੡ͷϥΠϒϥϦ

    View full-size slide

  35. ZXingObjC
    ٹੈओ
    TheLevelUp/ZXingObjC: An Objective-C Port of ZXing

    View full-size slide

  36. γϯϘϧҐஔ/߹ܭ਺ͱύϦςΟ͕औΕΔ
    @objc func captureResult(_ capture: ZXCapture!, result: ZXResult!) {
    guard let _ = result else { return }
    // ෼ׂQRίʔυͷ৔߹ɺZXResult#resultMetadata ͷҎԼ2ͭΛ֬ೝͯ͠
    // Ͳͷ෦෼ͷQRίʔυ͕ಡΈࠐ·Εͨͷ͔൑ఆ͢Δ͜ͱ͕Ͱ͖Δ
    // - kResultMetadataTypeStructuredAppendSequence
    // - kResultMetadataTypeStructuredAppendParity
    guard let metaData = result.resultMetadata,
    let sequenceValue = metaData[Int(kResultMetadataTypeStructuredAppendSequence.rawValue)] as? Int,
    let parity = metaData[Int(kResultMetadataTypeStructuredAppendParity.rawValue)] as? Int
    else { return }
    // sequence: ಡΈऔͬͨQRίʔυͷ൪߸ 4bit + τʔλϧͷQRίʔυ਺ 4bit
    let bit = String(sequenceValue, radix: 2)
    let pad = String(repeating: "0", count: (8 - bit.count))
    let sequence = pad + bit
    let current = Int(sequence.prefix(4), radix: 2)!
    let total = Int(sequence.suffix(from: 4), radix: 2)!

    }
    @objc func captureResult(_ capture: ZXCapture!, result: ZXResult!) {
    guard let _ = result else { return }
    // ෼ׂQRίʔυͷ৔߹ɺZXResult#resultMetadata ͷҎԼ2ͭΛ֬ೝͯ͠
    // Ͳͷ෦෼ͷQRίʔυ͕ಡΈࠐ·Εͨͷ͔൑ఆ͢Δ͜ͱ͕Ͱ͖Δ
    // - kResultMetadataTypeStructuredAppendSequence
    // - kResultMetadataTypeStructuredAppendParity

    View full-size slide

  37. γϯϘϧҐஔ/߹ܭ਺ͱύϦςΟ͕औΕΔ
    @objc func captureResult(_ capture: ZXCapture!, result: ZXResult!) {
    guard let _ = result else { return }
    // ෼ׂQRίʔυͷ৔߹ɺZXResult#resultMetadata ͷҎԼ2ͭΛ֬ೝͯ͠
    // Ͳͷ෦෼ͷQRίʔυ͕ಡΈࠐ·Εͨͷ͔൑ఆ͢Δ͜ͱ͕Ͱ͖Δ
    // - kResultMetadataTypeStructuredAppendSequence
    // - kResultMetadataTypeStructuredAppendParity
    guard let metaData = result.resultMetadata,
    let sequenceValue = metaData[Int(kResultMetadataTypeStructuredAppendSequence.rawValue)] as? Int,
    let parity = metaData[Int(kResultMetadataTypeStructuredAppendParity.rawValue)] as? Int
    else { return }
    // sequence: ಡΈऔͬͨQRίʔυͷ൪߸ 4bit + τʔλϧͷQRίʔυ਺ 4bit
    let bit = String(sequenceValue, radix: 2)
    let pad = String(repeating: "0", count: (8 - bit.count))
    let sequence = pad + bit
    let current = Int(sequence.prefix(4), radix: 2)!
    let total = Int(sequence.suffix(from: 4), radix: 2)!

    }
    @objc func captureResult(_ capture: ZXCapture!, result: ZXResult!) {
    guard let _ = result else { return }
    // ෼ׂQRίʔυͷ৔߹ɺZXResult#resultMetadata ͷҎԼ2ͭΛ֬ೝͯ͠
    // Ͳͷ෦෼ͷQRίʔυ͕ಡΈࠐ·Εͨͷ͔൑ఆ͢Δ͜ͱ͕Ͱ͖Δ
    // - kResultMetadataTypeStructuredAppendSequence
    // - kResultMetadataTypeStructuredAppendParity
    guard let metaData = result.resultMetadata,
    let sequenceValue = metaData[Int(kResultMetadataTypeStructuredAppendSequence.rawValue)] as? Int,
    let parity = metaData[Int(kResultMetadataTypeStructuredAppendParity.rawValue)] as? Int
    else { return }

    View full-size slide

  38. γϯϘϧҐஔ/߹ܭ਺ͱύϦςΟ͕औΕΔ
    @objc func captureResult(_ capture: ZXCapture!, result: ZXResult!) {
    guard let _ = result else { return }
    // ෼ׂQRίʔυͷ৔߹ɺZXResult#resultMetadata ͷҎԼ2ͭΛ֬ೝͯ͠
    // Ͳͷ෦෼ͷQRίʔυ͕ಡΈࠐ·Εͨͷ͔൑ఆ͢Δ͜ͱ͕Ͱ͖Δ
    // - kResultMetadataTypeStructuredAppendSequence
    // - kResultMetadataTypeStructuredAppendParity
    guard let metaData = result.resultMetadata,
    let sequenceValue = metaData[Int(kResultMetadataTypeStructuredAppendSequence.rawValue)] as? Int,
    let parity = metaData[Int(kResultMetadataTypeStructuredAppendParity.rawValue)] as? Int
    else { return }
    // sequence: ಡΈऔͬͨQRίʔυͷ൪߸ 4bit + τʔλϧͷQRίʔυ਺ 4bit
    let bit = String(sequenceValue, radix: 2)
    let pad = String(repeating: "0", count: (8 - bit.count))
    let sequence = pad + bit
    let current = Int(sequence.prefix(4), radix: 2)!
    let total = Int(sequence.suffix(from: 4), radix: 2)!

    }
    @objc func captureResult(_ capture: ZXCapture!, result: ZXResult!) {
    guard let _ = result else { return }
    // ෼ׂQRίʔυͷ৔߹ɺZXResult#resultMetadata ͷҎԼ2ͭΛ֬ೝͯ͠
    // Ͳͷ෦෼ͷQRίʔυ͕ಡΈࠐ·Εͨͷ͔൑ఆ͢Δ͜ͱ͕Ͱ͖Δ
    // - kResultMetadataTypeStructuredAppendSequence
    // - kResultMetadataTypeStructuredAppendParity
    guard let metaData = result.resultMetadata,
    let sequenceValue = metaData[Int(kResultMetadataTypeStructuredAppendSequence.rawValue)] as? Int,
    let parity = metaData[Int(kResultMetadataTypeStructuredAppendParity.rawValue)] as? Int
    else { return }
    // sequence: ಡΈऔͬͨQRίʔυͷ൪߸ 4bit + τʔλϧͷQRίʔυ਺ 4bit
    let bit = String(sequenceValue, radix: 2)
    let pad = String(repeating: "0", count: (8 - bit.count))
    let sequence = pad + bit
    let current = Int(sequence.prefix(4), radix: 2)!
    let total = Int(sequence.suffix(from: 4), radix: 2)!

    }

    View full-size slide

  39. γϯϘϧҐஔ/߹ܭ਺ͱύϦςΟ͕औΕΔ
    @objc func captureResult(_ capture: ZXCapture!, result: ZXResult!) {
    guard let _ = result else { return }
    // ෼ׂQRίʔυͷ৔߹ɺZXResult#resultMetadata ͷҎԼ2ͭΛ֬ೝͯ͠
    // Ͳͷ෦෼ͷQRίʔυ͕ಡΈࠐ·Εͨͷ͔൑ఆ͢Δ͜ͱ͕Ͱ͖Δ
    // - kResultMetadataTypeStructuredAppendSequence
    // - kResultMetadataTypeStructuredAppendParity
    guard let metaData = result.resultMetadata,
    let sequenceValue = metaData[Int(kResultMetadataTypeStructuredAppendSequence.rawValue)] as? Int,
    let parity = metaData[Int(kResultMetadataTypeStructuredAppendParity.rawValue)] as? Int
    else { return }
    // sequence: ಡΈऔͬͨQRίʔυͷ൪߸ 4bit + τʔλϧͷQRίʔυ਺ 4bit
    let bit = String(sequenceValue, radix: 2)
    let pad = String(repeating: "0", count: (8 - bit.count))
    let sequence = pad + bit
    let current = Int(sequence.prefix(4), radix: 2)!
    let total = Int(sequence.suffix(from: 4), radix: 2)!

    }
    @objc func captureResult(_ capture: ZXCapture!, result: ZXResult!) {
    guard let _ = result else { return }
    // ෼ׂQRίʔυͷ৔߹ɺZXResult#resultMetadata ͷҎԼ2ͭΛ֬ೝͯ͠
    // Ͳͷ෦෼ͷQRίʔυ͕ಡΈࠐ·Εͨͷ͔൑ఆ͢Δ͜ͱ͕Ͱ͖Δ
    // - kResultMetadataTypeStructuredAppendSequence
    // - kResultMetadataTypeStructuredAppendParity
    // sequence: ಡΈऔͬͨQRίʔυͷ൪߸ 4bit + τʔλϧͷQRίʔυ਺ 4bit
    let bit = String(sequenceValue, radix: 2)
    let pad = String(repeating: "0", count: (8 - bit.count))
    let sequence = pad + bit
    let current = Int(sequence.prefix(4), radix: 2)!
    let total = Int(sequence.suffix(from: 4), radix: 2)!

    }
    guard let metaData = result.resultMetadata,
    let sequenceValue = metaData[Int(kResultMetadataTypeStructuredAppendSequence.rawValue)] as? Int,
    let parity = metaData[Int(kResultMetadataTypeStructuredAppendParity.rawValue)] as? Int
    else { return }

    View full-size slide

  40. ղܾ
    ΍ͬͨʔʂʂ

    View full-size slide

  41. ZXingObjC ͷऑ఺
    • ಡΈऔΓਫ਼౓͕͋·Γߴ͘ͳ͍
    • AVFoundation ΍σϯιʔެࣜΞϓϦʹൺ΂Δͱ݁ߏ
    ͕͔͔࣌ؒΔ͜ͱ͕͋Δ
    • ։ൃ͕࣮࣭ࢭ·͍ͬͯΔ
    • Swift ʹஔ͖׵͍͑ͨͱ͔ॻ͔ΕͯΔ͚Ͳ͍ͭʹͳΔ
    ͔·ͬͨ͘Θ͔Βͳ͍

    View full-size slide

  42. ઈ๬
    ະདྷ͕ͳ͍

    View full-size slide

  43. ઈ๬
    ະདྷ͕ͳ͍
    ʁ

    View full-size slide

  44. ઈ๬
    ະདྷ͕ͳ͍
    ʁ
    2017 ೥ ൒͹
    ·Ͱͷ͓࿩

    View full-size slide

  45. ࣌͸ྲྀΕ…
    2018 ೥ 9 ݄ 1 ೔

    View full-size slide

  46. iOS ͷόʔδϣϯγΣΞભҠ





    ೥݄ ݄ ݄ ݄ ݄ ೥݄ ݄ ݄ ݄
    iOS 11
    iOS 10
    iOS 9 or
    Earlier
    ※ 2018೥9݄͸༧ଌ

    View full-size slide

  47. iOS 10 ͷαϙʔτ
    ͦΖͦΖ੾Ε·͢ΑͶʁ
    ࠓ݄͸ iOS 12 ͕ϦϦʔε͞Ε·͢

    View full-size slide

  48. CIQRCodeDescriptor
    ਅͷٹੈओ
    in AVMetadataMachineReadableCodeObject

    View full-size slide

  49. ϓϩύςΟ
    var corners: [CGPoint]
    A Swift array of corner points.
    var stringValue: String?
    Returns the error corrected
    data decoded into a human-
    readable string.
    var descriptor:
    CIBarcodeDescriptor?
    A barcode description for use
    in Core Image.

    View full-size slide

  50. CIQRCodeDescriptor ͱ͸

    View full-size slide

  51. CIQRCodeDescriptor ͱ͸
    • iOS 11 Ͱ௥Ճ͞ΕͨڧྗͳΫϥε
    • ந৅Ϋϥε CIBarcodeDescriptor ͷαϒΫϥε
    • QRίʔυΛੜ੒͢ΔͨΊʹඞཁे෼ͳσʔλΛ࣋ͭ
    • CIFilter Ͱ QRίʔυը૾Λੜ੒͢Δ͜ͱ΋Ͱ͖Δ

    View full-size slide

  52. CIQRCodeDescriptor ͱ͸
    • iOS 11 Ͱ௥Ճ͞ΕͨڧྗͳΫϥε
    • ந৅Ϋϥε CIBarcodeDescriptor ͷαϒΫϥε
    • CIFilter Ͱ QRίʔυը૾Λੜ੒͢Δ͜ͱ΋Ͱ͖Δ
    func generateQRCodeImage(from descriptor: CIQRCodeDescriptor) -> UIImage? {
    let inputParams: [String: Any] = ["inputBarcodeDescriptor": descriptor]
    let barcodeCreationFilter = CIFilter(name: "CIBarcodeGenerator",
    parameters: inputParams)
    guard let outputImage = barcodeCreationFilter?.outputImage,
    let cgImage = CIContext().createCGImage(outputImage, from:
    outputImage.extent) else {
    return nil
    }
    return UIImage(cgImage: cgImage)
    }

    View full-size slide

  53. େࣄͳͷ͸͜ͷ 2 ͭ
    var errorCorrectedPayload: Data
    The error-corrected payload containing the
    data encoded in the QR code.
    var symbolVersion: Int
    The version of the QR code.

    View full-size slide

  54. ࠇനϞδϡʔϧͷೝࣝ
    START
    ܕࣜ৘ใͷ෮߸
    ܕ൪ͷܾఆ
    ϚεΫॲཧͷղআ
    σʔλ & ޡΓగਖ਼ίʔυޠͷ෮ݩ

    View full-size slide

  55. ޡΓగਖ਼
    ޡΓݕग़
    σʔλΛ෮߸
    σʔλೖख
    END
    ޡΓφγ
    ޡΓΞϦ
    AVMetadataMachine
    ReadableCodeObject
    ͷ stringValue ͸
    ෳ߹ޙͷίϨ

    View full-size slide

  56. ޡΓగਖ਼
    ޡΓݕग़
    σʔλΛ෮߸
    σʔλೖख
    END
    ޡΓφγ
    ޡΓΞϦ
    errorCorrectedPayload ͸
    ίίͷσʔλʂ

    View full-size slide

  57. େࣄͳͷ͸͜ͷ 2 ͭ
    var errorCorrectedPayload: Data
    The error-corrected payload containing the
    data encoded in the QR code.
    var symbolVersion: Int
    The version of the QR code.

    View full-size slide

  58. େࣄͳͷ͸͜ͷ 2 ͭ
    var errorCorrectedPayload: Data
    The error-corrected payload containing the
    data encoded in the QR code.
    var symbolVersion: Int
    The version of the QR code.

    View full-size slide

  59. จࣈ਺ࢦࣔࢠͷϏοτ਺
    ܕ൪
    TZNCPM7FSTJPO
    ਺ࣈ
    Ϟʔυ
    ӳ਺ࣈ
    Ϟʔυ
    ϏοτόΠτ
    Ϟʔυ
    ׽ࣈ
    Ϟʔυ
    ʙ
    ʙ
    ʙ

    View full-size slide

  60. symbolVersion
    +
    errorCorrectedPayload
    σίʔυͰ͖Δ

    View full-size slide

  61. ͱ͍͏͜ͱ͸…ʁ

    View full-size slide

  62. iOS 11 Ҏ߱ͷੈքͰ͸
    1. AVCaptureSession
    ͰಡΈऔΔ
    ߴਫ਼౓Ͱ଎͍

    View full-size slide

  63. iOS 11 Ҏ߱ͷੈքͰ͸
    AVMetadata
    Machine
    ReadableCode
    Object
    2. CIQRCodeDescriptor
    #errorCorrectedPayload
    ΛऔΓग़͢
    1. AVCaptureSession
    ͰಡΈऔΔ

    View full-size slide

  64. iOS 11 Ҏ߱ͷੈքͰ͸
    AVMetadata
    Machine
    ReadableCode
    Object
    2. CIQRCodeDescriptor
    #errorCorrectedPayload
    ΛऔΓग़͢ σίʔυ͢Δ
    1. AVFoundation
    ͰಡΈऔΔ ͕Μ͹ͬͯ
    3.

    View full-size slide

  65. ղܾ
    ΍ͬͨʔʂʂࠓ౓ͦ͜

    View full-size slide

  66. σίʔυ͢Δ
    ͕Μ͹ͬͯ
    3.
    ͕Μ͹ͬͯ

    View full-size slide

  67. ͕Μ͹Δ = ࣗલͰσίʔυॲཧΛॻ͘

    View full-size slide

  68. ࣗલσίʔυͷํ਑
    • શϞʔυʹରԠ͠Α͏ͱࢥͬͨΒʢͨͿΜʣ݁ߏେม…
    • ͱ͍͏͔σϯιʔެࣜΞϓϦ΋ରԠͯ͠ͳ͍
    • ࠷௿ݶಡΈऔΓ͍ͨQRίʔυͷσίʔυॲཧͰଥڠ
    • ಠࣗΤϯίʔυ͞ΕͨQRίʔυ΋σίʔυͰ͖Δ͠ɺ
    ෯͕޿͕Δʢͱ͔ॻ͍ͯΔ͏ͪʹσϯιʔ͕Ԍ্͠·ͨ͠ʣ
    => https://srad.jp/submission/78134/

    View full-size slide

  69. σίʔυͷҰྫ
    https://github.com/
    monoqlo/QRCodeReader

    View full-size slide

  70. ࣌ؒ͋Ε͹
    গ͚ͩ͠ DEMO

    View full-size slide



  71. 0. iOS 10 ͷαϙʔτΛ੾ΔʢҰ൪େࣄʣ

    View full-size slide

  72. ·ͱΊʢiOS 11 Ҏ߱ͷੈքʣ
    1. AVCaptureSession
    ͰಡΈऔΔ
    AVMetadata
    Machine
    ReadableCode
    Object
    2. CIQRCodeDescriptor
    #errorCorrectedPayload
    ΛऔΓग़͢
    ͕Μ͹ͬͯσίʔυ͢Δ
    3.

    View full-size slide

  73. Appendix
    • Speaker Info
    @monoqlo
    • This Slide URL
    https://speakerdeck.com/monoqlo/iosdc-2018

    View full-size slide