Skip to content

Commit

Permalink
Merge branch 'swift3' into feature/swift-device-extensions
Browse files Browse the repository at this point in the history
  • Loading branch information
thorstenstark committed Jan 8, 2017
2 parents da55a53 + 8d15e3a commit fa3fbe9
Show file tree
Hide file tree
Showing 13 changed files with 410 additions and 51 deletions.
3 changes: 1 addition & 2 deletions .travis.yml
@@ -1,10 +1,9 @@
language: objective-c
before_install:
- pod repo update --silent
- gem install cocoapods --no-rdoc --no-ri --no-document --quiet
- gem install xcpretty --no-rdoc --no-ri --no-document --quiet
- cd $TRAVIS_BUILD_DIR
- pod install
- pod install || pod install --repo-update
script: rake test
osx_image: xcode8
cache: cocoapods
2 changes: 1 addition & 1 deletion Example/Example.xcodeproj/project.pbxproj
Expand Up @@ -347,7 +347,7 @@
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "diff \"${PODS_ROOT}/../Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [[ $? != 0 ]] ; then\n cat << EOM\nerror: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\nEOM\n exit 1\nfi\n";
shellScript = "diff \"${PODS_ROOT}/../Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n";
showEnvVarsInLog = 0;
};
AD6EA65F0F2334BE1EBF2A97 /* [CP] Copy Pods Resources */ = {
Expand Down
115 changes: 110 additions & 5 deletions PiwikTracker.xcodeproj/project.pbxproj
Expand Up @@ -7,10 +7,15 @@
objects = {

/* Begin PBXBuildFile section */
1F092C141E224C3E00394B30 /* PiwikUserDefaults.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1F092C131E224C3E00394B30 /* PiwikUserDefaults.swift */; };
1F1949F21E17A91100458199 /* MemoryQueue.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1F1949F11E17A91100458199 /* MemoryQueue.swift */; };
1F1949F41E17B06600458199 /* MemoryQueueSpec.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1F1949F31E17B06600458199 /* MemoryQueueSpec.swift */; };
1F1949F81E17B2C800458199 /* MemoryQueueFixtures.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1F1949F71E17B2C800458199 /* MemoryQueueFixtures.swift */; };
1F3CA58C1E09A30600121FDC /* Queue.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1F3CA58B1E09A30600121FDC /* Queue.swift */; };
1FCA6D451DBE0B2F0033F01C /* PiwikTracker.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1FCA6D3B1DBE0B2F0033F01C /* PiwikTracker.framework */; };
1FCA6D4A1DBE0B2F0033F01C /* PiwikTrackerTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1FCA6D491DBE0B2F0033F01C /* PiwikTrackerTests.swift */; };
1FCA6D4C1DBE0B2F0033F01C /* PiwikTracker.h in Headers */ = {isa = PBXBuildFile; fileRef = 1FCA6D3E1DBE0B2F0033F01C /* PiwikTracker.h */; settings = {ATTRIBUTES = (Public, ); }; };
2DE767EF1E0890CA00CA3CD7 /* Device.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2DE767EE1E0890CA00CA3CD7 /* Device.swift */; };
82A551CEC50ABB2EAD50FC4E /* Pods_PiwikTrackerTests.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 68F0C25DEF98C13D32CC46DD /* Pods_PiwikTrackerTests.framework */; };
/* End PBXBuildFile section */

/* Begin PBXContainerItemProxy section */
Expand All @@ -24,13 +29,20 @@
/* End PBXContainerItemProxy section */

