diff --git a/Placed.bundle/Info.plist b/Placed.bundle/Info.plist index 14186b6..921265d 100644 Binary files a/Placed.bundle/Info.plist and b/Placed.bundle/Info.plist differ diff --git a/Placed.bundle/PlacedOptInViewController.nib b/Placed.bundle/PlacedOptInViewController.nib deleted file mode 100644 index 30235f2..0000000 Binary files a/Placed.bundle/PlacedOptInViewController.nib and /dev/null differ diff --git a/Placed.bundle/PlacedSurveyViewController.nib b/Placed.bundle/PlacedSurveyViewController.nib index 16ca63e..3364236 100644 Binary files a/Placed.bundle/PlacedSurveyViewController.nib and b/Placed.bundle/PlacedSurveyViewController.nib differ diff --git a/Placed.bundle/config.json b/Placed.bundle/config.json index eb5dd8f..84d7819 100644 --- a/Placed.bundle/config.json +++ b/Placed.bundle/config.json @@ -1,11 +1,8 @@ { "project": "Placed-SDK-iOS", "framework": "Placed", - "version": "4.1.1", + "version": "4.2.0", "workspace": "Placed.xcworkspace", - "documentation_path": "README.md", - "documentation_image": "image_0.png", - "wkl": "s3://placed-api/placed-sdk/ios", "configurations": { "debug": { "scheme": "PlacedFramework", diff --git a/Placed.bundle/userDefaults-staging.plist b/Placed.bundle/userDefaults-staging.plist index 78a3a59..21a2f1b 100644 Binary files a/Placed.bundle/userDefaults-staging.plist and b/Placed.bundle/userDefaults-staging.plist differ diff --git a/Placed.bundle/userDefaults.plist b/Placed.bundle/userDefaults.plist index 5eab4da..b5e85a6 100644 Binary files a/Placed.bundle/userDefaults.plist and b/Placed.bundle/userDefaults.plist differ diff --git a/Placed.framework/Headers/PlacedAgent.h b/Placed.framework/Headers/PlacedAgent.h index f825adc..2bd78dc 100644 --- a/Placed.framework/Headers/PlacedAgent.h +++ b/Placed.framework/Headers/PlacedAgent.h @@ -14,6 +14,7 @@ @interface PlacedAgent : NSObject /** This method initializes the PlacedAgent and sets the delegate to be notified of updates. + After calling registerUser this method will also handle starting location tracking in the agent. You should call this in your application:didFinishLaunchingWithOptions: method. @@ -22,31 +23,27 @@ */ + (void)createWithAppKey:(NSString *)appKey andDelegate:(id)delegate; -/** This method starts location tracking in the agent. - - Call this when you want location gathering to begin, but after initializing the agent. - */ -+ (void)startTracking; - -/** This method stops all location tracking for the agent. - - Only call this if you want all tracking to stop. - */ -+ (void)stopTracking; - /** This method allows you to change the delegate that is notified by the agent. @param delegate the delegate you would like to be notified. */ + (void)setAgentDelegate:(id)delegate; -/** This will register a new user and call startTracking. +/** This will register a new user and start location tracking in the agent. This method should only be called once, when a new user enters the app. */ + (void)registerUser; -/** This will return if a user has been registered with a previous call to registerUser +/** This deregisters a user and stops all location tracking. + + Only call this if you want all tracking to stop. The Placed SDK can only be restarted by calling registerUser again. + */ ++ (void)deregisterUser; + +/** This will return if a user is in the registered state. + + This will return true after calling registerUser and false after calling deregisterUser. */ + (BOOL)isUserRegistered; diff --git a/Placed.framework/Info.plist b/Placed.framework/Info.plist index b4871dc..b942cff 100644 Binary files a/Placed.framework/Info.plist and b/Placed.framework/Info.plist differ diff --git a/Placed.framework/Placed b/Placed.framework/Placed index 973d159..c861637 100755 Binary files a/Placed.framework/Placed and b/Placed.framework/Placed differ diff --git a/Placed.framework/Placed.bundle/Info.plist b/Placed.framework/Placed.bundle/Info.plist index 14186b6..921265d 100644 Binary files a/Placed.framework/Placed.bundle/Info.plist and b/Placed.framework/Placed.bundle/Info.plist differ diff --git a/Placed.framework/Placed.bundle/PlacedOptInViewController.nib b/Placed.framework/Placed.bundle/PlacedOptInViewController.nib deleted file mode 100644 index bc865a3..0000000 Binary files a/Placed.framework/Placed.bundle/PlacedOptInViewController.nib and /dev/null differ diff --git a/Placed.framework/Placed.bundle/PlacedSurveyViewController.nib b/Placed.framework/Placed.bundle/PlacedSurveyViewController.nib index ec1600d..3364236 100644 Binary files a/Placed.framework/Placed.bundle/PlacedSurveyViewController.nib and b/Placed.framework/Placed.bundle/PlacedSurveyViewController.nib differ diff --git a/Placed.framework/Placed.bundle/config.json b/Placed.framework/Placed.bundle/config.json index eb5dd8f..84d7819 100644 --- a/Placed.framework/Placed.bundle/config.json +++ b/Placed.framework/Placed.bundle/config.json @@ -1,11 +1,8 @@ { "project": "Placed-SDK-iOS", "framework": "Placed", - "version": "4.1.1", + "version": "4.2.0", "workspace": "Placed.xcworkspace", - "documentation_path": "README.md", - "documentation_image": "image_0.png", - "wkl": "s3://placed-api/placed-sdk/ios", "configurations": { "debug": { "scheme": "PlacedFramework", diff --git a/Placed.framework/Placed.bundle/userDefaults-staging.plist b/Placed.framework/Placed.bundle/userDefaults-staging.plist index 78a3a59..21a2f1b 100644 Binary files a/Placed.framework/Placed.bundle/userDefaults-staging.plist and b/Placed.framework/Placed.bundle/userDefaults-staging.plist differ diff --git a/Placed.framework/Placed.bundle/userDefaults.plist b/Placed.framework/Placed.bundle/userDefaults.plist index 5eab4da..b5e85a6 100644 Binary files a/Placed.framework/Placed.bundle/userDefaults.plist and b/Placed.framework/Placed.bundle/userDefaults.plist differ diff --git a/Placed.podspec b/Placed.podspec index e6ebadc..8d75f43 100644 --- a/Placed.podspec +++ b/Placed.podspec @@ -1,6 +1,6 @@ Pod::Spec.new do |s| s.name = "Placed" - s.version = "4.1.1" + s.version = "4.2.0" s.summary = "Placed Affiliate SDK" s.homepage = "https://www.placed.com" s.author = { "Placed Affiliate Program" => "affiliate@placed.com" } @@ -13,4 +13,5 @@ Pod::Spec.new do |s| s.preserve_paths = 'Placed.framework' s.frameworks = 'CoreData', 'CoreTelephony', 'CoreLocation', 'CoreMotion', 'SystemConfiguration', 'AdSupport', 'Foundation', 'UIKit', 'Security' + s.dependency 'CocoaLumberjack' end diff --git a/README.md b/README.md index f58d1ac..9f3efae 100644 --- a/README.md +++ b/README.md @@ -2,46 +2,77 @@ ## Introduction -The Placed SDK for iOS is designed to help you add Placed location gathering to your app. It exposes simple public API calls that can be used to turn location gathering on. +The Placed SDK for iOS is designed to help you add Placed location gathering to your app. It exposes simple public API calls that can be used to turn on and off location gathering. The SDK has been designed for easy setup and integration with both new and existing mobile applications. ## Setup -The preferred method for installing the Placed SDK in your app is using CocoaPods. CocoaPods is dependency management system for Objective-C development. You can learn more about it at [http://cocoapods.org/](http://cocoapods.org/). +#### Cocoapods +The preferred method for installing the Placed SDK in your app is [CocoaPods](https://cocoapods.org/), a dependency manager for Cocoa projects. You can install CocoaPods with the following command: +``` +$ gem install cocoapods +``` -1. Add the following lines to your project's Podfile -`pod 'Placed', :git => 'https://github.com/placed/ios-placed-sdk.git'` +To integrate the Placed SDK into your Xcode project using CocoaPods, specify it in your `Podfile`: +```ruby +use_frameworks! -2. Celebrate! +pod 'Placed', :git => 'https://github.com/placed/ios-placed-sdk.git' +``` +Then, run the following command: +``` +$ pod install +``` -If you are not using CocoaPods, you can integrate the Placed.framework and Placed.bundle directly in your project. +#### Manually + +If you are not using CocoaPods, you can integrate [Placed.framework](./Placed.framework) manually into your project. ## Location Permission -This SDK requires Apple's background location permission. Under the "Required background modes" key in your app’s main plist file you should make sure to add: +As outlined in Section 5 of the [Placed Affiliate Agreement](https://affiliate.placed.com/placed-affiliate-agreement/), you must satisfy two requirements prior to registering a user with the Placed SDK: - App registers for location updates +1. *Gather Express Consent for User Data Collection via Opt-in Dialog* +In addition having a legally compliant privacy policy describing Placed’s collection of location and device information, you must include a discrete opt-in dialog which gathers express consent for data collection. This dialog appears prior to the fine location permission prompt, and includes: + - The language: “*Aggregated device data, including location, is measured for the purposes of market research by Placed, Inc.*” + - Links to the Placed [Terms of Service](https://www.placed.com/terms-of-service) and [Privacy Policy](https://www.placed.com/privacy-policy) + - Buttons to “Accept” or “Cancel” -In addition, for iOS 11, you must provide all of the following location usage descriptions in your app's plist: +2. *Prompt for Background Location Permission* + Under the “Required background modes” `UIBackgroundModes` key in your app’s main plist file, you will need to add: + ``` + App registers for location updates + ``` + In addition, you must provide all of the following location usage descriptions in your app's plist: + ``` NSLocationAlwaysAndWhenInUseUsageDescription NSLocationWhenInUseUsageDescription NSLocationAlwaysUsageDescription NSLocationUsageDescription + ``` + + **These permissions are very important to the Placed SDK.** If your app does not currently use background location permission, please contact a Placed representative. + +For an example of the opt-in dialog and location permission prompt, please refer to the sample app. We have also provided a [gallery for inspiration](./gallery) on how you can better integrate the opt-in experience into your app. -**These permissions are very important to the Placed SDK. If your app does not currently use background location permission, please contact a Placed representative.** -## Integration +## Usage -1. Add `#import ` to your main AppDelegate. +1. Add `[PlacedAgent createWithAppKey:andDelegate:]` call to your `AppDelegate`. Optionally, you may provide a `PlacedAgentDelegate` to this method but it is not required. + ```objc + #import -2. Initialize the agent in your AppDelegate's `application:didFinishLaunchingWithOptions:`. + @implementation AppDelegate - - Call `[PlacedAgent createWithAppKey:@"" andDelegate:nil];` providing the app key you received from Placed. Optionally, you may provide a `PlacedAgentDelegate` to this method but it is not required. - - Next, call `[PlacedAgent startTracking]`. This method must be called on every app start, but will only begin location collection if the user has been registered via the `[PlacedAgent registerUser]` method (see below). + - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { + // Initialize Placed SDK + [PlacedAgent createWithAppKey:@"" andDelegate:nil] + } + ``` -3. Call `[PlacedAgent registerUser]` to register a new user for location collection by the Placed SDK. This method should only be called once in the user's lifecycle. If you have EULA or terms of service that the user is required to accept before tracking, call this method after the user accepts those terms. You may find the method `[PlacedAgent isUserRegistered]` useful for checking if `registerUser` has already been called before. +2. Once you've gathered express consent to collect user data, call `[PlacedAgent registerUser]` to register a new user for location collection by the Placed SDK. This method should only be called once in the user's lifecycle. You may find the method `[PlacedAgent isUserRegistered]` useful for checking if `registerUser` has already been called. ## How to join Please contact your Placed representative to find out how to register your account. If you do not have a representative yet, please email [affiliate@placed.com](mailto:affiliate@placed.com). diff --git a/SampleApp/Podfile b/SampleApp/Podfile index 7392bb5..6fb9f09 100644 --- a/SampleApp/Podfile +++ b/SampleApp/Podfile @@ -1,4 +1,5 @@ platform :ios, '11.0' +use_frameworks! target 'SampleApp' do pod 'Placed', :git => 'https://github.com/placed/ios-placed-sdk.git' diff --git a/SampleApp/Podfile.lock b/SampleApp/Podfile.lock deleted file mode 100644 index e9c360d..0000000 --- a/SampleApp/Podfile.lock +++ /dev/null @@ -1,24 +0,0 @@ -PODS: - - Placed (4.0.10): - - Reachability (~> 3.2) - - Reachability (3.2) - -DEPENDENCIES: - - Placed (from `https://github.com/placed/ios-placed-sdk.git`) - -EXTERNAL SOURCES: - Placed: - :git: https://github.com/placed/ios-placed-sdk.git - -CHECKOUT OPTIONS: - Placed: - :commit: 78130ff72df21541d00d6c723f129614b78e34ea - :git: https://github.com/placed/ios-placed-sdk.git - -SPEC CHECKSUMS: - Placed: c8fbbb938a921330a81e50955279cb1d6245ad88 - Reachability: 33e18b67625424e47b6cde6d202dce689ad7af96 - -PODFILE CHECKSUM: 2096e7ab3f6c7843aab3e505aef0fa7ce2837f24 - -COCOAPODS: 1.3.1 diff --git a/SampleApp/SampleApp.xcodeproj/project.pbxproj b/SampleApp/SampleApp.xcodeproj/project.pbxproj index fb95d74..429f71c 100644 --- a/SampleApp/SampleApp.xcodeproj/project.pbxproj +++ b/SampleApp/SampleApp.xcodeproj/project.pbxproj @@ -7,19 +7,23 @@ objects = { /* Begin PBXBuildFile section */ + 2BF7B92520A3AFE800EE4D52 /* SampleAlertViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 2BF7B92320A3AFE800EE4D52 /* SampleAlertViewController.m */; }; + 2BF7B92620A3AFE800EE4D52 /* SampleAlertViewController.xib in Resources */ = {isa = PBXBuildFile; fileRef = 2BF7B92420A3AFE800EE4D52 /* SampleAlertViewController.xib */; }; + 96301AE7900C9797E86D11D0 /* Pods_SampleApp.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = FC4C4B2E15741F8E2E1B30E4 /* Pods_SampleApp.framework */; }; 9B591B5A1FD6033B007630C9 /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 9B591B591FD6033B007630C9 /* AppDelegate.m */; }; 9B591B5D1FD6033B007630C9 /* ViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 9B591B5C1FD6033B007630C9 /* ViewController.m */; }; 9B591B601FD6033B007630C9 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 9B591B5E1FD6033B007630C9 /* Main.storyboard */; }; 9B591B621FD6033B007630C9 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 9B591B611FD6033B007630C9 /* Assets.xcassets */; }; 9B591B651FD6033B007630C9 /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 9B591B631FD6033B007630C9 /* LaunchScreen.storyboard */; }; 9B591B681FD6033B007630C9 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 9B591B671FD6033B007630C9 /* main.m */; }; - E364D8FC89AD27A7D922DED3 /* libPods-SampleApp.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 2EE26D6FFA64FBE040560513 /* libPods-SampleApp.a */; }; /* End PBXBuildFile section */ /* Begin PBXFileReference section */ 179D363020295416E0308F7D /* Pods-SampleApp.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-SampleApp.debug.xcconfig"; path = "Pods/Target Support Files/Pods-SampleApp/Pods-SampleApp.debug.xcconfig"; sourceTree = ""; }; 1F70B84BCD5EF859658160BE /* Pods-SampleApp.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-SampleApp.release.xcconfig"; path = "Pods/Target Support Files/Pods-SampleApp/Pods-SampleApp.release.xcconfig"; sourceTree = ""; }; - 2EE26D6FFA64FBE040560513 /* libPods-SampleApp.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-SampleApp.a"; sourceTree = BUILT_PRODUCTS_DIR; }; + 2BF7B92220A3AFE800EE4D52 /* SampleAlertViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SampleAlertViewController.h; sourceTree = ""; }; + 2BF7B92320A3AFE800EE4D52 /* SampleAlertViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = SampleAlertViewController.m; sourceTree = ""; }; + 2BF7B92420A3AFE800EE4D52 /* SampleAlertViewController.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = SampleAlertViewController.xib; sourceTree = ""; }; 9B591B551FD6033B007630C9 /* SampleApp.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = SampleApp.app; sourceTree = BUILT_PRODUCTS_DIR; }; 9B591B581FD6033B007630C9 /* AppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = ""; }; 9B591B591FD6033B007630C9 /* AppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = ""; }; @@ -30,6 +34,7 @@ 9B591B641FD6033B007630C9 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; 9B591B661FD6033B007630C9 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 9B591B671FD6033B007630C9 /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; + FC4C4B2E15741F8E2E1B30E4 /* Pods_SampleApp.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_SampleApp.framework; sourceTree = BUILT_PRODUCTS_DIR; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ @@ -37,7 +42,7 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( - E364D8FC89AD27A7D922DED3 /* libPods-SampleApp.a in Frameworks */, + 96301AE7900C9797E86D11D0 /* Pods_SampleApp.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -56,7 +61,7 @@ 4C453A66CFBDB94C9D986AFD /* Frameworks */ = { isa = PBXGroup; children = ( - 2EE26D6FFA64FBE040560513 /* libPods-SampleApp.a */, + FC4C4B2E15741F8E2E1B30E4 /* Pods_SampleApp.framework */, ); name = Frameworks; sourceTree = ""; @@ -84,6 +89,9 @@ children = ( 9B591B581FD6033B007630C9 /* AppDelegate.h */, 9B591B591FD6033B007630C9 /* AppDelegate.m */, + 2BF7B92220A3AFE800EE4D52 /* SampleAlertViewController.h */, + 2BF7B92320A3AFE800EE4D52 /* SampleAlertViewController.m */, + 2BF7B92420A3AFE800EE4D52 /* SampleAlertViewController.xib */, 9B591B5B1FD6033B007630C9 /* ViewController.h */, 9B591B5C1FD6033B007630C9 /* ViewController.m */, 9B591B5E1FD6033B007630C9 /* Main.storyboard */, @@ -106,8 +114,8 @@ 9B591B511FD6033B007630C9 /* Sources */, 9B591B521FD6033B007630C9 /* Frameworks */, 9B591B531FD6033B007630C9 /* Resources */, - F46F2528666BE2DE16647CE7 /* [CP] Embed Pods Frameworks */, 3063A9684DA9F523F30ADF2E /* [CP] Copy Pods Resources */, + 72228D0CE512AE3269B38989 /* [CP] Embed Pods Frameworks */, ); buildRules = ( ); @@ -164,6 +172,7 @@ 9B591B651FD6033B007630C9 /* LaunchScreen.storyboard in Resources */, 9B591B621FD6033B007630C9 /* Assets.xcassets in Resources */, 9B591B601FD6033B007630C9 /* Main.storyboard in Resources */, + 2BF7B92620A3AFE800EE4D52 /* SampleAlertViewController.xib in Resources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -181,44 +190,47 @@ ); name = "[CP] Copy Pods Resources"; outputPaths = ( - "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}", + "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/Placed.bundle", ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-SampleApp/Pods-SampleApp-resources.sh\"\n"; showEnvVarsInLog = 0; }; - E69845DF5A0241E1F0F3544B /* [CP] Check Pods Manifest.lock */ = { + 72228D0CE512AE3269B38989 /* [CP] Embed Pods Frameworks */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; files = ( ); inputPaths = ( - "${PODS_PODFILE_DIR_PATH}/Podfile.lock", - "${PODS_ROOT}/Manifest.lock", + "${SRCROOT}/Pods/Target Support Files/Pods-SampleApp/Pods-SampleApp-frameworks.sh", + "${PODS_ROOT}/Placed/Placed.framework", ); - name = "[CP] Check Pods Manifest.lock"; + name = "[CP] Embed Pods Frameworks"; outputPaths = ( - "$(DERIVED_FILE_DIR)/Pods-SampleApp-checkManifestLockResult.txt", + "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/Placed.framework", ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; - shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/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# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; + shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-SampleApp/Pods-SampleApp-frameworks.sh\"\n"; showEnvVarsInLog = 0; }; - F46F2528666BE2DE16647CE7 /* [CP] Embed Pods Frameworks */ = { + E69845DF5A0241E1F0F3544B /* [CP] Check Pods Manifest.lock */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; files = ( ); inputPaths = ( + "${PODS_PODFILE_DIR_PATH}/Podfile.lock", + "${PODS_ROOT}/Manifest.lock", ); - name = "[CP] Embed Pods Frameworks"; + name = "[CP] Check Pods Manifest.lock"; outputPaths = ( + "$(DERIVED_FILE_DIR)/Pods-SampleApp-checkManifestLockResult.txt", ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; - shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-SampleApp/Pods-SampleApp-frameworks.sh\"\n"; + shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/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# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; showEnvVarsInLog = 0; }; /* End PBXShellScriptBuildPhase section */ @@ -231,6 +243,7 @@ 9B591B5D1FD6033B007630C9 /* ViewController.m in Sources */, 9B591B681FD6033B007630C9 /* main.m in Sources */, 9B591B5A1FD6033B007630C9 /* AppDelegate.m in Sources */, + 2BF7B92520A3AFE800EE4D52 /* SampleAlertViewController.m in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; diff --git a/SampleApp/SampleApp.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist b/SampleApp/SampleApp.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist new file mode 100644 index 0000000..18d9810 --- /dev/null +++ b/SampleApp/SampleApp.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist @@ -0,0 +1,8 @@ + + + + + IDEDidComputeMac32BitWarning + + + diff --git a/SampleApp/SampleApp/AppDelegate.m b/SampleApp/SampleApp/AppDelegate.m index 6c3a0e3..54c713e 100644 --- a/SampleApp/SampleApp/AppDelegate.m +++ b/SampleApp/SampleApp/AppDelegate.m @@ -19,7 +19,6 @@ - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:( // Initialize Placed SDK // IMPORTANT: This is where you'll want to enter your app key. [PlacedAgent createWithAppKey:@"" andDelegate:nil]; - [PlacedAgent startTracking]; return YES; } diff --git a/SampleApp/SampleApp/Assets.xcassets/Contents.json b/SampleApp/SampleApp/Assets.xcassets/Contents.json new file mode 100644 index 0000000..da4a164 --- /dev/null +++ b/SampleApp/SampleApp/Assets.xcassets/Contents.json @@ -0,0 +1,6 @@ +{ + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/SampleApp/SampleApp/Assets.xcassets/iconNewtab.imageset/Contents.json b/SampleApp/SampleApp/Assets.xcassets/iconNewtab.imageset/Contents.json new file mode 100644 index 0000000..6a4b56a --- /dev/null +++ b/SampleApp/SampleApp/Assets.xcassets/iconNewtab.imageset/Contents.json @@ -0,0 +1,23 @@ +{ + "images" : [ + { + "idiom" : "universal", + "filename" : "iconNewtab.png", + "scale" : "1x" + }, + { + "idiom" : "universal", + "filename" : "iconNewtab@2x.png", + "scale" : "2x" + }, + { + "idiom" : "universal", + "filename" : "iconNewtab@3x.png", + "scale" : "3x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/SampleApp/SampleApp/Assets.xcassets/iconNewtab.imageset/iconNewtab.png b/SampleApp/SampleApp/Assets.xcassets/iconNewtab.imageset/iconNewtab.png new file mode 100644 index 0000000..a64260f Binary files /dev/null and b/SampleApp/SampleApp/Assets.xcassets/iconNewtab.imageset/iconNewtab.png differ diff --git a/SampleApp/SampleApp/Assets.xcassets/iconNewtab.imageset/iconNewtab@2x.png b/SampleApp/SampleApp/Assets.xcassets/iconNewtab.imageset/iconNewtab@2x.png new file mode 100644 index 0000000..3f5e83e Binary files /dev/null and b/SampleApp/SampleApp/Assets.xcassets/iconNewtab.imageset/iconNewtab@2x.png differ diff --git a/SampleApp/SampleApp/Assets.xcassets/iconNewtab.imageset/iconNewtab@3x.png b/SampleApp/SampleApp/Assets.xcassets/iconNewtab.imageset/iconNewtab@3x.png new file mode 100644 index 0000000..51ae0df Binary files /dev/null and b/SampleApp/SampleApp/Assets.xcassets/iconNewtab.imageset/iconNewtab@3x.png differ diff --git a/SampleApp/SampleApp/SampleAlertViewController.h b/SampleApp/SampleApp/SampleAlertViewController.h new file mode 100644 index 0000000..a667051 --- /dev/null +++ b/SampleApp/SampleApp/SampleAlertViewController.h @@ -0,0 +1,13 @@ +// +// SampleAlertViewController.h +// SampleApp +// +// Created by Stanislav Stasiuk on 5/9/18. +// Copyright © 2018 Placed. All rights reserved. +// + +#import + +@interface SampleAlertViewController : UIViewController + +@end diff --git a/SampleApp/SampleApp/SampleAlertViewController.m b/SampleApp/SampleApp/SampleAlertViewController.m new file mode 100644 index 0000000..e3228d2 --- /dev/null +++ b/SampleApp/SampleApp/SampleAlertViewController.m @@ -0,0 +1,54 @@ +// +// SampleAlertViewController.m +// SampleApp +// +// Created by Stanislav Stasiuk on 5/9/18. +// Copyright © 2018 Placed. All rights reserved. +// + +#import "SampleAlertViewController.h" +#import + +@interface SampleAlertViewController () + +@end + +@implementation SampleAlertViewController + +- (instancetype)init { + self = [super init]; + if (self) { + self.modalPresentationStyle = UIModalPresentationOverCurrentContext; + self.modalTransitionStyle = UIModalTransitionStyleCrossDissolve; + } + return self; +} + +- (void)viewDidLoad { + [super viewDidLoad]; +} + +#pragma mark - Actions +- (IBAction)accept:(id)sender { + // User has accepted the EULA. Call registerUser to start up the Placed SDK. + [PlacedAgent registerUser]; + [self.presentingViewController dismissViewControllerAnimated:YES completion:nil]; +} + +- (IBAction)dismiss:(id)sender { + // User has declined the EULA. Call deregisterUser to make sure the Placed SDK is shut down. + [PlacedAgent deregisterUser]; + [self.presentingViewController dismissViewControllerAnimated:YES completion:nil]; +} + +- (IBAction)showTermsOfService:(id)sender { + NSURL *url = [[NSURL alloc] initWithString:@"https://www.placed.com/terms-of-service"]; + [UIApplication.sharedApplication openURL:url options:@{} completionHandler:nil]; +} + +- (IBAction)showPrivacyPolicy:(id)sender { + NSURL *url = [[NSURL alloc] initWithString:@"https://www.placed.com/privacy-policy"]; + [UIApplication.sharedApplication openURL:url options:@{} completionHandler:nil]; +} + +@end diff --git a/SampleApp/SampleApp/SampleAlertViewController.xib b/SampleApp/SampleApp/SampleAlertViewController.xib new file mode 100644 index 0000000..3a57395 --- /dev/null +++ b/SampleApp/SampleApp/SampleAlertViewController.xib @@ -0,0 +1,138 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/SampleApp/SampleApp/ViewController.m b/SampleApp/SampleApp/ViewController.m index 3ff776c..66da48e 100644 --- a/SampleApp/SampleApp/ViewController.m +++ b/SampleApp/SampleApp/ViewController.m @@ -7,6 +7,7 @@ // #import "ViewController.h" +#import "SampleAlertViewController.h" #import @interface ViewController () @@ -17,12 +18,24 @@ @implementation ViewController - (void)viewDidLoad { [super viewDidLoad]; - // Do any additional setup after loading the view, typically from a nib. } - (IBAction)registerUser:(id)sender { - // "Register User" button clicked - [PlacedAgent registerUser]; + if (![PlacedAgent isUserRegistered]) { + // If the user isn't registered with the Placed SDK, we'll show them the EULA so they can opt in. + [self presentViewController:[SampleAlertViewController new] animated:YES completion:nil]; + } else { + UIAlertController *successAlert = [UIAlertController + alertControllerWithTitle:@"User registered!" + message:@"The user is registered and the Placed SDK is running." + preferredStyle:UIAlertControllerStyleAlert]; + UIAlertAction *okButton = [UIAlertAction + actionWithTitle:@"OK" + style:UIAlertActionStyleDefault + handler:nil]; + [successAlert addAction:okButton]; + [self presentViewController:successAlert animated:YES completion:nil]; + } } @end diff --git a/gallery/aff-iOS-optin-dialogue1.jpg b/gallery/aff-iOS-optin-dialogue1.jpg new file mode 100755 index 0000000..68bc6a6 Binary files /dev/null and b/gallery/aff-iOS-optin-dialogue1.jpg differ diff --git a/gallery/aff-iOS-optin-dialogue2.jpg b/gallery/aff-iOS-optin-dialogue2.jpg new file mode 100755 index 0000000..087bc15 Binary files /dev/null and b/gallery/aff-iOS-optin-dialogue2.jpg differ diff --git a/gallery/aff-iOS-optin-full1.jpg b/gallery/aff-iOS-optin-full1.jpg new file mode 100755 index 0000000..7129f7d Binary files /dev/null and b/gallery/aff-iOS-optin-full1.jpg differ diff --git a/gallery/aff-iOS-optin-full2.jpg b/gallery/aff-iOS-optin-full2.jpg new file mode 100755 index 0000000..14f68b3 Binary files /dev/null and b/gallery/aff-iOS-optin-full2.jpg differ diff --git a/gallery/aff-iOS-optin-full3.jpg b/gallery/aff-iOS-optin-full3.jpg new file mode 100755 index 0000000..b40b2e6 Binary files /dev/null and b/gallery/aff-iOS-optin-full3.jpg differ diff --git a/image_0.png b/image_0.png deleted file mode 100644 index 81d1336..0000000 Binary files a/image_0.png and /dev/null differ