Skip to content

Commit

Permalink
fix: remove location-related code from SDK, add an example plugin to …
Browse files Browse the repository at this point in the history
…collect location data (#75)
  • Loading branch information
falconandy authored Aug 15, 2023
1 parent 903429a commit 34ff8e5
Show file tree
Hide file tree
Showing 15 changed files with 102 additions and 68 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
19C9CC1D2937F5A600C1E660 /* Preview Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 19C9CC1C2937F5A600C1E660 /* Preview Assets.xcassets */; };
19C9CC1F2937F5A600C1E660 /* Persistence.swift in Sources */ = {isa = PBXBuildFile; fileRef = 19C9CC1E2937F5A600C1E660 /* Persistence.swift */; };
19C9CC222937F5A600C1E660 /* AmplitudeSwiftUIExample.xcdatamodeld in Sources */ = {isa = PBXBuildFile; fileRef = 19C9CC202937F5A600C1E660 /* AmplitudeSwiftUIExample.xcdatamodeld */; };
19C9CC2D2937F5D000C1E660 /* Amplitude-Swift in Frameworks */ = {isa = PBXBuildFile; productRef = 19C9CC2C2937F5D000C1E660 /* Amplitude-Swift */; };
19C9CC2D2937F5D000C1E660 /* AmplitudeSwift in Frameworks */ = {isa = PBXBuildFile; productRef = 19C9CC2C2937F5D000C1E660 /* AmplitudeSwift */; };
3A3036482A4B45780004CF0B /* TroubleShootingPlugin.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3A3036472A4B45780004CF0B /* TroubleShootingPlugin.swift */; };
3A4E19BD2941D885002EA8BC /* IDFACollectionPlugin.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3A4E19BC2941D86E002EA8BC /* IDFACollectionPlugin.swift */; };
58324F75294BF7CF00C71E2E /* WidgetKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 58324F74294BF7CF00C71E2E /* WidgetKit.framework */; };
Expand All @@ -30,7 +30,8 @@
58324F97294BFB4000C71E2E /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 58324F96294BFB4000C71E2E /* Assets.xcassets */; };
58324F9A294BFB4000C71E2E /* Preview Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 58324F99294BFB4000C71E2E /* Preview Assets.xcassets */; };
58324F9F294BFB4000C71E2E /* iOSAppClip.app in Embed App Clips */ = {isa = PBXBuildFile; fileRef = 58324F90294BFB4000C71E2E /* iOSAppClip.app */; settings = {ATTRIBUTES = (RemoveHeadersOnCopy, ); }; };
58324FA5294BFF3700C71E2E /* Amplitude-Swift in Frameworks */ = {isa = PBXBuildFile; productRef = 58324FA4294BFF3700C71E2E /* Amplitude-Swift */; };
58324FA5294BFF3700C71E2E /* AmplitudeSwift in Frameworks */ = {isa = PBXBuildFile; productRef = 58324FA4294BFF3700C71E2E /* AmplitudeSwift */; };
BA541E9B2A8B587E0088D841 /* LocationPlugin.swift in Sources */ = {isa = PBXBuildFile; fileRef = BA541E9A2A8B587E0088D841 /* LocationPlugin.swift */; };
/* End PBXBuildFile section */

/* Begin PBXContainerItemProxy section */
Expand Down Expand Up @@ -83,7 +84,7 @@
19C9CC1C2937F5A600C1E660 /* Preview Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = "Preview Assets.xcassets"; sourceTree = "<group>"; };
19C9CC1E2937F5A600C1E660 /* Persistence.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Persistence.swift; sourceTree = "<group>"; };
19C9CC212937F5A600C1E660 /* AmplitudeSwiftUIExample.xcdatamodel */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcdatamodel; path = AmplitudeSwiftUIExample.xcdatamodel; sourceTree = "<group>"; };
19C9CC292937F5B200C1E660 /* Amplitude-Swift */ = {isa = PBXFileReference; lastKnownFileType = wrapper; name = "Amplitude-Swift"; path = ../..; sourceTree = "<group>"; };
19C9CC292937F5B200C1E660 /* AmplitudeSwift */ = {isa = PBXFileReference; lastKnownFileType = wrapper; name = AmplitudeSwift; path = ../..; sourceTree = "<group>"; };
19C9CC2A2937F5C900C1E660 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist; path = Info.plist; sourceTree = "<group>"; };
3A3036472A4B45780004CF0B /* TroubleShootingPlugin.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TroubleShootingPlugin.swift; sourceTree = "<group>"; };
3A4E19BC2941D86E002EA8BC /* IDFACollectionPlugin.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = IDFACollectionPlugin.swift; sourceTree = "<group>"; };
Expand All @@ -103,14 +104,15 @@
58324F99294BFB4000C71E2E /* Preview Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = "Preview Assets.xcassets"; sourceTree = "<group>"; };
58324F9B294BFB4000C71E2E /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
58324F9C294BFB4000C71E2E /* iOSAppClip.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = iOSAppClip.entitlements; sourceTree = "<group>"; };
BA541E9A2A8B587E0088D841 /* LocationPlugin.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = LocationPlugin.swift; sourceTree = "<group>"; };
/* End PBXFileReference section */

