Skip to content

Commit

Permalink
Merge pull request #1 from xremix/develop
Browse files Browse the repository at this point in the history
v0.2.0 Logic Refactoring
  • Loading branch information
xremix authored Jun 26, 2017
2 parents 698975c + 4c3812a commit 6078271
Show file tree
Hide file tree
Showing 10 changed files with 229 additions and 103 deletions.
2 changes: 1 addition & 1 deletion SwiftGS1Barcode.podspec
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
Pod::Spec.new do |s|
s.name = 'SwiftGS1Barcode'
s.version = '0.1.4'
s.version = '0.2.0'
s.summary = 'A GS1 Barcode Library and Parser for Swift'

s.description = <<-DESC
Expand Down
18 changes: 13 additions & 5 deletions SwiftGS1Barcode.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@
64754D181F011B9700B22B62 /* README.md in Sources */ = {isa = PBXBuildFile; fileRef = 64754D171F011B9700B22B62 /* README.md */; };
64AE611D1F01081800F3B9C0 /* SwiftGS1Barcode.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 64AE61131F01081800F3B9C0 /* SwiftGS1Barcode.framework */; };
64AE61241F01081800F3B9C0 /* SwiftGS1Barcode.h in Headers */ = {isa = PBXBuildFile; fileRef = 64AE61161F01081800F3B9C0 /* SwiftGS1Barcode.h */; settings = {ATTRIBUTES = (Public, ); }; };
64DD17361F014E1400F10103 /* GS1Node.swift in Sources */ = {isa = PBXBuildFile; fileRef = 64DD17351F014E1400F10103 /* GS1Node.swift */; };
64DD17381F014F8700F10103 /* GS1NodeTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 64DD17371F014F8700F10103 /* GS1NodeTests.swift */; };
/* End PBXBuildFile section */

/* Begin PBXContainerItemProxy section */
Expand Down Expand Up @@ -53,6 +55,8 @@
64AE61171F01081800F3B9C0 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
64AE611C1F01081800F3B9C0 /* SwiftGS1BarcodeTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = SwiftGS1BarcodeTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
64AE61231F01081800F3B9C0 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
64DD17351F014E1400F10103 /* GS1Node.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = GS1Node.swift; sourceTree = "<group>"; };
64DD17371F014F8700F10103 /* GS1NodeTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = GS1NodeTests.swift; sourceTree = "<group>"; };
/* End PBXFileReference section */

/* Begin PBXFrameworksBuildPhase section */
Expand Down Expand Up @@ -99,12 +103,13 @@
children = (
64AE61161F01081800F3B9C0 /* SwiftGS1Barcode.h */,
64AE61171F01081800F3B9C0 /* Info.plist */,
64754CFD1F010A1000B22B62 /* GS1Barcode.swift */,
64754CFF1F010E8400B22B62 /* BarcodeParser.swift */,
64754D011F010E9100B22B62 /* Barcode.swift */,
64754CFF1F010E8400B22B62 /* BarcodeParser.swift */,
64754D071F010ECA00B22B62 /* DateExtension.swift */,
64754CFD1F010A1000B22B62 /* GS1Barcode.swift */,
64DD17351F014E1400F10103 /* GS1Node.swift */,
64754D031F010EA000B22B62 /* SimpleBarcode.swift */,
64754D051F010EBB00B22B62 /* StringExtension.swift */,
64754D071F010ECA00B22B62 /* DateExtension.swift */,
);
path = SwiftGS1Barcode;
sourceTree = "<group>";
Expand All @@ -114,10 +119,11 @@
children = (
64AE61231F01081800F3B9C0 /* Info.plist */,
64754D0B1F01103C00B22B62 /* BarcodeParserTests.swift */,
64754D0F1F01106500B22B62 /* SimpleBarcodeTests.swift */,
64754D151F01107B00B22B62 /* DateTests.swift */,
64754D111F01106D00B22B62 /* GS1BarcodeTests.swift */,
64DD17371F014F8700F10103 /* GS1NodeTests.swift */,
64754D0F1F01106500B22B62 /* SimpleBarcodeTests.swift */,
64754D131F01107500B22B62 /* StringTests.swift */,
64754D151F01107B00B22B62 /* DateTests.swift */,
);
path = SwiftGS1BarcodeTests;
sourceTree = "<group>";
Expand Down Expand Up @@ -237,6 +243,7 @@
buildActionMask = 2147483647;
files = (
64754D041F010EA000B22B62 /* SimpleBarcode.swift in Sources */,
64DD17361F014E1400F10103 /* GS1Node.swift in Sources */,
64754D081F010ECA00B22B62 /* DateExtension.swift in Sources */,
64754CFE1F010A1000B22B62 /* GS1Barcode.swift in Sources */,
64754D181F011B9700B22B62 /* README.md in Sources */,
Expand All @@ -253,6 +260,7 @@
64754D161F01107B00B22B62 /* DateTests.swift in Sources */,
64754D141F01107500B22B62 /* StringTests.swift in Sources */,
64754D0C1F01103C00B22B62 /* BarcodeParserTests.swift in Sources */,
64DD17381F014F8700F10103 /* GS1NodeTests.swift in Sources */,
64754D121F01106D00B22B62 /* GS1BarcodeTests.swift in Sources */,
64754D101F01106500B22B62 /* SimpleBarcodeTests.swift in Sources */,
);
Expand Down
118 changes: 82 additions & 36 deletions SwiftGS1Barcode/BarcodeParser.swift
Original file line number Diff line number Diff line change
Expand Up @@ -14,50 +14,96 @@ public class GS1BarcodeParser: NSObject {
return data
}