/* Begin PBXFileReference section */
1F092C131E224C3E00394B30 /* PiwikUserDefaults.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PiwikUserDefaults.swift; sourceTree = "<group>"; };
1F1949F11E17A91100458199 /* MemoryQueue.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MemoryQueue.swift; sourceTree = "<group>"; };
1F1949F31E17B06600458199 /* MemoryQueueSpec.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MemoryQueueSpec.swift; sourceTree = "<group>"; };
1F1949F71E17B2C800458199 /* MemoryQueueFixtures.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = MemoryQueueFixtures.swift; path = Fixtures/MemoryQueueFixtures.swift; sourceTree = "<group>"; };
1F3CA58B1E09A30600121FDC /* Queue.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Queue.swift; sourceTree = "<group>"; };
1FCA6D3B1DBE0B2F0033F01C /* PiwikTracker.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = PiwikTracker.framework; sourceTree = BUILT_PRODUCTS_DIR; };
1FCA6D3E1DBE0B2F0033F01C /* PiwikTracker.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = PiwikTracker.h; sourceTree = "<group>"; };
1FCA6D3F1DBE0B2F0033F01C /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
1FCA6D441DBE0B2F0033F01C /* PiwikTrackerTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = PiwikTrackerTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
1FCA6D491DBE0B2F0033F01C /* PiwikTrackerTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PiwikTrackerTests.swift; sourceTree = "<group>"; };
1FCA6D4B1DBE0B2F0033F01C /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
2DE767EE1E0890CA00CA3CD7 /* Device.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Device.swift; sourceTree = "<group>"; };
68F0C25DEF98C13D32CC46DD /* Pods_PiwikTrackerTests.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_PiwikTrackerTests.framework; sourceTree = BUILT_PRODUCTS_DIR; };
8F688B0F18F298B5E61552AC /* Pods-PiwikTrackerTests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-PiwikTrackerTests.release.xcconfig"; path = "Pods/Target Support Files/Pods-PiwikTrackerTests/Pods-PiwikTrackerTests.release.xcconfig"; sourceTree = "<group>"; };
FD284F50B998823EAFB0CEE9 /* Pods-PiwikTrackerTests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-PiwikTrackerTests.debug.xcconfig"; path = "Pods/Target Support Files/Pods-PiwikTrackerTests/Pods-PiwikTrackerTests.debug.xcconfig"; sourceTree = "<group>"; };
/* End PBXFileReference section */

