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 Slide

  2. View Slide

  3. ḪΔ͜ͱ
    ಥવͰ͕͢

    View Slide

  4. ໿
    1೥൒

    View Slide

  5. 2017 ೥ 3 ݄ ๭೔

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

  9. QRίʔυ
    ౉͞Εͨ

    View Slide

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

    View Slide

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

    View Slide

  12. View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

  17. φχϞϊ
    ͜Ε͸…

    View Slide

  18. View Slide

  19. http://www.qrcode.com

    View Slide

  20. View Slide

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

    View Slide

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

    View Slide

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

    View Slide


  24. 115 ϖʔδ…

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

  29. “Ϟʔυ” ͱ͸

    View Slide

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

    View Slide

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

    View Slide

  32. ߏ଄త࿈઀
    Ϟʔυ

    View Slide

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

    View Slide

  34. View Slide

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

    View Slide

  36. ͦΜͳ΋ͷͳ͍
    AVMetadataMachineReadableCodeObject ʹ

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide


  40. None
    Swift ੡ͷϥΠϒϥϦ

    View Slide

  41. View Slide

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

    View Slide

  43. γϯϘϧҐஔ/߹ܭ਺ͱύϦςΟ͕औΕΔ
    @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 Slide

  44. γϯϘϧҐஔ/߹ܭ਺ͱύϦςΟ͕औΕΔ
    @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 Slide

  45. γϯϘϧҐஔ/߹ܭ਺ͱύϦςΟ͕औΕΔ
    @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 Slide

  46. γϯϘϧҐஔ/߹ܭ਺ͱύϦςΟ͕औΕΔ
    @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 Slide

  47. ղܾ
    ΍ͬͨʔʂʂ

    View Slide

  48. ຊ౰ʹʁ

    View Slide

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

    View Slide

  50. ઈ๬
    ະདྷ͕ͳ͍

    View Slide

  51. ઈ๬
    ະདྷ͕ͳ͍
    ʁ

    View Slide

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

    View Slide

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

    View Slide

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





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

    View Slide

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

    View Slide

  56. CIQRCodeDescriptor
    ਅͷٹੈओ
    in AVMetadataMachineReadableCodeObject

    View Slide

  57. ϓϩύςΟ
    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 Slide

  58. CIQRCodeDescriptor ͱ͸

    View Slide

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

    View Slide

  60. 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 Slide

  61. େࣄͳͷ͸͜ͷ 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 Slide

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

    View Slide

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

    View Slide

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

    View Slide

  65. େࣄͳͷ͸͜ͷ 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 Slide

  66. େࣄͳͷ͸͜ͷ 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 Slide

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

    View Slide

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

    View Slide

  69. ͱ͍͏͜ͱ͸…ʁ

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

  79. ·ͱΊ

    View Slide



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

    View Slide

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

    View Slide

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

    View Slide