質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.50%
Xcode

Xcodeはソフトウェア開発のための、Appleの統合開発環境です。Mac OSXに付随するかたちで配布されています。

Swift

Swiftは、アップルのiOSおよびOS Xのためのプログラミング言語で、Objective-CやObjective-C++と共存することが意図されています

Q&A

1回答

606閲覧

Swift , Xcode : バーコードリーダーを作りたい

kimkim

総合スコア142

Xcode

Xcodeはソフトウェア開発のための、Appleの統合開発環境です。Mac OSXに付随するかたちで配布されています。

Swift

Swiftは、アップルのiOSおよびOS Xのためのプログラミング言語で、Objective-CやObjective-C++と共存することが意図されています

0グッド

0クリップ

投稿2018/02/26 07:51

編集2022/01/12 10:55

タイトルの通り、現在作成中のアプリにバーコードリーダー機能を追加したいと思っています。
環境はXcode(Version:9.2),Swift4.0です。

https://qiita.com/ryokosuge/items/c903e04da555294299ae
上記のリンクを参考にし、自分なりにエラーなどを直して以下のようなコードを書きました。

swift

1//BarCordView.swift 2 3import UIKit 4import AVFoundation 5 6final class BarCordView: UIViewController { 7 8 @IBOutlet weak var captureView: UIView! 9 10 @IBOutlet weak var resultTextLabel: UILabel! 11 12 private lazy var captureSession: AVCaptureSession = AVCaptureSession() 13 private lazy var captureDevice: AVCaptureDevice = AVCaptureDevice.default(for: AVMediaType.video)! 14 private lazy var capturePreviewLayer: AVCaptureVideoPreviewLayer = { 15 let layer = AVCaptureVideoPreviewLayer(session: self.captureSession) 16 return layer 17 }() 18 19 private var captureInput: AVCaptureInput? = nil 20 private lazy var captureOutput: AVCaptureMetadataOutput = { 21 let output = AVCaptureMetadataOutput() 22 output.setMetadataObjectsDelegate(self as? AVCaptureMetadataOutputObjectsDelegate, queue: DispatchQueue.main) 23 return output 24 }() 25 26 override func viewDidLoad() { 27 super.viewDidLoad() 28 29 // Do any additional setup after loading the view, typically from a nib. 30 setupBarcodeCapture() 31 } 32 33 override func viewDidLayoutSubviews() { 34 super.viewDidLayoutSubviews() 35 capturePreviewLayer.frame = self.captureView?.bounds ?? CGRect.zero 36 } 37 38 override func didReceiveMemoryWarning() { 39 super.didReceiveMemoryWarning() 40 // Dispose of any resources that can be recreated. 41 } 42 43 // MARK: - private 44 private func setupBarcodeCapture() { 45 do { 46 captureInput = try AVCaptureDeviceInput(device: captureDevice) 47 captureSession.addInput(captureInput!) 48 captureSession.addOutput(captureOutput) 49 captureOutput.metadataObjectTypes = captureOutput.availableMetadataObjectTypes 50 capturePreviewLayer.frame = self.captureView?.bounds ?? CGRect.zero 51 capturePreviewLayer.videoGravity = AVLayerVideoGravity.resizeAspectFill 52 captureView?.layer.addSublayer(capturePreviewLayer) 53 captureSession.startRunning() 54 } catch let error as NSError { 55 print(error) 56 } 57 } 58 59 private func convartISBN(value: String) -> String? { 60 let v = NSString(string: value).longLongValue 61 let prefix: Int64 = Int64(v / 10000000000) 62 guard prefix == 978 || prefix == 979 else { return nil } 63 let isbn9: Int64 = (v % 10000000000) / 10 64 var sum: Int64 = 0 65 var tmpISBN = isbn9 66 /* 67 for var i = 10; i > 0 && tmpISBN > 0; i -= 1 { 68 let divisor: Int64 = Int64(pow(10, Double(i - 2))) 69 sum += (tmpISBN / divisor) * Int64(i) 70 tmpISBN %= divisor 71 } 72 */ 73 74 var i = 10 75 while i > 0 && tmpISBN > 0 { 76 let divisor: Int64 = Int64(pow(10, Double(i - 2))) 77 sum += (tmpISBN / divisor) * Int64(i) 78 tmpISBN %= divisor 79 i -= 1 80 } 81 82 let checkdigit = 11 - (sum % 11) 83 return String(format: "%lld%@", isbn9, (checkdigit == 10) ? "X" : String(format: "%lld", checkdigit % 11)) 84 } 85} 86 87extension BarCordView: AVCaptureMetadataOutputObjectsDelegate { 88 89 func captureOutput(captureOutput: AVCaptureOutput!, didOutputMetadataObjects metadataObjects: [AnyObject]!, fromConnection connection: AVCaptureConnection!) { 90 self.captureSession.stopRunning() 91 guard let objects = metadataObjects as? [AVMetadataObject] else { return } 92 var detectionString: String? = nil 93 let barcodeTypes = [AVMetadataObject.ObjectType.ean8, AVMetadataObject.ObjectType.ean13] 94 for metadataObject in objects { 95 loop: for type in barcodeTypes { 96 guard metadataObject.type == type else { continue } 97 guard self.capturePreviewLayer.transformedMetadataObject(for: metadataObject) is AVMetadataMachineReadableCodeObject else { continue } 98 if let object = metadataObject as? AVMetadataMachineReadableCodeObject { 99 detectionString = object.stringValue 100 break loop 101 } 102 } 103 var text = "" 104 guard let value = detectionString else { continue } 105 text += "読み込んだ値:\t(value)" 106 text += "\n" 107 guard let isbn = convartISBN(value: value) else { continue } 108 text += "ISBN:\t(isbn)" 109 resultTextLabel?.text = text 110 let URLString = String(format: "http://amazon.co.jp/dp/%@", isbn) 111 guard let URL = NSURL(string: URLString) else { continue } 112 UIApplication.shared.open(URL as URL, options: [:], completionHandler: { result in 113 print(result)}) // → true) 114 } 115 self.captureSession.startRunning() 116 } 117} 118