/* Begin PBXFrameworksBuildPhase section */
Expand All @@ -46,18 +58,29 @@
buildActionMask = 2147483647;
files = (
1FCA6D451DBE0B2F0033F01C /* PiwikTracker.framework in Frameworks */,
82A551CEC50ABB2EAD50FC4E /* Pods_PiwikTrackerTests.framework in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXFrameworksBuildPhase section */

/* Begin PBXGroup section */
1F1949F51E17B2A400458199 /* Fixtures */ = {
isa = PBXGroup;
children = (
1F1949F71E17B2C800458199 /* MemoryQueueFixtures.swift */,
);
name = Fixtures;
sourceTree = "<group>";
};
1FCA6D311DBE0B2F0033F01C = {
isa = PBXGroup;
children = (
1FCA6D3D1DBE0B2F0033F01C /* PiwikTracker */,
1FCA6D481DBE0B2F0033F01C /* PiwikTrackerTests */,
1FCA6D3C1DBE0B2F0033F01C /* Products */,
2031C9E411023782603AB505 /* Pods */,
ADAE39D28F21B08F51A5C6A8 /* Frameworks */,
);
sourceTree = "<group>";
};
Expand All @@ -73,6 +96,9 @@
1FCA6D3D1DBE0B2F0033F01C /* PiwikTracker */ = {
isa = PBXGroup;
children = (
1F092C131E224C3E00394B30 /* PiwikUserDefaults.swift */,
1F3CA58B1E09A30600121FDC /* Queue.swift */,
1F1949F11E17A91100458199 /* MemoryQueue.swift */,
1FCA6D3E1DBE0B2F0033F01C /* PiwikTracker.h */,
1FCA6D3F1DBE0B2F0033F01C /* Info.plist */,
2DE767EE1E0890CA00CA3CD7 /* Device.swift */,
Expand All @@ -83,12 +109,30 @@
1FCA6D481DBE0B2F0033F01C /* PiwikTrackerTests */ = {
isa = PBXGroup;
children = (
1FCA6D491DBE0B2F0033F01C /* PiwikTrackerTests.swift */,
1F1949F51E17B2A400458199 /* Fixtures */,
1F1949F31E17B06600458199 /* MemoryQueueSpec.swift */,
1FCA6D4B1DBE0B2F0033F01C /* Info.plist */,
);
path = PiwikTrackerTests;
sourceTree = "<group>";
};
2031C9E411023782603AB505 /* Pods */ = {
isa = PBXGroup;
children = (
FD284F50B998823EAFB0CEE9 /* Pods-PiwikTrackerTests.debug.xcconfig */,
8F688B0F18F298B5E61552AC /* Pods-PiwikTrackerTests.release.xcconfig */,
);
name = Pods;
sourceTree = "<group>";
};
ADAE39D28F21B08F51A5C6A8 /* Frameworks */ = {
isa = PBXGroup;
children = (
68F0C25DEF98C13D32CC46DD /* Pods_PiwikTrackerTests.framework */,
);
name = Frameworks;
sourceTree = "<group>";
};
/* End PBXGroup section */

/* Begin PBXHeadersBuildPhase section */
Expand Down Expand Up @@ -125,9 +169,12 @@
isa = PBXNativeTarget;
buildConfigurationList = 1FCA6D521DBE0B2F0033F01C /* Build configuration list for PBXNativeTarget "PiwikTrackerTests" */;
buildPhases = (
40E940918D712CC15E5735CE /* [CP] Check Pods Manifest.lock */,
1FCA6D401DBE0B2F0033F01C /* Sources */,
1FCA6D411DBE0B2F0033F01C /* Frameworks */,
1FCA6D421DBE0B2F0033F01C /* Resources */,
22AB6DF399C52F3B2B8ED25F /* [CP] Embed Pods Frameworks */,
F440219733D7385F192471AC /* [CP] Copy Pods Resources */,
);
buildRules = (
);
Expand All @@ -151,11 +198,12 @@
TargetAttributes = {
1FCA6D3A1DBE0B2F0033F01C = {
CreatedOnToolsVersion = 8.0;
LastSwiftMigration = 0800;
LastSwiftMigration = 0820;
ProvisioningStyle = Automatic;
};
1FCA6D431DBE0B2F0033F01C = {
CreatedOnToolsVersion = 8.0;
LastSwiftMigration = 0820;
ProvisioningStyle = Automatic;
};
};
Expand Down Expand Up @@ -195,20 +243,72 @@
};
/* End PBXResourcesBuildPhase section */

/* Begin PBXShellScriptBuildPhase section */
22AB6DF399C52F3B2B8ED25F /* [CP] Embed Pods Frameworks */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
);
inputPaths = (
);
name = "[CP] Embed Pods Frameworks";
outputPaths = (
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-PiwikTrackerTests/Pods-PiwikTrackerTests-frameworks.sh\"\n";
showEnvVarsInLog = 0;
};
40E940918D712CC15E5735CE /* [CP] Check Pods Manifest.lock */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
);
inputPaths = (
);
name = "[CP] Check Pods Manifest.lock";
outputPaths = (
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "diff \"${PODS_ROOT}/../Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n";
showEnvVarsInLog = 0;
};
F440219733D7385F192471AC /* [CP] Copy Pods Resources */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
);
inputPaths = (
);
name = "[CP] Copy Pods Resources";
outputPaths = (
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-PiwikTrackerTests/Pods-PiwikTrackerTests-resources.sh\"\n";
showEnvVarsInLog = 0;
};
/* End PBXShellScriptBuildPhase section */