var length = (node.value?.length ?? 0) + (node.identifier.length)
if (node.type == .GroupSeperatorBased || node.type == .GroupSeperatorBasedInt) && length < data!.length{
var length = (node.originalValue?.length ?? 0) + (node.identifier.length)
if node.dynamicLength && data!.length > length{
length += 1
}
return data!.substring(from: length)
}
static func parseGS1Node(node: GS1Node, data: String)->GS1Node{
print("Parsing node of type \(node.type.description) with identifier \(node.identifier)")
switch node.type {
case .GroupSeperatorBased, .GroupSeperatorBasedInt:
if !data.contains("\u{1D}") {
node.value = data.substring(from: node.identifier.length)
}else{
let toi = data.index(of: "\u{1D}")
let to = data.distance(from: data.startIndex, to: toi ?? data.startIndex)

node.value = data.substring(node.identifier.length, to: to)
}
if node.type == .GroupSeperatorBasedInt{
node.rawValue = Int(node.value!)
}
case .Date:
node.rawValue = NSDate.from(
year: Int("20" + data.substring(2, length: 2)),
month: Int(data.substring(4, length: 2)),
day: Int(data.substring(6, length: 2))
)
node.value = data.substring(2, length: 6)
default:
// GTIN, GTINIndicatorDigit, etc.
if node.fixedValueLength != nil{
node.value = data.substring(node.identifier.length, length: node.fixedValueLength!)
if node.type == .FixedLengthBasedInt && node.value != nil{
node.rawValue = Int(node.value!)
}
}else{
// TODO throw error here?
node.value = data.substring(from: node.identifier.length)
}
print("Parsing node with identifier \(node.identifier) of type \(String(describing: node.type?.description))")

// Get Pure Data by removing the identifier
var nodeData = data
nodeData = nodeData.substring(from: node.identifier.length)


// Cut to Group Seperator
if node.dynamicLength && nodeData.index(of: "\u{1D}") != nil {
let toi = nodeData.index(of: "\u{1D}")
let to = nodeData.distance(from: nodeData.startIndex, to: toi ?? nodeData.startIndex)

nodeData = nodeData.substring(to: to)
}
// Cut to Max Length
if nodeData.length > node.maxLength{
nodeData = nodeData.substring(to: node.maxLength)
}
if node.rawValue == nil{
node.rawValue = node.value

// Set original value to the value of the content
node.originalValue = nodeData

if node.type == GS1Type.Date{

node.dateValue = NSDate.from(
year: Int("20" + nodeData.substring(to: 2)),
month: Int(nodeData.substring(2, length: 2)),
day: Int(nodeData.substring(4, length: 2))
)
}else if(node.type == GS1Type.Int){
node.intValue = Int(nodeData)
}else{
node.stringValue = nodeData
}
// switch node.type {
// case GS1Type.Date:
// node.dateValue = NSDate.from(
// year: Int("20" + nodeData.substring(to: 2)),
// month: Int(nodeData.substring(2, length: 2)),
// day: Int(nodeData.substring(4, length: 2))
// )
// default:
// node.stringValue = nodeData
// }



// switch node.type {
// case .GroupSeperatorBased, .GroupSeperatorBasedInt:
// if !data.contains("\u{1D}") {
// node.value = data.substring(from: node.identifier.length)
// }else{
// let toi = data.index(of: "\u{1D}")
// let to = data.distance(from: data.startIndex, to: toi ?? data.startIndex)
//
// node.value = data.substring(node.identifier.length, to: to)
// }
// if node.type == .GroupSeperatorBasedInt{
// node.rawValue = Int(node.value!)
// }
// case .Date:
// node.rawValue = NSDate.from(
// year: Int("20" + data.substring(2, length: 2)),
// month: Int(data.substring(4, length: 2)),
// day: Int(data.substring(6, length: 2))
// )
// node.value = data.substring(2, length: 6)
// default:
// // GTIN, GTINIndicatorDigit, etc.
// if node.fixedValueLength != nil{
// node.value = data.substring(node.identifier.length, length: node.fixedValueLength!)
// if node.type == .FixedLengthBasedInt && node.value != nil{
// node.rawValue = Int(node.value!)
// }
// }else{
// // TODO throw error here?
// node.value = data.substring(from: node.identifier.length)
// }
//
// }
// if node.rawValue == nil{
// node.rawValue = node.value
// }
return node
}
}
62 changes: 16 additions & 46 deletions SwiftGS1Barcode/GS1Barcode.swift
Original file line number Diff line number Diff line change
Expand Up @@ -8,59 +8,26 @@

import UIKit

enum GS1Type: String{
case FixedLengthBased
case FixedLengthBasedInt
case GroupSeperatorBased
case GroupSeperatorBasedInt
case Date
var description: String{
return self.rawValue
}
}

class GS1Node: NSObject{
var identifier: String
var type: GS1Type
var fixedValueLength: Int?

// Values
var value: String?
var rawValue: Any?
var dateValue: NSDate?{ return rawValue as? NSDate }
var intValue: Int?{ return rawValue as? Int }

init(identifier: String, type: GS1Type){
self.identifier = identifier
self.type = type
}
init(identifier: String, type: GS1Type, fixedValue: Int){
self.identifier = identifier
self.type = type
self.fixedValueLength = fixedValue
}
}

// Struct used in the GS1 Barcode Class
struct GS1Nodes{
var gtinNode = GS1Node(identifier: "01", type: .FixedLengthBased, fixedValue: 14)
var gtinIndicatorDigitNode = GS1Node(identifier: "01", type: .FixedLengthBasedInt, fixedValue: 1)
// TODO should have maximum of 20
var lotNumberNode = GS1Node(identifier: "10", type: .GroupSeperatorBased)
var expirationDateNode = GS1Node(identifier: "17", type: .Date)
// TODO should have maximum of 20
var serialNumberNode = GS1Node(identifier: "21", type: .GroupSeperatorBased)
// TODO should have maximum of 8 characters
var amountNode = GS1Node(identifier: "30", type: .GroupSeperatorBasedInt)
var gtinNode = GS1Node("01", length: 14, type: .String)
var gtinIndicatorDigitNode = GS1Node("01", length: 1, type: .Int)
var lotNumberNode = GS1Node("10", length: 20, type: .String, dynamicLength: true)
var expirationDateNode = GS1Node("17", length: 6, type: .Date)
var serialNumberNode = GS1Node("21", length: 20, type: .String, dynamicLength: true)
var amountNode = GS1Node("30", length: 8, type: .Int, dynamicLength: true)
}

public class GS1Barcode: NSObject, Barcode {
public var raw: String?
private var parseSuccessFull: Bool = false
var nodes = GS1Nodes()

public var gtin: String?{ get {return nodes.gtinNode.value} }
public var lotNumber: String?{ get {return nodes.lotNumberNode.value} }
// Mapping for User Friendly Usage
public var gtin: String?{ get {return nodes.gtinNode.stringValue} }
public var lotNumber: String?{ get {return nodes.lotNumberNode.stringValue} }
public var expirationDate: NSDate?{ get {return nodes.expirationDateNode.dateValue} }
public var serialNumber: String?{ get {return nodes.serialNumberNode.value} }
public var serialNumber: String?{ get {return nodes.serialNumberNode.stringValue} }
public var amount: Int?{ get {return nodes.amountNode.intValue} }
public var gtinIndicatorDigit: Int? {get {return nodes.gtinIndicatorDigitNode.intValue}}

Expand All @@ -73,11 +40,13 @@ public class GS1Barcode: NSObject, Barcode {
_ = parse()
}

// Validating if the barcode got parsed correctly
func validate() -> Bool {
return gtin != nil
return parseSuccessFull && raw != "" && raw != nil
}

func parse() ->Bool{
self.parseSuccessFull = false
var data = raw

if data != nil{
Expand Down Expand Up @@ -108,6 +77,7 @@ public class GS1Barcode: NSObject, Barcode {
}
}
}
self.parseSuccessFull = true
return true
}
}
45 changes: 45 additions & 0 deletions SwiftGS1Barcode/GS1Node.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
//
// GS1Node.swift
// SwiftGS1Barcode
//
// Created by Toni Hoffmann on 26.06.17.
// Copyright © 2017 Toni Hoffmann. All rights reserved.
//

import UIKit

enum GS1Type: String{
case Date
case String
case Int
var description: String{
return self.rawValue
}
}

class GS1Node: NSObject{
var identifier: String
var maxLength: Int
var dynamicLength: Bool = false

var type: GS1Type?

var originalValue: String?
var dateValue: NSDate?
var intValue: Int?

var stringValue: String?

init(_ identifier: String, length: Int){
self.identifier = identifier
self.maxLength = length
}
convenience init(_ identifier: String, length: Int, type: GS1Type){
self.init(identifier, length: length)
self.type = type
}
convenience init(_ identifier: String, length: Int, type: GS1Type, dynamicLength: Bool){
self.init(identifier, length: length, type: type)
self.dynamicLength = dynamicLength
}
}
2 changes: 1 addition & 1 deletion SwiftGS1Barcode/Info.plist
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
<key>CFBundlePackageType</key>
<string>FMWK</string>
<key>CFBundleShortVersionString</key>
<string>0.1.4</string>
<string>0.2.0</string>
<key>CFBundleVersion</key>
<string>$(CURRENT_PROJECT_VERSION)</string>
<key>NSPrincipalClass</key>
Expand Down
Loading

0 comments on commit 6078271

Please sign in to comment.