これはバーコードを読み取って、そこからISBNを取得し、Amazonの商品ページに飛ばしているらしいのですが、実機でデバックし、カメラにバーコードを移しても何も反応しません。
これとは違うコードでもいいのですが、バーコードリーダーを実装する方法を教えていただきたいです。

ちなみに読みとったバーコードは以下です。
イメージ説明

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

fuzzball

2018/02/26 08:05

参考記事はSwift2ではないかと思うのですが、Swift3/4に変更していますか?(AVCaptureMetadataOutputObjectsDelegateとか名前変わってますし)あと、不要なタグを削除して下さい。
kimkim

2018/02/26 08:11

自分なりに変更したつもりなのですが、初心者のため合っているのかわかりません。。。一応エラーなくコンパイルはできています。(AVCaptureMetadataOutputObjectsDelegateはエラーが出ていないのでそのままにしています。。。) すみません。タグとはどれのことでしょう?
fuzzball

2018/02/26 08:15 編集

Swift2を使っていないなら「Swift2」は不要です。Xcodeも同じく「Xcode 7」「Xcode 4」は不要でしょう。余計なタグを付ける前に、質問内に自分の環境を書いて下さい。
guest

回答1

0

とりあえず。

AVCaptureMetadataOutputObjectsDelegate
metadataOutput(_:didOutput:from:)

コピペするか、Xcodeの補完を利用して下さい。

投稿2018/02/26 08:19

fuzzball

総合スコア16731

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

kimkim

2018/02/26 08:43

自分なりに補完してみたのですが、どうもうまくいきません。 具体的にどこをどのように変更すればいいのか教えていただくことは可能でしょうか?
fuzzball

2018/02/26 08:55

「自分なりに」じゃなくて、なぜXcodeの補完を使わないのでしょうか? 回答に書いたリンク先のコピペでもいいのですが、コピペも出来ないのでしょうか?
errolizer

2019/03/24 08:59

このプログラムが想定通りに動かない原因は、AVCaptureMetadataOutputObjectsDelegate プロトコルのデリゲートメソッドのひとつである func metadataOutput(AVCaptureMetadataOutput, didOutput: [AVMetadataObject], from: AVCaptureConnection) が無いからです。 上記のデリゲートメソッドを記述すればちゃんと動きましたよ。 公式はこちらです。 https://developer.apple.com/documentation/avfoundation/avcapturemetadataoutputobjectsdelegate Xcodeの補完機能を使う方法ですが関連文字を打つだけです。この場合「meta」とか「didout」と入力すれば目的のメソッドが出てきます。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだベストアンサーが選ばれていません

会員登録して回答してみよう

アカウントをお持ちの方は

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.50%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問