diff --git a/.swiftpm/xcode/package.xcworkspace/contents.xcworkspacedata b/.swiftpm/xcode/package.xcworkspace/contents.xcworkspacedata
new file mode 100644
index 0000000..919434a
--- /dev/null
+++ b/.swiftpm/xcode/package.xcworkspace/contents.xcworkspacedata
@@ -0,0 +1,7 @@
+
+
+
+
+
diff --git a/BarcodeScanner.podspec b/BarcodeScanner.podspec
index f84e366..5acd641 100644
--- a/BarcodeScanner.podspec
+++ b/BarcodeScanner.podspec
@@ -1,7 +1,7 @@
Pod::Spec.new do |s|
s.name = "BarcodeScanner"
s.summary = "Simple and beautiful barcode scanner."
- s.version = "5.0.0"
+ s.version = "5.0.1"
s.homepage = "https://github.com/hyperoslo/BarcodeScanner"
s.license = 'MIT'
s.author = { "Hyper Interaktiv AS" => "ios@hyper.no" }
diff --git a/BarcodeScanner.xcodeproj/project.pbxproj b/BarcodeScanner.xcodeproj/project.pbxproj
index 4b26f59..a961262 100644
--- a/BarcodeScanner.xcodeproj/project.pbxproj
+++ b/BarcodeScanner.xcodeproj/project.pbxproj
@@ -8,11 +8,9 @@
/* Begin PBXBuildFile section */
2DBF9E0E1F169DEF006B5AA8 /* FocusViewType.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2DBF9E0D1F169DEF006B5AA8 /* FocusViewType.swift */; };
+ AA8BA41623CCA895002F447D /* Localizable.strings in Resources */ = {isa = PBXBuildFile; fileRef = AA8BA40F23CCA895002F447D /* Localizable.strings */; };
+ CE8C0771252FBBAF007FF4A4 /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = CE8C0770252FBBAF007FF4A4 /* Images.xcassets */; };
D504555F1FD8714700E46826 /* UIView+Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = D504555E1FD8714700E46826 /* UIView+Extensions.swift */; };
- D50BE3E91C9FE7A80000A34C /* flashOff@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = D50BE3E51C9FE7A80000A34C /* flashOff@3x.png */; };
- D50BE3EA1C9FE7A80000A34C /* flashOn@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = D50BE3E61C9FE7A80000A34C /* flashOn@3x.png */; };
- D50BE3EB1C9FE7A80000A34C /* info@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = D50BE3E71C9FE7A80000A34C /* info@3x.png */; };
- D5349DF8201E42D900CD53EA /* cameraRotate@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = D5349DF7201E42D900CD53EA /* cameraRotate@3x.png */; };
D55281B62016758F00FF3CDD /* HeaderViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = D55281B52016758F00FF3CDD /* HeaderViewController.swift */; };
D55281B8201675D500FF3CDD /* MessageViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = D55281B7201675D500FF3CDD /* MessageViewController.swift */; };
D55281BA2016770800FF3CDD /* CameraViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = D55281B92016770800FF3CDD /* CameraViewController.swift */; };
@@ -28,11 +26,14 @@
/* Begin PBXFileReference section */
2DBF9E0D1F169DEF006B5AA8 /* FocusViewType.swift */ = {isa = PBXFileReference; fileEncoding = 4; indentWidth = 2; lastKnownFileType = sourcecode.swift; path = FocusViewType.swift; sourceTree = ""; tabWidth = 2; };
+ AA8BA41023CCA895002F447D /* de */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = de; path = de.lproj/Localizable.strings; sourceTree = ""; };
+ AA8BA41123CCA895002F447D /* ja */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = ja; path = ja.lproj/Localizable.strings; sourceTree = ""; };
+ AA8BA41223CCA895002F447D /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/Localizable.strings; sourceTree = ""; };
+ AA8BA41323CCA895002F447D /* tr */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = tr; path = tr.lproj/Localizable.strings; sourceTree = ""; };
+ AA8BA41423CCA895002F447D /* fr */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = fr; path = fr.lproj/Localizable.strings; sourceTree = ""; };
+ AA8BA41523CCA895002F447D /* pl-PL */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "pl-PL"; path = "pl-PL.lproj/Localizable.strings"; sourceTree = ""; };
+ CE8C0770252FBBAF007FF4A4 /* Images.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Images.xcassets; sourceTree = ""; };
D504555E1FD8714700E46826 /* UIView+Extensions.swift */ = {isa = PBXFileReference; indentWidth = 2; lastKnownFileType = sourcecode.swift; path = "UIView+Extensions.swift"; sourceTree = ""; tabWidth = 2; };
- D50BE3E51C9FE7A80000A34C /* flashOff@3x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "flashOff@3x.png"; sourceTree = ""; };
- D50BE3E61C9FE7A80000A34C /* flashOn@3x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "flashOn@3x.png"; sourceTree = ""; };
- D50BE3E71C9FE7A80000A34C /* info@3x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "info@3x.png"; sourceTree = ""; };
- D5349DF7201E42D900CD53EA /* cameraRotate@3x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "cameraRotate@3x.png"; sourceTree = ""; };
D55281B52016758F00FF3CDD /* HeaderViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HeaderViewController.swift; sourceTree = ""; };
D55281B7201675D500FF3CDD /* MessageViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MessageViewController.swift; sourceTree = ""; };
D55281B92016770800FF3CDD /* CameraViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CameraViewController.swift; sourceTree = ""; };
@@ -59,13 +60,18 @@
/* End PBXFrameworksBuildPhase section */
/* Begin PBXGroup section */
+ AA8BA40E23CCA895002F447D /* Localization */ = {
+ isa = PBXGroup;
+ children = (
+ AA8BA40F23CCA895002F447D /* Localizable.strings */,
+ );
+ path = Localization;
+ sourceTree = "";
+ };
D50BE3E31C9FE7A80000A34C /* Images */ = {
isa = PBXGroup;
children = (
- D5349DF7201E42D900CD53EA /* cameraRotate@3x.png */,
- D50BE3E51C9FE7A80000A34C /* flashOff@3x.png */,
- D50BE3E61C9FE7A80000A34C /* flashOn@3x.png */,
- D50BE3E71C9FE7A80000A34C /* info@3x.png */,
+ CE8C0770252FBBAF007FF4A4 /* Images.xcassets */,
);
path = Images;
sourceTree = "";
@@ -95,9 +101,9 @@
D5B2E8951C3A780C00C0327D = {
isa = PBXGroup;
children = (
- D50BE3E31C9FE7A80000A34C /* Images */,
D5C629691C3A809D007F7B7C /* Sources */,
D5C6295C1C3A800E007F7B7C /* BarcodeScanner */,
+ AA8BA40E23CCA895002F447D /* Localization */,
D5B2E8A01C3A780C00C0327D /* Products */,
);
sourceTree = "";
@@ -121,6 +127,7 @@
D5C629691C3A809D007F7B7C /* Sources */ = {
isa = PBXGroup;
children = (
+ D50BE3E31C9FE7A80000A34C /* Images */,
D5CB3785201947D000B9319D /* Helpers */,
D5CB37842019477900B9319D /* DataStructures */,
D55281BD20167D9F00FF3CDD /* Extensions */,
@@ -200,7 +207,13 @@
developmentRegion = en;
hasScannedForEncodings = 0;
knownRegions = (
+ English,
en,
+ de,
+ ja,
+ tr,
+ fr,
+ "pl-PL",
Base,
);
mainGroup = D5B2E8951C3A780C00C0327D;
@@ -218,10 +231,12 @@
isa = PBXResourcesBuildPhase;
buildActionMask = 2147483647;
files = (
+ AA8BA41623CCA895002F447D /* Localizable.strings in Resources */,
D50BE3E91C9FE7A80000A34C /* flashOff@3x.png in Resources */,
D5349DF8201E42D900CD53EA /* cameraRotate@3x.png in Resources */,
D50BE3EB1C9FE7A80000A34C /* info@3x.png in Resources */,
D50BE3EA1C9FE7A80000A34C /* flashOn@3x.png in Resources */,
+ CE8C0771252FBBAF007FF4A4 /* Images.xcassets in Resources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@@ -250,6 +265,22 @@
};
/* End PBXSourcesBuildPhase section */
+/* Begin PBXVariantGroup section */
+ AA8BA40F23CCA895002F447D /* Localizable.strings */ = {
+ isa = PBXVariantGroup;
+ children = (
+ AA8BA41023CCA895002F447D /* de */,
+ AA8BA41123CCA895002F447D /* ja */,
+ AA8BA41223CCA895002F447D /* en */,
+ AA8BA41323CCA895002F447D /* tr */,
+ AA8BA41423CCA895002F447D /* fr */,
+ AA8BA41523CCA895002F447D /* pl-PL */,
+ );
+ name = Localizable.strings;
+ sourceTree = "";
+ };
+/* End PBXVariantGroup section */
+
/* Begin XCBuildConfiguration section */
D5B2E8B11C3A780C00C0327D /* Debug */ = {
isa = XCBuildConfiguration;
diff --git a/Example/BarcodeScannerExample/BarcodeScannerExample.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist b/Example/BarcodeScannerExample/BarcodeScannerExample.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist
new file mode 100644
index 0000000..18d9810
--- /dev/null
+++ b/Example/BarcodeScannerExample/BarcodeScannerExample.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist
@@ -0,0 +1,8 @@
+
+
+
+
+ IDEDidComputeMac32BitWarning
+
+
+
diff --git a/Package.swift b/Package.swift
new file mode 100644
index 0000000..637b8ab
--- /dev/null
+++ b/Package.swift
@@ -0,0 +1,28 @@
+// swift-tools-version:5.3
+// The swift-tools-version declares the minimum version of Swift required to build this package.
+
+import PackageDescription
+
+let package = Package(
+ name: "BarcodeScanner",
+ defaultLocalization: "en",
+ platforms: [.iOS(.v14)],
+ products: [
+ // Products define the executables and libraries produced by a package, and make them visible to other packages.
+ .library(
+ name: "BarcodeScanner",
+ targets: ["BarcodeScanner"]),
+ ],
+ dependencies: [
+ // Dependencies declare other packages that this package depends on.
+ // .package(url: /* package url */, from: "1.0.0"),
+ ],
+ targets: [
+ // Targets are the basic building blocks of a package. A target can define a module or a test suite.
+ // Targets can depend on other targets in this package, and on products in packages which this package depends on.
+ .target(
+ name: "BarcodeScanner",
+ path: "Sources"
+ ),
+ ]
+)
diff --git a/Sources/Controllers/BarcodeScannerViewController.swift b/Sources/Controllers/BarcodeScannerViewController.swift
index b93eb9e..0a166a0 100644
--- a/Sources/Controllers/BarcodeScannerViewController.swift
+++ b/Sources/Controllers/BarcodeScannerViewController.swift
@@ -4,7 +4,7 @@ import AVFoundation
// MARK: - Delegates
/// Delegate to handle the captured code.
-public protocol BarcodeScannerCodeDelegate: class {
+@objc public protocol BarcodeScannerCodeDelegate: AnyObject {
func scanner(
_ controller: BarcodeScannerViewController,
didCaptureCode code: String,
@@ -13,12 +13,12 @@ public protocol BarcodeScannerCodeDelegate: class {
}
/// Delegate to report errors.
-public protocol BarcodeScannerErrorDelegate: class {
+@objc public protocol BarcodeScannerErrorDelegate: AnyObject {
func scanner(_ controller: BarcodeScannerViewController, didReceiveError error: Error)
}
/// Delegate to dismiss barcode scanner when the close button has been pressed.
-public protocol BarcodeScannerDismissalDelegate: class {
+@objc public protocol BarcodeScannerDismissalDelegate: AnyObject {
func scannerDidDismiss(_ controller: BarcodeScannerViewController)
}
@@ -32,24 +32,28 @@ public protocol BarcodeScannerDismissalDelegate: class {
- Not found error message
*/
open class BarcodeScannerViewController: UIViewController {
- private static let footerHeight: CGFloat = 75
- public var hideFooterView = false
+ public static var footerHeight: CGFloat = 75
+ @objc public var hideFooterView = false
// MARK: - Public properties
/// Delegate to handle the captured code.
- public weak var codeDelegate: BarcodeScannerCodeDelegate?
+ @objc public weak var codeDelegate: BarcodeScannerCodeDelegate?
/// Delegate to report errors.
- public weak var errorDelegate: BarcodeScannerErrorDelegate?
+ @objc public weak var errorDelegate: BarcodeScannerErrorDelegate?
/// Delegate to dismiss barcode scanner when the close button has been pressed.
- public weak var dismissalDelegate: BarcodeScannerDismissalDelegate?
+ @objc public weak var dismissalDelegate: BarcodeScannerDismissalDelegate?
/// When the flag is set to `true` controller returns a captured code
/// and waits for the next reset action.
- public var isOneTimeSearch = true
+ @objc public var isOneTimeSearch = true
+ /// When the flag is set to `true` the screen is flashed on barcode scan.
+ /// Defaults to true.
+ @objc public var shouldSimulateFlash = true
+
/// `AVCaptureMetadataOutput` metadata object types.
- public var metadata = AVMetadataObject.ObjectType.barcodeScannerMetadata {
+ @objc public var metadata = AVMetadataObject.ObjectType.barcodeScannerMetadata {
didSet {
cameraViewController.metadata = metadata
}
@@ -198,6 +202,13 @@ open class BarcodeScannerViewController: UIViewController {
- Parameter processing: Flag to set the current state to `.processing`.
*/
private func animateFlash(whenProcessing: Bool = false) {
+ guard shouldSimulateFlash else {
+ if whenProcessing {
+ self.status = Status(state: .processing)
+ }
+ return
+ }
+
let flashView = UIView(frame: view.bounds)
flashView.backgroundColor = UIColor.white
flashView.alpha = 1
diff --git a/Sources/Controllers/CameraViewController.swift b/Sources/Controllers/CameraViewController.swift
index da907e8..f5a722d 100644
--- a/Sources/Controllers/CameraViewController.swift
+++ b/Sources/Controllers/CameraViewController.swift
@@ -2,7 +2,7 @@ import UIKit
import AVFoundation
/// Delegate to handle camera setup and video capturing.
-protocol CameraViewControllerDelegate: class {
+protocol CameraViewControllerDelegate: AnyObject {
func cameraViewControllerDidSetupCaptureSession(_ controller: CameraViewController)
func cameraViewControllerDidFailToSetupCaptureSession(_ controller: CameraViewController)
func cameraViewController(_ controller: CameraViewController, didReceiveError error: Error)
@@ -134,7 +134,9 @@ public final class CameraViewController: UIViewController {
}
torchMode = .off
- captureSession.startRunning()
+ DispatchQueue.global(qos: .background).async {
+ self.captureSession.startRunning()
+ }
focusView.isHidden = false
flashButton.isHidden = captureDevice?.position == .front
cameraButton.isHidden = !showsCameraButton
diff --git a/Sources/Controllers/HeaderViewController.swift b/Sources/Controllers/HeaderViewController.swift
index 733e73c..8eb1c9e 100644
--- a/Sources/Controllers/HeaderViewController.swift
+++ b/Sources/Controllers/HeaderViewController.swift
@@ -1,7 +1,7 @@
import UIKit
/// Delegate to handle touch event of the close button.
-protocol HeaderViewControllerDelegate: class {
+protocol HeaderViewControllerDelegate: AnyObject {
func headerViewControllerDidTapCloseButton(_ controller: HeaderViewController)
}
diff --git a/Sources/Helpers/Functions.swift b/Sources/Helpers/Functions.swift
index f959382..8c70eb7 100644
--- a/Sources/Helpers/Functions.swift
+++ b/Sources/Helpers/Functions.swift
@@ -7,15 +7,9 @@ import AVFoundation
- Returns: An image.
*/
func imageNamed(_ name: String) -> UIImage {
- let cls = BarcodeScannerViewController.self
- var bundle = Bundle(for: cls)
let traitCollection = UITraitCollection(displayScale: 3)
- if let resourceBundle = bundle.resourcePath.flatMap({ Bundle(path: $0 + "/BarcodeScanner.bundle") }) {
- bundle = resourceBundle
- }
-
- guard let image = UIImage(named: name, in: bundle, compatibleWith: traitCollection) else {
+ guard let image = UIImage(named: name, in: Bundle.module, compatibleWith: traitCollection) else {
return UIImage()
}
@@ -28,6 +22,9 @@ func imageNamed(_ name: String) -> UIImage {
- Returns: An image.
*/
func localizedString(_ key: String) -> String {
+ if let bundle = Bundle(identifier: "no.hyper.BarcodeScanner-iOS") {
+ return bundle.localizedString(forKey: key, value: nil, table: "Localizable")
+ }
if let path = Bundle(for: BarcodeScannerViewController.self).resourcePath,
let resourceBundle = Bundle(path: path + "/Localization.bundle") {
return resourceBundle.localizedString(forKey: key, value: nil, table: "Localizable")
diff --git a/Sources/Images/Images.xcassets/Contents.json b/Sources/Images/Images.xcassets/Contents.json
new file mode 100644
index 0000000..73c0059
--- /dev/null
+++ b/Sources/Images/Images.xcassets/Contents.json
@@ -0,0 +1,6 @@
+{
+ "info" : {
+ "author" : "xcode",
+ "version" : 1
+ }
+}
diff --git a/Sources/Images/Images.xcassets/cameraRotate.imageset/Contents.json b/Sources/Images/Images.xcassets/cameraRotate.imageset/Contents.json
new file mode 100644
index 0000000..dcae763
--- /dev/null
+++ b/Sources/Images/Images.xcassets/cameraRotate.imageset/Contents.json
@@ -0,0 +1,21 @@
+{
+ "images" : [
+ {
+ "idiom" : "universal",
+ "scale" : "1x"
+ },
+ {
+ "idiom" : "universal",
+ "scale" : "2x"
+ },
+ {
+ "filename" : "cameraRotate@3x.png",
+ "idiom" : "universal",
+ "scale" : "3x"
+ }
+ ],
+ "info" : {
+ "author" : "xcode",
+ "version" : 1
+ }
+}
diff --git a/Images/cameraRotate@3x.png b/Sources/Images/Images.xcassets/cameraRotate.imageset/cameraRotate@3x.png
similarity index 100%
rename from Images/cameraRotate@3x.png
rename to Sources/Images/Images.xcassets/cameraRotate.imageset/cameraRotate@3x.png
diff --git a/Sources/Images/Images.xcassets/flashOff.imageset/Contents.json b/Sources/Images/Images.xcassets/flashOff.imageset/Contents.json
new file mode 100644
index 0000000..d663350
--- /dev/null
+++ b/Sources/Images/Images.xcassets/flashOff.imageset/Contents.json
@@ -0,0 +1,21 @@
+{
+ "images" : [
+ {
+ "idiom" : "universal",
+ "scale" : "1x"
+ },
+ {
+ "idiom" : "universal",
+ "scale" : "2x"
+ },
+ {
+ "filename" : "flashOff@3x.png",
+ "idiom" : "universal",
+ "scale" : "3x"
+ }
+ ],
+ "info" : {
+ "author" : "xcode",
+ "version" : 1
+ }
+}
diff --git a/Images/flashOff@3x.png b/Sources/Images/Images.xcassets/flashOff.imageset/flashOff@3x.png
similarity index 100%
rename from Images/flashOff@3x.png
rename to Sources/Images/Images.xcassets/flashOff.imageset/flashOff@3x.png
diff --git a/Sources/Images/Images.xcassets/flashOn.imageset/Contents.json b/Sources/Images/Images.xcassets/flashOn.imageset/Contents.json
new file mode 100644
index 0000000..3c72d8a
--- /dev/null
+++ b/Sources/Images/Images.xcassets/flashOn.imageset/Contents.json
@@ -0,0 +1,21 @@
+{
+ "images" : [
+ {
+ "idiom" : "universal",
+ "scale" : "1x"
+ },
+ {
+ "idiom" : "universal",
+ "scale" : "2x"
+ },
+ {
+ "filename" : "flashOn@3x.png",
+ "idiom" : "universal",
+ "scale" : "3x"
+ }
+ ],
+ "info" : {
+ "author" : "xcode",
+ "version" : 1
+ }
+}
diff --git a/Images/flashOn@3x.png b/Sources/Images/Images.xcassets/flashOn.imageset/flashOn@3x.png
similarity index 100%
rename from Images/flashOn@3x.png
rename to Sources/Images/Images.xcassets/flashOn.imageset/flashOn@3x.png
diff --git a/Sources/Images/Images.xcassets/info.imageset/Contents.json b/Sources/Images/Images.xcassets/info.imageset/Contents.json
new file mode 100644
index 0000000..675e54e
--- /dev/null
+++ b/Sources/Images/Images.xcassets/info.imageset/Contents.json
@@ -0,0 +1,21 @@
+{
+ "images" : [
+ {
+ "idiom" : "universal",
+ "scale" : "1x"
+ },
+ {
+ "idiom" : "universal",
+ "scale" : "2x"
+ },
+ {
+ "filename" : "info@3x.png",
+ "idiom" : "universal",
+ "scale" : "3x"
+ }
+ ],
+ "info" : {
+ "author" : "xcode",
+ "version" : 1
+ }
+}
diff --git a/Images/info@3x.png b/Sources/Images/Images.xcassets/info.imageset/info@3x.png
similarity index 100%
rename from Images/info@3x.png
rename to Sources/Images/Images.xcassets/info.imageset/info@3x.png
diff --git a/Localization/de.lproj/Localizable.strings b/Sources/Localization/de.lproj/Localizable.strings
similarity index 100%
rename from Localization/de.lproj/Localizable.strings
rename to Sources/Localization/de.lproj/Localizable.strings
diff --git a/Localization/en.lproj/Localizable.strings b/Sources/Localization/en.lproj/Localizable.strings
similarity index 100%
rename from Localization/en.lproj/Localizable.strings
rename to Sources/Localization/en.lproj/Localizable.strings
diff --git a/Localization/fr.lproj/Localizable.strings b/Sources/Localization/fr.lproj/Localizable.strings
similarity index 100%
rename from Localization/fr.lproj/Localizable.strings
rename to Sources/Localization/fr.lproj/Localizable.strings
diff --git a/Localization/ja.lproj/Localizable.strings b/Sources/Localization/ja.lproj/Localizable.strings
similarity index 100%
rename from Localization/ja.lproj/Localizable.strings
rename to Sources/Localization/ja.lproj/Localizable.strings
diff --git a/Localization/nl.lproj/Localizable.strings b/Sources/Localization/nl.lproj/Localizable.strings
similarity index 100%
rename from Localization/nl.lproj/Localizable.strings
rename to Sources/Localization/nl.lproj/Localizable.strings
diff --git a/Localization/pl-PL.lproj/Localizable.strings b/Sources/Localization/pl-PL.lproj/Localizable.strings
similarity index 100%
rename from Localization/pl-PL.lproj/Localizable.strings
rename to Sources/Localization/pl-PL.lproj/Localizable.strings
diff --git a/Localization/pt-BR.lproj/Localizable.strings b/Sources/Localization/pt-BR.lproj/Localizable.strings
similarity index 100%
rename from Localization/pt-BR.lproj/Localizable.strings
rename to Sources/Localization/pt-BR.lproj/Localizable.strings
diff --git a/Localization/ru.lproj/Localizable.strings b/Sources/Localization/ru.lproj/Localizable.strings
similarity index 100%
rename from Localization/ru.lproj/Localizable.strings
rename to Sources/Localization/ru.lproj/Localizable.strings
diff --git a/Localization/tr.lproj/Localizable.strings b/Sources/Localization/tr.lproj/Localizable.strings
similarity index 100%
rename from Localization/tr.lproj/Localizable.strings
rename to Sources/Localization/tr.lproj/Localizable.strings
diff --git a/Sources/Localization/zh-Hans.lproj/Localizable.strings b/Sources/Localization/zh-Hans.lproj/Localizable.strings
new file mode 100644
index 0000000..2b3abfb
--- /dev/null
+++ b/Sources/Localization/zh-Hans.lproj/Localizable.strings
@@ -0,0 +1,7 @@
+"SCAN_BARCODE_TITLE" = "扫描二维码";
+"BUTTON_CLOSE" = "关闭";
+"BUTTON_SETTINGS" = "设置";
+"INFO_DESCRIPTION_TEXT" = "把条形码放在窗口来扫描。搜索会自动开始。";
+"INFO_LOADING_TITLE" = "寻找产品中...";
+"NO_PRODUCT_ERROR_TITLE" = "没有找到产品。";
+"ASK_FOR_PERMISSION_TEXT" = "你需要允许在设置里,允许访问相机才能扫描条形码。";