/* Begin PBXFrameworksBuildPhase section */
19C9CC0F2937F5A400C1E660 /* Frameworks */ = {
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
19C9CC2D2937F5D000C1E660 /* Amplitude-Swift in Frameworks */,
19C9CC2D2937F5D000C1E660 /* AmplitudeSwift in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
};
Expand All @@ -127,7 +129,7 @@
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
58324FA5294BFF3700C71E2E /* Amplitude-Swift in Frameworks */,
58324FA5294BFF3700C71E2E /* AmplitudeSwift in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
};
Expand Down Expand Up @@ -182,7 +184,7 @@
19C9CC282937F5B200C1E660 /* Packages */ = {
isa = PBXGroup;
children = (
19C9CC292937F5B200C1E660 /* Amplitude-Swift */,
19C9CC292937F5B200C1E660 /* AmplitudeSwift */,
);
name = Packages;
sourceTree = "<group>";
Expand All @@ -199,6 +201,7 @@
3A4E19BB2941D86E002EA8BC /* ExamplePlugins */ = {
isa = PBXGroup;
children = (
BA541E9A2A8B587E0088D841 /* LocationPlugin.swift */,
3A4E19BC2941D86E002EA8BC /* IDFACollectionPlugin.swift */,
3A3036472A4B45780004CF0B /* TroubleShootingPlugin.swift */,
);
Expand Down Expand Up @@ -260,7 +263,7 @@
);
name = AmplitudeSwiftUIExample;
packageProductDependencies = (
19C9CC2C2937F5D000C1E660 /* Amplitude-Swift */,
19C9CC2C2937F5D000C1E660 /* AmplitudeSwift */,
);
productName = AmplitudeSwiftUIExample;
productReference = 19C9CC122937F5A400C1E660 /* AmplitudeSwiftUIExample.app */;
Expand Down Expand Up @@ -297,7 +300,7 @@
);
name = iOSAppClip;
packageProductDependencies = (
58324FA4294BFF3700C71E2E /* Amplitude-Swift */,
58324FA4294BFF3700C71E2E /* AmplitudeSwift */,
);
productName = iOSAppClip;
productReference = 58324F90294BFB4000C71E2E /* iOSAppClip.app */;
Expand Down Expand Up @@ -385,6 +388,7 @@
3A4E19BD2941D885002EA8BC /* IDFACollectionPlugin.swift in Sources */,
58324F84294BF7CF00C71E2E /* iOSWidgetExample.intentdefinition in Sources */,
3A3036482A4B45780004CF0B /* TroubleShootingPlugin.swift in Sources */,
BA541E9B2A8B587E0088D841 /* LocationPlugin.swift in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
Expand Down Expand Up @@ -762,13 +766,13 @@
/* End XCConfigurationList section */

/* Begin XCSwiftPackageProductDependency section */
19C9CC2C2937F5D000C1E660 /* Amplitude-Swift */ = {
19C9CC2C2937F5D000C1E660 /* AmplitudeSwift */ = {
isa = XCSwiftPackageProductDependency;
productName = "Amplitude-Swift";
productName = AmplitudeSwift;
};
58324FA4294BFF3700C71E2E /* Amplitude-Swift */ = {
58324FA4294BFF3700C71E2E /* AmplitudeSwift */ = {
isa = XCSwiftPackageProductDependency;
productName = "Amplitude-Swift";
productName = AmplitudeSwift;
};
/* End XCSwiftPackageProductDependency section */

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
// Created by Hao Yu on 11/30/22.
//

import Amplitude_Swift
import AmplitudeSwift
import AppTrackingTransparency
import SwiftUI

Expand All @@ -16,6 +16,7 @@ struct AmplitudeSwiftUIExampleApp: App {
// Overriding the initializer in the App in order to config amplitude
init() {
Amplitude.testInstance.add(plugin: IDFACollectionPlugin())
Amplitude.testInstance.add(plugin: LocationPlugin())
// add the trouble shooting plugin for debugging
Amplitude.testInstance.add(plugin: TroubleShootingPlugin())
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
// Created by Hao Yu on 11/30/22.
//

import Amplitude_Swift
import AmplitudeSwift
import AppTrackingTransparency
import CoreData
import SwiftUI
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
// and for your convenience should you find it useful.

import AdSupport
import Amplitude_Swift
import AmplitudeSwift
import AppTrackingTransparency
import Foundation
import SwiftUI
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
import AmplitudeSwift
import Foundation
import CoreLocation

/// Plugin to collect location data. Users will be prompted if authorization status is undetermined.
/// This plugin example currently supports iOS 14+ only.
/// Don't forget to add "NSLocationWhenInUseUsageDescription" with a description to your Info.plist.
class LocationPlugin: NSObject, Plugin, CLLocationManagerDelegate {
let type = PluginType.enrichment
weak var amplitude: Amplitude? = nil
private var locationManager: CLLocationManager? = nil
private var location: CLLocation? = nil

func setup(amplitude: Amplitude) {
self.amplitude = amplitude

locationManager = CLLocationManager()
locationManager!.delegate = self
startUpdatingLocation()
}

func execute(event: BaseEvent?) -> BaseEvent? {
if let location {
event?.locationLat = location.coordinate.latitude
event?.locationLng = location.coordinate.longitude
}
return event
}

func startUpdatingLocation() {
if !isAuthorized() {
locationManager?.requestWhenInUseAuthorization()
} else {
locationManager?.startUpdatingLocation()
}
}

func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
if locations.count > 0 {
location = locations.first
}
}

func locationManager(_ manager: CLLocationManager, didFailWithError error: Error) {
amplitude?.logger?.error(message: error.localizedDescription)
clearReferences()
}

func locationManagerDidChangeAuthorization(_ manager: CLLocationManager) {
switch manager.authorizationStatus {
case .authorizedAlways, .authorizedWhenInUse:
startUpdatingLocation()
break
case .notDetermined:
break
case .denied, .restricted:
clearReferences()
default:
clearReferences()
}
}

func clearReferences() {
locationManager?.stopUpdatingLocation()
locationManager = nil
}

func isAuthorizationDenied() -> Bool {
let status = locationManager?.authorizationStatus
return status == .denied
}

func isAuthorized() -> Bool {
let status = locationManager?.authorizationStatus
return status == .authorizedAlways || status == .authorizedWhenInUse
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
//

import Foundation
import Amplitude_Swift
import AmplitudeSwift

class TroubleShootingPlugin: DestinationPlugin {
open override func setup(amplitude: Amplitude) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>NSLocationWhenInUseUsageDescription</key>
<string>This app need to get your location...</string>
<key>CFBundleURLTypes</key>
<array>
<dict>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
//

import SwiftUI
import Amplitude_Swift
import AmplitudeSwift

struct ContentView: View {
var body: some View {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
//

import SwiftUI
import Amplitude_Swift
import AmplitudeSwift

@main
struct iOSAppClipApp: App {
Expand Down
10 changes: 0 additions & 10 deletions Sources/Amplitude/Amplitude.swift
Original file line number Diff line number Diff line change
Expand Up @@ -11,16 +11,6 @@ public class Amplitude {
var state: State = State()
var contextPlugin: ContextPlugin

/**
Sets a block to be called when location (latitude, longitude) information can be passed into an event.

let locationInfo = LocationInfo(lat: 37.7, lng: 122.4)
Amplitude.testInstance.locationInfoBlock = {
return locationInfo
}
*/
public var locationInfoBlock: LocationInfoBlock?

lazy var storage: any Storage = {
return self.configuration.storageProvider
}()
Expand Down
1 change: 0 additions & 1 deletion Sources/Amplitude/Constants.swift
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,6 @@ public struct Constants {
static let AMP_TRACKING_OPTION_IDFV = "idfv"
static let AMP_TRACKING_OPTION_IP_ADDRESS = "ip_address"
static let AMP_TRACKING_OPTION_LANGUAGE = "language"
static let AMP_TRACKING_OPTION_LAT_LNG = "lat_lng"
static let AMP_TRACKING_OPTION_OS_NAME = "os_name"
static let AMP_TRACKING_OPTION_OS_VERSION = "os_version"
static let AMP_TRACKING_OPTION_PLATFORM = "platform"
Expand Down
5 changes: 0 additions & 5 deletions Sources/Amplitude/Plugins/ContextPlugin.swift
Original file line number Diff line number Diff line change
Expand Up @@ -141,11 +141,6 @@ class ContextPlugin: Plugin {
if trackingOptions?.shouldTrackIDFV() ?? false {
event.idfv = context["idfv"] as? String
}
if (trackingOptions?.shouldTrackLatLng() ?? false) && (self.amplitude?.locationInfoBlock != nil) {
let location = self.amplitude?.locationInfoBlock!()
event.locationLat = location?.lat
event.locationLng = location?.lng
}
if trackingOptions?.shouldTrackLanguage() ?? false {
event.language = context["language"] as? String
}
Expand Down
10 changes: 0 additions & 10 deletions Sources/Amplitude/TrackingOptions.swift
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@ public class TrackingOptions {
Constants.AMP_TRACKING_OPTION_IDFV,
Constants.AMP_TRACKING_OPTION_CITY,
Constants.AMP_TRACKING_OPTION_IP_ADDRESS,
Constants.AMP_TRACKING_OPTION_LAT_LNG,
]

var disabledFields: Set<String> = []
Expand Down Expand Up @@ -147,15 +146,6 @@ public class TrackingOptions {
return self
}

public func shouldTrackLatLng() -> Bool {
return shouldTrackField(field: Constants.AMP_TRACKING_OPTION_LAT_LNG)
}

public func disableTrackLatLng() -> TrackingOptions {
disabledFields.insert(Constants.AMP_TRACKING_OPTION_LAT_LNG)
return self
}

func forCoppaControl() -> TrackingOptions {
let trackingOptions = TrackingOptions()
for property in COPPA_CONTROL_PROPERTIES {
Expand Down
11 changes: 0 additions & 11 deletions Sources/Amplitude/Types.swift
Original file line number Diff line number Diff line change
Expand Up @@ -44,17 +44,6 @@ public struct IngestionMetadata: Codable {

public typealias EventCallback = (BaseEvent, Int, String) -> Void

public struct LocationInfo {
public var lat: Double
public var lng: Double
public init(lat: Double, lng: Double) {
self.lat = lat
self.lng = lng
}
}

public typealias LocationInfoBlock = () -> LocationInfo

// Swift 5.7 supports any existential type.
// The type of EventBlock has to be determined pre-runtime.
// It cannot be dynamically associated with this protocol.
Expand Down
13 changes: 0 additions & 13 deletions Tests/AmplitudeTests/AmplitudeTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -66,11 +66,6 @@ final class AmplitudeTests: XCTestCase {
func testContext() {
let amplitude = Amplitude(configuration: configuration)

let locationInfo = LocationInfo(lat: 123, lng: 123)
amplitude.locationInfoBlock = {
return locationInfo
}

let outputReader = OutputReaderPlugin()
amplitude.add(plugin: outputReader)
amplitude.track(event: BaseEvent(eventType: "testEvent"))
Expand All @@ -84,8 +79,6 @@ final class AmplitudeTests: XCTestCase {
XCTAssertNil(lastEvent?.country)
XCTAssertEqual(lastEvent?.platform!.isEmpty, false)
XCTAssertEqual(lastEvent?.language!.isEmpty, false)
XCTAssertNotNil(lastEvent?.locationLat)
XCTAssertNotNil(lastEvent?.locationLng)
}

func testContextWithDisableTrackingOptions() {
Expand All @@ -94,17 +87,11 @@ final class AmplitudeTests: XCTestCase {
_ = trackingOptions.disableTrackIpAddress()
.disableCarrier()
.disableTrackIDFV()
.disableTrackLatLng()
.disableTrackCountry()
let configuration = Configuration(apiKey: apiKey, trackingOptions: trackingOptions)

let amplitude = Amplitude(configuration: configuration)

let locationInfo = LocationInfo(lat: 123, lng: 123)
amplitude.locationInfoBlock = {
return locationInfo
}

let outputReader = OutputReaderPlugin()
amplitude.add(plugin: outputReader)
amplitude.track(event: BaseEvent(eventType: "testEvent"))
Expand Down

0 comments on commit 34ff8e5

Please sign in to comment.