Skip to content

Commit

Permalink
Merge pull request #4 from ef1rspb/master
Browse files Browse the repository at this point in the history
Fix potential crash. Refactor
  • Loading branch information
jad939933 authored Mar 31, 2019
2 parents f7c7c20 + d195e37 commit 98b74a5
Show file tree
Hide file tree
Showing 6 changed files with 79 additions and 82 deletions.
9 changes: 4 additions & 5 deletions WoopraSDK/DictionaryExtension.swift
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,11 @@
// Copyright © 2017 Woopra. All rights reserved.
//

import UIKit

extension Dictionary {
mutating func update(other:Dictionary) {
for (key,value) in other {
self.updateValue(value, forKey:key)

mutating func update(with dictionary: Dictionary) {
for (key, value) in dictionary {
updateValue(value, forKey: key)
}
}
}
2 changes: 1 addition & 1 deletion WoopraSDK/WEvent.swift
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ public class WEvent: WPropertiesContainer {

public init(name: String) {
super.init()
self.add(property: "~event", value: name)
add(property: "~event", value: name)
}

public static func event(name: String) -> WEvent {
Expand Down
62 changes: 34 additions & 28 deletions WoopraSDK/WPinger.swift
Original file line number Diff line number Diff line change
Expand Up @@ -6,20 +6,18 @@
// Copyright © 2017 Woopra. All rights reserved.
//

import UIKit

class WPinger: NSObject {

var tracker: WTracker? = nil
let tracker: WTracker
private var pingTimer: Timer?
private var observerContext = 0
private var pingInterval = 50.0
private let WPingEndpoint = "https://www.woopra.com/track/ping/"
private let pingEndpoint = "https://www.woopra.com/track/ping/"

init(tracker: WTracker) {
super.init()
self.tracker = tracker

super.init()

for p in monitoredTrackerProperties() {
tracker.addObserver(self, forKeyPath: p, options: NSKeyValueObservingOptions.new, context: &observerContext)
}
Expand All @@ -29,45 +27,52 @@ class WPinger: NSObject {

deinit {
for p in monitoredTrackerProperties() {
tracker?.removeObserver(self, forKeyPath: p, context: &observerContext)
tracker.removeObserver(self, forKeyPath: p, context: &observerContext)
}
}

override public func observeValue(forKeyPath keyPath: String?, of object: Any?, change: [NSKeyValueChangeKey : Any]?, context: UnsafeMutableRawPointer?) {
if let tracker = self.tracker, let keyPath = keyPath {
if tracker.isEqual(object) && self.monitoredTrackerProperties().contains(keyPath) {
self.startStopPingTimerAccordingToTrackerState()
} else {
super.observeValue(forKeyPath: keyPath, of: object, change: change, context: context)
}
override public func observeValue(forKeyPath keyPath: String?,
of object: Any?,
change: [NSKeyValueChangeKey : Any]?,
context: UnsafeMutableRawPointer?) {
guard let keyPath = keyPath else {
return
}
if tracker.isEqual(object) && monitoredTrackerProperties().contains(keyPath) {
startStopPingTimerAccordingToTrackerState()
} else {
super.observeValue(forKeyPath: keyPath, of: object, change: change, context: context)
}
}

private func startStopPingTimerAccordingToTrackerState() {
pingTimer?.invalidate()
pingTimer = nil

if let tracker = self.tracker, let domain = tracker.domain {
if (!domain.isEmpty &&
tracker.visitor != nil &&
tracker.pingEnabled) {
pingInterval = tracker.idleTimeout - 10.0
pingTimer = Timer.scheduledTimer(timeInterval: pingInterval, target: self, selector: #selector(WPinger.pingTimerDidFire(timer:)), userInfo: nil, repeats: true)
self.pingTimerDidFire(timer: pingTimer!)
}
if let domain = tracker.domain,
!domain.isEmpty,
tracker.visitor != nil,
tracker.pingEnabled {

pingInterval = tracker.idleTimeout - 10.0
pingTimer = Timer.scheduledTimer(timeInterval: pingInterval,
target: self,
selector: #selector(WPinger.pingTimerDidFire(timer:)),
userInfo: nil,
repeats: true)
pingTimerDidFire(timer: pingTimer!)
}
}

@objc func pingTimerDidFire(timer: Timer) {

if let tracker = self.tracker, let domain = tracker.domain, let visitor = tracker.visitor {
let parameters = "?host=" + domain + "&response=xml&cookie=\(visitor.cookie)&meta=VGhpcyBpcyBhIHRlc3Q&timeout=\(Int(tracker.idleTimeout * 1000))"
if let domain = tracker.domain, let visitor = tracker.visitor {
let parameters = "?host=\(domain)&response=xml&cookie=\(visitor.cookie)&meta=VGhpcyBpcyBhIHRlc3Q&timeout=\(Int(tracker.idleTimeout * 1000))"

if let url = URL(string: WPingEndpoint.appending(parameters)) {
if let url = URL(string: pingEndpoint.appending(parameters)) {
let pingRequest = URLRequest(url: url)
let session = URLSession.shared
let task = session.dataTask(with: pingRequest, completionHandler: { (data, response, error) in

let task = URLSession.shared.dataTask(with: pingRequest, completionHandler: { (data, response, error) in
#if DEBUG
guard error == nil else {
print("error")
print(error!)
Expand All @@ -81,6 +86,7 @@ class WPinger: NSObject {

print("\(Date()) " + responseData.debugDescription)
print(parameters)
#endif
})
task.resume()
}
Expand Down
14 changes: 5 additions & 9 deletions WoopraSDK/WPropertiesContainer.swift
Original file line number Diff line number Diff line change
Expand Up @@ -9,17 +9,13 @@
import Foundation

public class WPropertiesContainer: NSObject {
var properties = Dictionary<String, String>()
var properties: [String: String] = [:]

public func add(property key: String, value: String) {
properties[key] = value
}
properties[key] = value
}

public func add(properties newDictionary: Dictionary<String, String>) {
properties.update(other: newDictionary)
public func add(properties newDictionary: [String: String]) {
properties.update(with: newDictionary)
}
}




70 changes: 34 additions & 36 deletions WoopraSDK/WTracker.swift
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,6 @@
// Copyright © 2017 Woopra. All rights reserved.
//

import UIKit

public class WTracker: WPropertiesContainer {

// MARK: - Public properties
Expand All @@ -20,15 +18,16 @@ public class WTracker: WPropertiesContainer {
@objc dynamic public var idleTimeout: TimeInterval {
get { return _idleTimeout }
set(aNewValue) {
if aNewValue < 30.0 {
_idleTimeout = 30.0
if aNewValue < WTracker.defaultIdleTimeout {
_idleTimeout = WTracker.defaultIdleTimeout
} else {
_idleTimeout = aNewValue
}
}
}

private var _idleTimeout: TimeInterval = 60.0
private static let defaultIdleTimeout: TimeInterval = 60.0
private var _idleTimeout: TimeInterval = defaultIdleTimeout

// ping requests can be periodically sent to Woopra servers to refresh the visitor timeout counter. This is used if it’s important to keep a visitor status ‘online’ when he’s inactive for a long time (for cases such as watching a long video).
@objc dynamic public var pingEnabled = false
Expand All @@ -37,8 +36,8 @@ public class WTracker: WPropertiesContainer {
public var referer: String?

// MARK: - Private properties
private let WEventEndpoint = "https://www.woopra.com/track/ce/"
private var gPinger: WPinger? = nil
private let wEventEndpoint = "https://www.woopra.com/track/ce/"
private var wPinger: WPinger?

// MARK: - Shared instance
public static let shared: WTracker = {
Expand All @@ -47,61 +46,60 @@ public class WTracker: WPropertiesContainer {
// initialize system needed properties
instance.add(property: "device", value: UIDevice.current.model)
instance.add(property: "os", value: "\(UIDevice.current.systemName) \(UIDevice.current.systemVersion)")
let bundleName = (Bundle.main.object(forInfoDictionaryKey: kCFBundleNameKey as String))
let bundleName = Bundle.main.object(forInfoDictionaryKey: kCFBundleNameKey as String)
instance.add(property: "browser", value: bundleName as! String)

instance.gPinger = WPinger(tracker: instance)
instance.wPinger = WPinger(tracker: instance)
// create dummy visitor object to track 'anonymous' events
instance.visitor = WVisitor.anonymousVisitor()

return instance
}()

private override init() {
super.init()
}


// MARK: - Methods
public func trackEvent(_ event: WEvent) {
// check parameters
if (self.domain == nil)
{
print("WTracker.domain property must be set before WTracker.trackEvent: invocation. Ex.: tracker.domain = mywebsite.com");
guard let domain = domain else {
#if DEBUG
print("WTracker.domain property must be set before WTracker.trackEvent: invocation. Ex.: tracker.domain = mywebsite.com")
#endif
return
}

if (self.visitor == nil)
{
print("WTracker.visitor property must be set before WTracker.trackEvent: invocation");

guard let visitor = visitor else {
#if DEBUG
print("WTracker.visitor property must be set before WTracker.trackEvent: invocation")
#endif
return
}

let url = URL(string: WEventEndpoint)
let components = NSURLComponents(url: url!, resolvingAgainstBaseURL: true)
let url = URL(string: wEventEndpoint)!
let components = NSURLComponents(url: url, resolvingAgainstBaseURL: true)
var queryItems: [NSURLQueryItem] = [
NSURLQueryItem(name: "app", value: "ios"),
NSURLQueryItem(name: "host", value: self.domain),
NSURLQueryItem(name: "cookie", value: self.visitor!.cookie),
NSURLQueryItem(name: "host", value: domain),
NSURLQueryItem(name: "cookie", value: visitor.cookie),
NSURLQueryItem(name: "response", value: "xml"),
NSURLQueryItem(name: "timeout", value: Int(self.idleTimeout * 1000).description)
NSURLQueryItem(name: "timeout", value: Int(idleTimeout * 1000).description)
]

if (self.referer != nil) {
queryItems.append(NSURLQueryItem(name: "referer", value: self.referer))
if let referer = referer {
queryItems.append(NSURLQueryItem(name: "referer", value: referer))
}

// Add system properties e.g. device, os, browser
for (key, value) in self.properties {
for (key, value) in properties {
queryItems.append(NSURLQueryItem(name: "\(key)", value: value))
}

// Add visitors properties
let visitorProperties = self.visitor!.properties
let visitorProperties = visitor.properties
for (key, value) in visitorProperties {
queryItems.append(NSURLQueryItem(name: "cv_\(key)", value: value));
}

// Add Event Properties
let eventProperties = event.properties
for (key, value) in eventProperties {
for (key, value) in event.properties {
if key.hasPrefix("~") {
// Parsing of required system event properties. For example ~event – custom event type. e.g. event=purchase, event=signup etc…
let index = key.index(key.startIndex, offsetBy: 1)
Expand All @@ -117,9 +115,8 @@ public class WTracker: WPropertiesContainer {

if let url = requestUrl {
let request = URLRequest(url: url)
let session = URLSession.shared
let task = session.dataTask(with: request, completionHandler: { (data, response, error) in

let task = URLSession.shared.dataTask(with: request, completionHandler: { (data, response, error) in
#if DEBUG
// check for errors
guard error == nil else {
print("error")
Expand All @@ -131,8 +128,9 @@ public class WTracker: WPropertiesContainer {
print("Error: did not receive data")
return
}

print(responseData.debugDescription)
#endif
})
task.resume()
}
Expand Down
4 changes: 1 addition & 3 deletions WoopraSDK/WVisitor.swift
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,9 @@
// Copyright © 2017 Woopra. All rights reserved.
//

import UIKit

public class WVisitor: WPropertiesContainer {

public var cookie: String = ""
public var cookie = ""
private static let WoopraCookieKey = "woopra_cookie"

public static func visitor(withCookie cookie: String) -> WVisitor {
Expand Down

0 comments on commit 98b74a5

Please sign in to comment.