/* Begin PBXSourcesBuildPhase section */
1FCA6D361DBE0B2F0033F01C /* Sources */ = {
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
2DE767EF1E0890CA00CA3CD7 /* Device.swift in Sources */,
1F092C141E224C3E00394B30 /* PiwikUserDefaults.swift in Sources */,
1F1949F21E17A91100458199 /* MemoryQueue.swift in Sources */,
1F3CA58C1E09A30600121FDC /* Queue.swift in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
1FCA6D401DBE0B2F0033F01C /* Sources */ = {
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
1FCA6D4A1DBE0B2F0033F01C /* PiwikTrackerTests.swift in Sources */,
1F1949F81E17B2C800458199 /* MemoryQueueFixtures.swift in Sources */,
1F1949F41E17B06600458199 /* MemoryQueueSpec.swift in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
Expand Down Expand Up @@ -363,20 +463,25 @@
};
1FCA6D531DBE0B2F0033F01C /* Debug */ = {
isa = XCBuildConfiguration;
baseConfigurationReference = FD284F50B998823EAFB0CEE9 /* Pods-PiwikTrackerTests.debug.xcconfig */;
buildSettings = {
ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
CLANG_ENABLE_MODULES = YES;
INFOPLIST_FILE = PiwikTrackerTests/Info.plist;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
PRODUCT_BUNDLE_IDENTIFIER = org.piwik.PiwikTrackerTests;
PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
SWIFT_VERSION = 3.0;
};
name = Debug;
};
1FCA6D541DBE0B2F0033F01C /* Release */ = {
isa = XCBuildConfiguration;
baseConfigurationReference = 8F688B0F18F298B5E61552AC /* Pods-PiwikTrackerTests.release.xcconfig */;
buildSettings = {
ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
CLANG_ENABLE_MODULES = YES;
INFOPLIST_FILE = PiwikTrackerTests/Info.plist;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
PRODUCT_BUNDLE_IDENTIFIER = org.piwik.PiwikTrackerTests;
Expand Down
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
LastUpgradeVersion = "0800"
LastUpgradeVersion = "0820"
version = "1.3">
<BuildAction
parallelizeBuildables = "YES"
Expand Down
28 changes: 28 additions & 0 deletions PiwikTracker/MemoryQueue.swift
@@ -0,0 +1,28 @@
import Foundation

/// The MemoryQueue is a **not thread safe** in memory Queue.
struct MemoryQueue<E: Any>: Queue {
typealias T = E
private var items = [E]()

var itemCount: Int { get {
return items.count
}
}

mutating func queue(item: T, completion: ()->()) {
items.append(item)
completion()
}

mutating func dequeue(withLimit limit: Int, completion: (_ items: [T])->()) {
let amount = [limit,itemCount].min()!
let dequeuedItems = Array(items[0..<amount])
items.removeSubrange(0..<amount)
completion(dequeuedItems)
}

mutating func deleteAll() {
items = []
}
}
80 changes: 80 additions & 0 deletions PiwikTracker/PiwikUserDefaults.swift
@@ -0,0 +1,80 @@
import Foundation

/// PiwikUserDefaults is a wrapper for the UserDefaults with properties
/// mapping onto values stored in the UserDefaults.
/// All getter and setter are sideeffect free and automatically syncronize
/// after writing.
internal struct PiwikUserDefaults {
static let standard = PiwikUserDefaults()
let userDefaults = UserDefaults.standard

var totalNumberOfVisits: Int {
get {
return userDefaults.integer(forKey: PiwikUserDefaults.Key.totalNumberOfVisits)
}
set {
userDefaults.set(newValue, forKey: PiwikUserDefaults.Key.totalNumberOfVisits)
userDefaults.synchronize()
}
}

var firstVisit: Date? {
get {
return userDefaults.object(forKey: PiwikUserDefaults.Key.firstVistsTimestamp) as? Date
}
set {
userDefaults.set(newValue, forKey: PiwikUserDefaults.Key.firstVistsTimestamp)
userDefaults.synchronize()
}
}

var previousVisit: Date? {
get {
return userDefaults.object(forKey: PiwikUserDefaults.Key.previousVistsTimestamp) as? Date
}
set {
userDefaults.set(newValue, forKey: PiwikUserDefaults.Key.previousVistsTimestamp)
userDefaults.synchronize()
}
}

var currentVisit: Date? {
get {
return userDefaults.object(forKey: PiwikUserDefaults.Key.currentVisitTimestamp) as? Date
}
set {
userDefaults.set(newValue, forKey: PiwikUserDefaults.Key.currentVisitTimestamp)
userDefaults.synchronize()
}
}

var optOut: Bool {
get {
return userDefaults.bool(forKey: PiwikUserDefaults.Key.optOut)
}
set {
userDefaults.set(newValue, forKey: PiwikUserDefaults.Key.optOut)
userDefaults.synchronize()
}
}

func clientId() -> String? {
return userDefaults.string(forKey: PiwikUserDefaults.Key.visitorID)
}

func set(clientId: String) {
userDefaults.setValue(clientId, forKey: PiwikUserDefaults.Key.visitorID)
userDefaults.synchronize()
}
}

extension PiwikUserDefaults {
fileprivate struct Key {
static let totalNumberOfVisits = "PiwikTotalNumberOfVistsKey"
static let currentVisitTimestamp = "PiwikCurrentVisitTimestampKey"
static let previousVistsTimestamp = "PiwikPreviousVistsTimestampKey"
static let firstVistsTimestamp = "PiwikFirstVistsTimestampKey"
static let visitorID = "PiwikVisitorIDKey"
static let optOut = "PiwikOptOutKey"
}
}

0 comments on commit fa3fbe9

Please sign in to comment.