├── Cartfile ├── mParticle-ButtonTests ├── Helpers │ ├── mParticle-ButtonTests-Bridging-Header.h │ ├── MPKitButton+ButtonTests.m │ └── MPKitButton+ButtonTests.h ├── Info.plist └── mParticle-ButtonTests.swift ├── Cartfile.resolved ├── .travis.yml ├── mParticle-Button ├── mParticle_Button.h ├── Info.plist ├── MPKitButton.h └── MPKitButton.m ├── .github └── workflows │ └── Test.yml ├── mParticle-Button.podspec ├── mParticle_Button.json ├── .gitignore ├── README.md ├── mParticle-Button.xcodeproj ├── xcshareddata │ └── xcschemes │ │ ├── mParticle-ButtonTests.xcscheme │ │ └── mParticle-Button.xcscheme └── project.pbxproj └── LICENSE /Cartfile: -------------------------------------------------------------------------------- 1 | github "mparticle/mparticle-apple-sdk" ~> 7.10.0 2 | github "button/button-merchant-ios" ~> 1.0 3 | -------------------------------------------------------------------------------- /mParticle-ButtonTests/Helpers/mParticle-ButtonTests-Bridging-Header.h: -------------------------------------------------------------------------------- 1 | #import "MPKitButton+ButtonTests.h" 2 | -------------------------------------------------------------------------------- /Cartfile.resolved: -------------------------------------------------------------------------------- 1 | github "button/button-merchant-ios" "1.3.0" 2 | github "mparticle/mparticle-apple-sdk" "7.16.2" 3 | -------------------------------------------------------------------------------- /mParticle-ButtonTests/Helpers/MPKitButton+ButtonTests.m: -------------------------------------------------------------------------------- 1 | #import "MPKitButton+ButtonTests.h" 2 | 3 | @implementation MPKitButton (ButtonTests) 4 | @dynamic mParticleInstance; 5 | @end 6 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | osx_image: xcode9.3 2 | language: objective-c 3 | script: 4 | - sudo gem install cocoapods -v 1.5.0 5 | - travis_retry pod repo update > /dev/null 6 | - pod lib lint --use-libraries --allow-warnings || pod lib lint --allow-warnings 7 | -------------------------------------------------------------------------------- /mParticle-ButtonTests/Helpers/MPKitButton+ButtonTests.h: -------------------------------------------------------------------------------- 1 | #import "mParticle_Button.h" 2 | 3 | @interface MPKitButton (ButtonTests) 4 | @property (nonatomic, strong) MParticle *mParticleInstance; 5 | @property (nonatomic, strong) NSNotificationCenter *defaultCenter; 6 | @end 7 | 8 | 9 | -------------------------------------------------------------------------------- /mParticle-Button/mParticle_Button.h: -------------------------------------------------------------------------------- 1 | #import 2 | @import ButtonMerchant; 3 | 4 | //! Project version number for mParticle-Button. 5 | FOUNDATION_EXPORT double mParticle_ButtonVersionNumber; 6 | 7 | //! Project version string for mParticle-Button. 8 | FOUNDATION_EXPORT const unsigned char mParticle_ButtonVersionString[]; 9 | 10 | // In this header, you should import all the public headers of your framework using statements like #import 11 | 12 | #import 13 | -------------------------------------------------------------------------------- /.github/workflows/Test.yml: -------------------------------------------------------------------------------- 1 | name: Run tests 2 | 3 | on: pull_request 4 | 5 | jobs: 6 | build: 7 | 8 | runs-on: macos-latest 9 | 10 | steps: 11 | - name: Clone Repo 12 | uses: actions/checkout@v1 13 | 14 | - uses: actions/cache@v2 15 | with: 16 | path: Carthage 17 | key: ${{ runner.os }}-carthage-${{ hashFiles('**/Cartfile.resolved') }} 18 | restore-keys: | 19 | ${{ runner.os }}-carthage- 20 | 21 | - name: Carthage 22 | run: carthage update 23 | 24 | - name: Test 25 | run: | 26 | xcodebuild \ 27 | -project mParticle-Button.xcodeproj \ 28 | -scheme mParticle-Button \ 29 | -destination "platform=iOS Simulator,name=iPhone 11,OS=latest" \ 30 | clean test 31 | -------------------------------------------------------------------------------- /mParticle-ButtonTests/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | $(DEVELOPMENT_LANGUAGE) 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | BNDL 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleVersion 20 | 1 21 | 22 | 23 | -------------------------------------------------------------------------------- /mParticle-Button/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | FMWK 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleVersion 20 | $(CURRENT_PROJECT_VERSION) 21 | NSPrincipalClass 22 | 23 | 24 | 25 | -------------------------------------------------------------------------------- /mParticle-Button.podspec: -------------------------------------------------------------------------------- 1 | Pod::Spec.new do |s| 2 | s.name = "mParticle-Button" 3 | s.version = "7.10.0" 4 | s.summary = "Button integration for mParticle" 5 | 6 | s.description = <<-DESC 7 | This is the Button integration for mParticle. 8 | DESC 9 | 10 | s.homepage = "https://www.mparticle.com" 11 | s.license = { :type => 'Apache 2.0', :file => 'LICENSE' } 12 | s.author = { "mParticle" => "support@mparticle.com" } 13 | s.source = { :git => "https://github.com/mparticle-integrations/mparticle-apple-integration-button.git", :tag => s.version.to_s } 14 | s.social_media_url = "https://twitter.com/mparticle" 15 | 16 | s.ios.deployment_target = "9.0" 17 | s.ios.source_files = 'mParticle-Button/*.{h,m,mm}' 18 | s.ios.dependency 'mParticle-Apple-SDK/mParticle', '~> 7.10.0' 19 | s.ios.dependency 'ButtonMerchant', '~> 1' 20 | end 21 | -------------------------------------------------------------------------------- /mParticle-Button/MPKitButton.h: -------------------------------------------------------------------------------- 1 | #import 2 | #import 3 | #if defined(__has_include) && __has_include() 4 | #import 5 | #else 6 | #import "mParticle.h" 7 | #endif 8 | 9 | extern NSString * _Nonnull const MPKitButtonErrorDomain; 10 | extern NSString * _Nonnull const MPKitButtonErrorMessageKey; 11 | 12 | /// A key into the linkInfo passed to the onAttributionComplete handler. 13 | /// (Note: This key will be set to the same value as `BTNDeferredDeepLinkURLKey`. 14 | /// We added it later to match the naming convention used by other kits.) 15 | extern NSString * _Nonnull const MPKitButtonAttributionResultKey; 16 | 17 | /// A key into the linkInfo passed to the onAttributionComplete handler. 18 | extern NSString * _Nonnull const BTNPostInstallURLKey; 19 | 20 | #pragma mark - MPIButton 21 | @interface MPIButton : NSObject 22 | 23 | /// Returns the Button referrer token if present (i.e. btn_ref). 24 | @property (nonatomic, copy, readonly, nullable) NSString *attributionToken; 25 | 26 | @end 27 | 28 | 29 | #pragma mark - MPKitButton 30 | @interface MPKitButton : NSObject 31 | 32 | @property (nonatomic, strong, nonnull) NSDictionary *configuration; 33 | @property (nonatomic, unsafe_unretained, readonly) BOOL started; 34 | 35 | @end 36 | -------------------------------------------------------------------------------- /mParticle_Button.json: -------------------------------------------------------------------------------- 1 | { 2 | "7.7.4": "https://github.com/mparticle-integrations/mparticle-apple-integration-button/releases/download/7.7.4/mParticle_Button.framework.zip", 3 | "7.7.5": "https://github.com/mparticle-integrations/mparticle-apple-integration-button/releases/download/7.7.5/mParticle_Button.framework.zip", 4 | "7.8.0": "https://github.com/mparticle-integrations/mparticle-apple-integration-button/releases/download/7.8.0/mParticle_Button.framework.zip", 5 | "7.8.1": "https://github.com/mparticle-integrations/mparticle-apple-integration-button/releases/download/7.8.1/mParticle_Button.framework.zip", 6 | "7.8.2": "https://github.com/mparticle-integrations/mparticle-apple-integration-button/releases/download/7.8.2/mParticle_Button.framework.zip", 7 | "7.8.3": "https://github.com/mparticle-integrations/mparticle-apple-integration-button/releases/download/7.8.3/mParticle_Button.framework.zip", 8 | "7.8.4": "https://github.com/mparticle-integrations/mparticle-apple-integration-button/releases/download/7.8.4/mParticle_Button.framework.zip", 9 | "7.8.5": "https://github.com/mparticle-integrations/mparticle-apple-integration-button/releases/download/7.8.5/mParticle_Button.framework.zip", 10 | "7.8.6": "https://github.com/mparticle-integrations/mparticle-apple-integration-button/releases/download/7.8.6/mParticle_Button.framework.zip", 11 | "7.9.0": "https://github.com/mparticle-integrations/mparticle-apple-integration-button/releases/download/7.9.0/mParticle_Button.framework.zip", 12 | "7.9.1": "https://github.com/mparticle-integrations/mparticle-apple-integration-button/releases/download/7.9.1/mParticle_Button.framework.zip" 13 | } 14 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Xcode 2 | # 3 | # gitignore contributors: remember to update Global/Xcode.gitignore, Objective-C.gitignore & Swift.gitignore 4 | 5 | ## Build generated 6 | build/ 7 | DerivedData/ 8 | 9 | ## Various settings 10 | *.pbxuser 11 | !default.pbxuser 12 | *.mode1v3 13 | !default.mode1v3 14 | *.mode2v3 15 | !default.mode2v3 16 | *.perspectivev3 17 | !default.perspectivev3 18 | xcuserdata/ 19 | 20 | ## Other 21 | *.moved-aside 22 | *.xcuserstate 23 | .DS_Store 24 | 25 | ## Obj-C/Swift specific 26 | *.hmap 27 | *.ipa 28 | 29 | ## Playgrounds 30 | timeline.xctimeline 31 | playground.xcworkspace 32 | 33 | # Swift Package Manager 34 | # 35 | # Add this line if you want to avoid checking in source code from Swift Package Manager dependencies. 36 | # Packages/ 37 | .build/ 38 | 39 | # CocoaPods 40 | # 41 | # We recommend against adding the Pods directory to your .gitignore. However 42 | # you should judge for yourself, the pros and cons are mentioned at: 43 | # https://guides.cocoapods.org/using/using-cocoapods.html#should-i-check-the-pods-directory-into-source-control 44 | # 45 | Pods/ 46 | 47 | # Carthage 48 | # 49 | # Add this line if you want to avoid checking in source code from Carthage dependencies. 50 | Carthage/Checkouts 51 | 52 | Carthage/Build 53 | 54 | # fastlane 55 | # 56 | # It is recommended to not store the screenshots in the git repo. Instead, use fastlane to re-generate the 57 | # screenshots whenever they are needed. 58 | # For more information about the recommended setup visit: 59 | # https://github.com/fastlane/fastlane/blob/master/fastlane/docs/Gitignore.md 60 | 61 | fastlane/report.xml 62 | fastlane/Preview.html 63 | fastlane/screenshots 64 | fastlane/test_output 65 | 66 | **/Podfile.lock 67 | **/*.xcworkspace 68 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ## Button Kit Integration 2 | 3 | This repository contains the [Button](https://www.usebutton.com) integration for the [mParticle Apple SDK](https://github.com/mParticle/mparticle-apple-sdk). 4 | 5 | ### Adding the integration 6 | 7 | 1. Add the kit dependency to your app's Podfile or Cartfile: 8 | 9 | ``` 10 | pod 'mParticle-Button', '~> 7.0' 11 | ``` 12 | 13 | OR 14 | 15 | ``` 16 | github 'mparticle-integrations/mparticle-apple-integration-button' ~> 7.0 17 | ``` 18 | 19 | 2. Follow the mParticle iOS SDK [quick-start](https://github.com/mParticle/mparticle-apple-sdk), then rebuild and launch your app, and verify that you see `"Included kits: { Button }"` in your Xcode console 20 | 21 | > (This requires your mParticle log level to be at least Debug) 22 | 23 | 3. Reference mParticle's integration docs below to enable the integration. 24 | 25 | ## Deep-linking 26 | 27 | Set the property `onAttributionComplete:` on `MParticleOptions` when initializing the mParticle SDK. A copy of your block will be invoked to provide the respective information: 28 | 29 | ```objective-c 30 | - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { 31 | MParticleOptions *options = [MParticleOptions optionsWithKey:@"<>" secret:@"<>"]; 32 | options.onAttributionComplete = ^void (MPAttributionResult *_Nullable attributionResult, NSError * _Nullable error) { 33 | if (error) { 34 | NSLog(@"Attribution fetching for kitCode=%@ failed with error=%@", error.userInfo[mParticleKitInstanceKey], error); 35 | return; 36 | } 37 | 38 | NSLog(@"Attribution fetching for kitCode=%@ completed with linkInfo: %@", attributionResult.kitCode, attributionResult.linkInfo); 39 | 40 | } 41 | [[MParticle sharedInstance] startWithOptions:options]; 42 | 43 | return YES; 44 | } 45 | ``` 46 | 47 | ### Documentation 48 | 49 | [Button integration](https://docs.mparticle.com/integrations/button/event/) 50 | 51 | ### License 52 | 53 | [Apache License 2.0](http://www.apache.org/licenses/LICENSE-2.0) 54 | -------------------------------------------------------------------------------- /mParticle-Button.xcodeproj/xcshareddata/xcschemes/mParticle-ButtonTests.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 30 | 31 | 33 | 39 | 40 | 41 | 42 | 43 | 49 | 50 | 51 | 52 | 53 | 54 | 64 | 65 | 71 | 72 | 73 | 74 | 75 | 76 | 82 | 83 | 89 | 90 | 91 | 92 | 94 | 95 | 98 | 99 | 100 | -------------------------------------------------------------------------------- /mParticle-Button.xcodeproj/xcshareddata/xcschemes/mParticle-Button.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 29 | 35 | 36 | 37 | 38 | 39 | 44 | 45 | 51 | 52 | 53 | 54 | 56 | 62 | 63 | 64 | 65 | 66 | 76 | 77 | 83 | 84 | 85 | 86 | 92 | 93 | 99 | 100 | 101 | 102 | 104 | 105 | 108 | 109 | 110 | -------------------------------------------------------------------------------- /mParticle-Button/MPKitButton.m: -------------------------------------------------------------------------------- 1 | // 2 | // MPKitButton.m 3 | // 4 | // Copyright 2019 Button, Inc. 5 | // 6 | // Licensed under the Apache License, Version 2.0 (the "License"); 7 | // you may not use this file except in compliance with the License. 8 | // You may obtain a copy of the License at 9 | // 10 | // http://www.apache.org/licenses/LICENSE-2.0 11 | // 12 | // Unless required by applicable law or agreed to in writing, software 13 | // distributed under the License is distributed on an "AS IS" BASIS, 14 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | // See the License for the specific language governing permissions and 16 | // limitations under the License. 17 | // 18 | 19 | #import "MPKitButton.h" 20 | 21 | @import ButtonMerchant; 22 | 23 | static NSString * const BTNMPKitVersion = @"2.0.0"; 24 | 25 | static NSString * const BTNReferrerTokenDefaultsKey = @"com.usebutton.referrer"; 26 | static NSString * const BTNLinkFetchStatusDefaultsKey = @"com.usebutton.link.fetched"; 27 | 28 | NSString * const MPKitButtonAttributionResultKey = @"mParticle-Button Attribution Result"; 29 | NSString * const BTNPostInstallURLKey = @"BTNPostInstallURLKey"; 30 | 31 | NSString * const MPKitButtonErrorDomain = @"com.mparticle.kits.button"; 32 | NSString * const MPKitButtonErrorMessageKey = @"mParticle-Button Error"; 33 | NSString * const MPKitButtonIntegrationAttribution = @"com.usebutton.source_token"; 34 | 35 | 36 | #pragma mark - MPIButton 37 | 38 | @implementation MPIButton 39 | 40 | - (instancetype)init { 41 | self = [super init]; 42 | return self; 43 | } 44 | 45 | 46 | - (NSString *)attributionToken { 47 | return ButtonMerchant.attributionToken; 48 | } 49 | 50 | @end 51 | 52 | 53 | #pragma mark - MPKitButton 54 | 55 | @interface MPKitButton () 56 | 57 | @property (nonatomic, strong) MParticle *mParticleInstance; 58 | @property (nonatomic, strong, nonnull) MPIButton *button; 59 | @property (nonatomic, copy) NSString *applicationId; 60 | @property (nonatomic, strong) NSNotificationCenter *defaultCenter; 61 | 62 | @end 63 | 64 | 65 | @implementation MPKitButton 66 | 67 | @synthesize kitApi = _kitApi; 68 | 69 | + (NSNumber *)kitCode { 70 | return @1022; 71 | } 72 | 73 | 74 | + (void)load { 75 | MPKitRegister *kitRegister = [[MPKitRegister alloc] initWithName:@"Button" 76 | className:NSStringFromClass(self)]; 77 | [MParticle registerExtension:kitRegister]; 78 | } 79 | 80 | 81 | - (MParticle *)mParticleInstance { 82 | if (!_mParticleInstance) { 83 | _mParticleInstance = [MParticle sharedInstance]; 84 | } 85 | return _mParticleInstance; 86 | } 87 | 88 | 89 | - (NSNotificationCenter *)defaultCenter { 90 | if (!_defaultCenter) { 91 | _defaultCenter = NSNotificationCenter.defaultCenter; 92 | } 93 | return _defaultCenter; 94 | } 95 | 96 | 97 | - (void)trackIncomingURL:(NSURL *)url { 98 | [ButtonMerchant trackIncomingURL:url]; 99 | } 100 | 101 | 102 | #pragma mark - MPKitInstanceProtocol methods 103 | 104 | - (MPKitExecStatus *)didFinishLaunchingWithConfiguration:(NSDictionary *)configuration { 105 | MPKitExecStatus *execStatus = nil; 106 | _button = [[MPIButton alloc] init]; 107 | _applicationId = [configuration[@"application_id"] copy]; 108 | if (!_applicationId) { 109 | execStatus = [[MPKitExecStatus alloc] initWithSDKCode:[[self class] kitCode] returnCode:MPKitReturnCodeRequirementsNotMet]; 110 | return execStatus; 111 | } 112 | 113 | [ButtonMerchant configureWithApplicationId:_applicationId]; 114 | [self.defaultCenter addObserver:self 115 | selector:@selector(observeAttributionTokenDidChangeNotification:) 116 | name:ButtonMerchant.AttributionTokenDidChangeNotification 117 | object:nil]; 118 | 119 | _configuration = configuration; 120 | _started = YES; 121 | 122 | dispatch_async(dispatch_get_main_queue(), ^{ 123 | [self checkForAttribution]; 124 | }); 125 | 126 | execStatus = [[MPKitExecStatus alloc] initWithSDKCode:[[self class] kitCode] returnCode:MPKitReturnCodeSuccess]; 127 | 128 | return execStatus; 129 | } 130 | 131 | 132 | - (id)providerKitInstance { 133 | return [self started] ? self.button : nil; 134 | } 135 | 136 | 137 | - (nonnull MPKitExecStatus *)openURL:(nonnull NSURL *)url options:(nullable NSDictionary *)options { 138 | [self trackIncomingURL:url]; 139 | return [[MPKitExecStatus alloc] initWithSDKCode:[[self class] kitCode] 140 | returnCode:MPKitReturnCodeSuccess]; 141 | } 142 | 143 | 144 | - (nonnull MPKitExecStatus *)openURL:(nonnull NSURL *)url sourceApplication:(nullable NSString *)sourceApplication annotation:(nullable id)annotation { 145 | [self trackIncomingURL:url]; 146 | return [[MPKitExecStatus alloc] initWithSDKCode:[[self class] kitCode] 147 | returnCode:MPKitReturnCodeSuccess]; 148 | } 149 | 150 | 151 | - (nonnull MPKitExecStatus *)continueUserActivity:(nonnull NSUserActivity *)userActivity restorationHandler:(void(^ _Nonnull)(NSArray * _Nullable restorableObjects))restorationHandler { 152 | [self trackIncomingURL:userActivity.webpageURL]; 153 | return [[MPKitExecStatus alloc] initWithSDKCode:[[self class] kitCode] 154 | returnCode:MPKitReturnCodeSuccess]; 155 | } 156 | 157 | 158 | #pragma mark - Private Methods 159 | 160 | - (NSError *)errorWithMessage:(NSString *)message { 161 | NSError *error = [NSError errorWithDomain:MPKitButtonErrorDomain code:0 userInfo:@{MPKitButtonErrorMessageKey: message}]; 162 | return error; 163 | } 164 | 165 | 166 | - (void)checkForAttribution { 167 | [ButtonMerchant handlePostInstallURL:^(NSURL * _Nullable postInstallURL, NSError * _Nullable error) { 168 | if (error || !postInstallURL) { 169 | NSError *attributionError = [self errorWithMessage:@"No attribution information available."]; 170 | [self->_kitApi onAttributionCompleteWithResult:nil error:attributionError]; 171 | return; 172 | } 173 | NSDictionary *linkInfo = @{ BTNPostInstallURLKey: postInstallURL.absoluteString }; 174 | MPAttributionResult *attributionResult = [[MPAttributionResult alloc] init]; 175 | attributionResult.linkInfo = linkInfo; 176 | [self->_kitApi onAttributionCompleteWithResult:attributionResult error:nil]; 177 | }]; 178 | } 179 | 180 | 181 | - (void)observeAttributionTokenDidChangeNotification:(NSNotification *)note { 182 | NSString *attributionToken = note.userInfo[ButtonMerchant.AttributionTokenKey]; 183 | if (attributionToken) { 184 | NSDictionary *integrationAttributes = @{ MPKitButtonIntegrationAttribution: attributionToken }; 185 | [self.mParticleInstance setIntegrationAttributes:integrationAttributes forKit:[[self class] kitCode]]; 186 | } 187 | } 188 | 189 | @end 190 | -------------------------------------------------------------------------------- /mParticle-ButtonTests/mParticle-ButtonTests.swift: -------------------------------------------------------------------------------- 1 | import XCTest 2 | import ButtonMerchant 3 | import mParticle_Button 4 | 5 | class Actual { 6 | static var applicationId: String? 7 | } 8 | 9 | class Stub { 10 | static var url: URL? 11 | static var error: NSError? 12 | } 13 | 14 | extension ButtonMerchant { 15 | @objc public static func configure(applicationId: String) { 16 | Actual.applicationId = applicationId 17 | } 18 | @objc public static func handlePostInstallURL(_ completion: @escaping (URL?, Error?) -> Void) { 19 | completion(Stub.url, Stub.error) 20 | } 21 | } 22 | 23 | class TestMParticle: MParticle { 24 | var actualIntegrationAttributes: [String : String]! 25 | var actualKitCode: NSNumber! 26 | override func setIntegrationAttributes(_ attributes: [String : String], forKit kitCode: NSNumber) -> MPKitExecStatus { 27 | actualIntegrationAttributes = attributes 28 | actualKitCode = kitCode 29 | return MPKitExecStatus() 30 | } 31 | } 32 | 33 | class TestMPKitAPI: MPKitAPI { 34 | var onAttributionCompleteTestHandler: ((MPAttributionResult?, NSError?) -> ())! 35 | open override func onAttributionComplete(with result: MPAttributionResult?, error: Error?) { 36 | onAttributionCompleteTestHandler(result, error as NSError?) 37 | } 38 | } 39 | 40 | class TestNotificationCenter: NotificationCenter { 41 | var actualObserver: MPKitButton? 42 | var actualSelector: Selector? 43 | var actualName: NSNotification.Name? 44 | var actualObject: Any? 45 | override func addObserver(_ observer: Any, 46 | selector aSelector: Selector, 47 | name aName: NSNotification.Name?, 48 | object anObject: Any?) { 49 | actualObserver = observer as? MPKitButton 50 | actualSelector = aSelector 51 | actualName = aName 52 | actualObject = anObject 53 | } 54 | } 55 | 56 | class mParticle_ButtonTests: XCTestCase { 57 | 58 | var testMParticleInstance: TestMParticle! 59 | var buttonKit: MPKitButton! 60 | var buttonInstance: MPIButton! 61 | var applicationId: String = "app-\(arc4random_uniform(10000))" 62 | 63 | override func setUp() { 64 | super.setUp() 65 | // Reset all static test output & stubs. 66 | Actual.applicationId = nil 67 | Stub.url = nil 68 | Stub.error = nil 69 | 70 | // Start the Button kit. 71 | buttonKit = MPKitButton() 72 | testMParticleInstance = TestMParticle() 73 | buttonKit.mParticleInstance = testMParticleInstance 74 | let configuration = ["application_id": applicationId] 75 | buttonKit.didFinishLaunching(withConfiguration: configuration) 76 | buttonInstance = buttonKit.providerKitInstance as? MPIButton 77 | } 78 | 79 | func testKitCode() { 80 | XCTAssertEqual(MPKitButton.kitCode(), 1022) 81 | } 82 | 83 | func testDidFinishLaunchingWithConfiguration() { 84 | // Arrange 85 | let testNotificationCenter = TestNotificationCenter() 86 | buttonKit.defaultCenter = testNotificationCenter 87 | 88 | // Act 89 | let configuration = ["application_id": applicationId] 90 | buttonKit.didFinishLaunching(withConfiguration: configuration) 91 | 92 | // Assert 93 | XCTAssertEqual(Actual.applicationId, applicationId) 94 | XCTAssertEqual(testNotificationCenter.actualObserver, buttonKit) 95 | XCTAssertEqual(testNotificationCenter.actualSelector, NSSelectorFromString("observeAttributionTokenDidChangeNotification:")) 96 | XCTAssertEqual(testNotificationCenter.actualName, NSNotification.Name.Button.AttributionTokenDidChange) 97 | XCTAssertNil(testNotificationCenter.actualObject) 98 | } 99 | 100 | func testOpenURLOptionsTracks() { 101 | 102 | // Arrange 103 | let attributionToken = "testtoken-\(arc4random_uniform(10000))" 104 | let url = URL(string: "https://usebutton.com?btn_ref=\(attributionToken)")! 105 | 106 | // Act 107 | buttonKit.open(url, options: nil) 108 | 109 | // Assert 110 | XCTAssertEqual(ButtonMerchant.attributionToken, attributionToken) 111 | XCTAssertEqual(buttonInstance.attributionToken, attributionToken) 112 | XCTAssertEqual(testMParticleInstance.actualIntegrationAttributes, [ "com.usebutton.source_token": attributionToken ]) 113 | } 114 | 115 | func testOpenURLSourceApplicationAnnotationTracks() { 116 | 117 | // Arrange 118 | let attributionToken = "testtoken-\(arc4random_uniform(10000))" 119 | let url = URL(string: "https://usebutton.com?btn_ref=\(attributionToken)")! 120 | 121 | // Act 122 | buttonKit.open(url, sourceApplication: "test", annotation: nil) 123 | 124 | // Assert 125 | XCTAssertEqual(ButtonMerchant.attributionToken, attributionToken) 126 | XCTAssertEqual(buttonInstance.attributionToken, attributionToken) 127 | XCTAssertEqual(testMParticleInstance.actualIntegrationAttributes, [ "com.usebutton.source_token": attributionToken ]) 128 | } 129 | 130 | func testContinueUserActivityTracks() { 131 | 132 | // Arrange 133 | let attributionToken = "testtoken-\(arc4random_uniform(10000))" 134 | let url = URL(string: "https://usebutton.com?btn_ref=\(attributionToken)")! 135 | let userActivity = NSUserActivity(activityType: "web") 136 | userActivity.webpageURL = url 137 | 138 | // Act 139 | buttonKit.continue(userActivity) { handler in } 140 | 141 | // Assert 142 | XCTAssertEqual(ButtonMerchant.attributionToken, attributionToken) 143 | XCTAssertEqual(buttonInstance.attributionToken, attributionToken) 144 | XCTAssertEqual(testMParticleInstance.actualIntegrationAttributes, [ "com.usebutton.source_token": attributionToken ]) 145 | } 146 | 147 | func testPostInstallCheckOnAttribution() { 148 | 149 | // Arrange 150 | buttonKit = MPKitButton() 151 | let expectation = self.expectation(description: "post-install-url-check") 152 | let configuration = ["application_id": applicationId] 153 | let attributionToken = "testtoken-\(arc4random_uniform(10000))" 154 | let url = URL(string: "https://usebutton.com?btn_ref=\(attributionToken)")! 155 | let testKitApi = TestMPKitAPI() 156 | buttonKit.kitApi = testKitApi 157 | Stub.url = url 158 | 159 | // Act 160 | buttonKit.didFinishLaunching(withConfiguration: configuration) 161 | 162 | // Assert 163 | testKitApi.onAttributionCompleteTestHandler = { result, error in 164 | let actualURL = result?.linkInfo[BTNPostInstallURLKey] as? String 165 | XCTAssertEqual(actualURL, url.absoluteString) 166 | XCTAssertNotNil(url) 167 | XCTAssertNil(error) 168 | expectation.fulfill() 169 | } 170 | 171 | self.wait(for: [expectation], timeout: 1.0) 172 | } 173 | 174 | func testPostInstallCheckOnNoAttribution() { 175 | 176 | // Arrange 177 | buttonKit = MPKitButton() 178 | let expectation = self.expectation(description: "post-install-url-check") 179 | let configuration = ["application_id": applicationId] 180 | let testKitApi = TestMPKitAPI() 181 | buttonKit.kitApi = testKitApi 182 | Stub.error = NSError(domain: "test", code: -1, userInfo: nil) 183 | 184 | // Act 185 | buttonKit.didFinishLaunching(withConfiguration: configuration) 186 | 187 | // Assert 188 | testKitApi.onAttributionCompleteTestHandler = { result, error in 189 | let message = error?.userInfo[MPKitButtonErrorMessageKey] as? String 190 | XCTAssertEqual(message, "No attribution information available.") 191 | XCTAssertNotNil(error) 192 | XCTAssertNil(result) 193 | expectation.fulfill() 194 | } 195 | 196 | self.wait(for: [expectation], timeout: 1.0) 197 | } 198 | 199 | func testPostInstallCheckOnError() { 200 | 201 | // Arrange 202 | buttonKit = MPKitButton() 203 | let expectation = self.expectation(description: "post-install-url-check") 204 | let configuration = ["application_id": applicationId] 205 | let testKitApi = TestMPKitAPI() 206 | buttonKit.kitApi = testKitApi 207 | Stub.url = nil 208 | 209 | // Act 210 | buttonKit.didFinishLaunching(withConfiguration: configuration) 211 | 212 | // Assert 213 | testKitApi.onAttributionCompleteTestHandler = { result, error in 214 | let message = error?.userInfo[MPKitButtonErrorMessageKey] as? String 215 | XCTAssertEqual(message, "No attribution information available.") 216 | XCTAssertNotNil(error) 217 | XCTAssertNil(result) 218 | expectation.fulfill() 219 | } 220 | 221 | self.wait(for: [expectation], timeout: 1.0) 222 | } 223 | 224 | func testAttributionDidChangeNotificationSetsIntegrationAttributes() { 225 | // Arrange 226 | let attributionToken = "faketok-from-notification" 227 | 228 | // Act 229 | NotificationCenter.default.post(name: Notification.Name.Button.AttributionTokenDidChange, 230 | object: nil, 231 | userInfo: [Notification.Key.NewToken: attributionToken]) 232 | // Assert 233 | XCTAssertEqual(testMParticleInstance.actualIntegrationAttributes, [ "com.usebutton.source_token": attributionToken ]) 234 | } 235 | } 236 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright 2019 mParticle, Inc. 2 | 3 | Licensed under the Apache License, Version 2.0 (the "License"); 4 | you may not use this file except in compliance with the License. 5 | You may obtain a copy of the License at 6 | 7 | http://www.apache.org/licenses/LICENSE-2.0 8 | 9 | Unless required by applicable law or agreed to in writing, software 10 | distributed under the License is distributed on an "AS IS" BASIS, 11 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | See the License for the specific language governing permissions and 13 | limitations under the License. 14 | 15 | 16 | Apache License 17 | Version 2.0, January 2004 18 | http://www.apache.org/licenses/ 19 | 20 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 21 | 22 | 1. Definitions. 23 | 24 | "License" shall mean the terms and conditions for use, reproduction, 25 | and distribution as defined by Sections 1 through 9 of this document. 26 | 27 | "Licensor" shall mean the copyright owner or entity authorized by 28 | the copyright owner that is granting the License. 29 | 30 | "Legal Entity" shall mean the union of the acting entity and all 31 | other entities that control, are controlled by, or are under common 32 | control with that entity. For the purposes of this definition, 33 | "control" means (i) the power, direct or indirect, to cause the 34 | direction or management of such entity, whether by contract or 35 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 36 | outstanding shares, or (iii) beneficial ownership of such entity. 37 | 38 | "You" (or "Your") shall mean an individual or Legal Entity 39 | exercising permissions granted by this License. 40 | 41 | "Source" form shall mean the preferred form for making modifications, 42 | including but not limited to software source code, documentation 43 | source, and configuration files. 44 | 45 | "Object" form shall mean any form resulting from mechanical 46 | transformation or translation of a Source form, including but 47 | not limited to compiled object code, generated documentation, 48 | and conversions to other media types. 49 | 50 | "Work" shall mean the work of authorship, whether in Source or 51 | Object form, made available under the License, as indicated by a 52 | copyright notice that is included in or attached to the work 53 | (an example is provided in the Appendix below). 54 | 55 | "Derivative Works" shall mean any work, whether in Source or Object 56 | form, that is based on (or derived from) the Work and for which the 57 | editorial revisions, annotations, elaborations, or other modifications 58 | represent, as a whole, an original work of authorship. For the purposes 59 | of this License, Derivative Works shall not include works that remain 60 | separable from, or merely link (or bind by name) to the interfaces of, 61 | the Work and Derivative Works thereof. 62 | 63 | "Contribution" shall mean any work of authorship, including 64 | the original version of the Work and any modifications or additions 65 | to that Work or Derivative Works thereof, that is intentionally 66 | submitted to Licensor for inclusion in the Work by the copyright owner 67 | or by an individual or Legal Entity authorized to submit on behalf of 68 | the copyright owner. For the purposes of this definition, "submitted" 69 | means any form of electronic, verbal, or written communication sent 70 | to the Licensor or its representatives, including but not limited to 71 | communication on electronic mailing lists, source code control systems, 72 | and issue tracking systems that are managed by, or on behalf of, the 73 | Licensor for the purpose of discussing and improving the Work, but 74 | excluding communication that is conspicuously marked or otherwise 75 | designated in writing by the copyright owner as "Not a Contribution." 76 | 77 | "Contributor" shall mean Licensor and any individual or Legal Entity 78 | on behalf of whom a Contribution has been received by Licensor and 79 | subsequently incorporated within the Work. 80 | 81 | 2. Grant of Copyright License. Subject to the terms and conditions of 82 | this License, each Contributor hereby grants to You a perpetual, 83 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 84 | copyright license to reproduce, prepare Derivative Works of, 85 | publicly display, publicly perform, sublicense, and distribute the 86 | Work and such Derivative Works in Source or Object form. 87 | 88 | 3. Grant of Patent License. Subject to the terms and conditions of 89 | this License, each Contributor hereby grants to You a perpetual, 90 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 91 | (except as stated in this section) patent license to make, have made, 92 | use, offer to sell, sell, import, and otherwise transfer the Work, 93 | where such license applies only to those patent claims licensable 94 | by such Contributor that are necessarily infringed by their 95 | Contribution(s) alone or by combination of their Contribution(s) 96 | with the Work to which such Contribution(s) was submitted. If You 97 | institute patent litigation against any entity (including a 98 | cross-claim or counterclaim in a lawsuit) alleging that the Work 99 | or a Contribution incorporated within the Work constitutes direct 100 | or contributory patent infringement, then any patent licenses 101 | granted to You under this License for that Work shall terminate 102 | as of the date such litigation is filed. 103 | 104 | 4. Redistribution. You may reproduce and distribute copies of the 105 | Work or Derivative Works thereof in any medium, with or without 106 | modifications, and in Source or Object form, provided that You 107 | meet the following conditions: 108 | 109 | (a) You must give any other recipients of the Work or 110 | Derivative Works a copy of this License; and 111 | 112 | (b) You must cause any modified files to carry prominent notices 113 | stating that You changed the files; and 114 | 115 | (c) You must retain, in the Source form of any Derivative Works 116 | that You distribute, all copyright, patent, trademark, and 117 | attribution notices from the Source form of the Work, 118 | excluding those notices that do not pertain to any part of 119 | the Derivative Works; and 120 | 121 | (d) If the Work includes a "NOTICE" text file as part of its 122 | distribution, then any Derivative Works that You distribute must 123 | include a readable copy of the attribution notices contained 124 | within such NOTICE file, excluding those notices that do not 125 | pertain to any part of the Derivative Works, in at least one 126 | of the following places: within a NOTICE text file distributed 127 | as part of the Derivative Works; within the Source form or 128 | documentation, if provided along with the Derivative Works; or, 129 | within a display generated by the Derivative Works, if and 130 | wherever such third-party notices normally appear. The contents 131 | of the NOTICE file are for informational purposes only and 132 | do not modify the License. You may add Your own attribution 133 | notices within Derivative Works that You distribute, alongside 134 | or as an addendum to the NOTICE text from the Work, provided 135 | that such additional attribution notices cannot be construed 136 | as modifying the License. 137 | 138 | You may add Your own copyright statement to Your modifications and 139 | may provide additional or different license terms and conditions 140 | for use, reproduction, or distribution of Your modifications, or 141 | for any such Derivative Works as a whole, provided Your use, 142 | reproduction, and distribution of the Work otherwise complies with 143 | the conditions stated in this License. 144 | 145 | 5. Submission of Contributions. Unless You explicitly state otherwise, 146 | any Contribution intentionally submitted for inclusion in the Work 147 | by You to the Licensor shall be under the terms and conditions of 148 | this License, without any additional terms or conditions. 149 | Notwithstanding the above, nothing herein shall supersede or modify 150 | the terms of any separate license agreement you may have executed 151 | with Licensor regarding such Contributions. 152 | 153 | 6. Trademarks. This License does not grant permission to use the trade 154 | names, trademarks, service marks, or product names of the Licensor, 155 | except as required for reasonable and customary use in describing the 156 | origin of the Work and reproducing the content of the NOTICE file. 157 | 158 | 7. Disclaimer of Warranty. Unless required by applicable law or 159 | agreed to in writing, Licensor provides the Work (and each 160 | Contributor provides its Contributions) on an "AS IS" BASIS, 161 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 162 | implied, including, without limitation, any warranties or conditions 163 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 164 | PARTICULAR PURPOSE. You are solely responsible for determining the 165 | appropriateness of using or redistributing the Work and assume any 166 | risks associated with Your exercise of permissions under this License. 167 | 168 | 8. Limitation of Liability. In no event and under no legal theory, 169 | whether in tort (including negligence), contract, or otherwise, 170 | unless required by applicable law (such as deliberate and grossly 171 | negligent acts) or agreed to in writing, shall any Contributor be 172 | liable to You for damages, including any direct, indirect, special, 173 | incidental, or consequential damages of any character arising as a 174 | result of this License or out of the use or inability to use the 175 | Work (including but not limited to damages for loss of goodwill, 176 | work stoppage, computer failure or malfunction, or any and all 177 | other commercial damages or losses), even if such Contributor 178 | has been advised of the possibility of such damages. 179 | 180 | 9. Accepting Warranty or Additional Liability. While redistributing 181 | the Work or Derivative Works thereof, You may choose to offer, 182 | and charge a fee for, acceptance of support, warranty, indemnity, 183 | or other liability obligations and/or rights consistent with this 184 | License. However, in accepting such obligations, You may act only 185 | on Your own behalf and on Your sole responsibility, not on behalf 186 | of any other Contributor, and only if You agree to indemnify, 187 | defend, and hold each Contributor harmless for any liability 188 | incurred by, or claims asserted against, such Contributor by reason 189 | of your accepting any such warranty or additional liability. 190 | 191 | END OF TERMS AND CONDITIONS 192 | -------------------------------------------------------------------------------- /mParticle-Button.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 46; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | DB0773DB1DB916610031F3E3 /* mParticle_Button.h in Headers */ = {isa = PBXBuildFile; fileRef = DB0773D91DB916610031F3E3 /* mParticle_Button.h */; settings = {ATTRIBUTES = (Public, ); }; }; 11 | DB0773E31DB916B80031F3E3 /* MPKitButton.h in Headers */ = {isa = PBXBuildFile; fileRef = DB0773E11DB916B80031F3E3 /* MPKitButton.h */; settings = {ATTRIBUTES = (Public, ); }; }; 12 | DB0773E41DB916B80031F3E3 /* MPKitButton.m in Sources */ = {isa = PBXBuildFile; fileRef = DB0773E21DB916B80031F3E3 /* MPKitButton.m */; }; 13 | DE811925214C4CF900AAC951 /* mParticle_Button.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = DB0773D61DB916610031F3E3 /* mParticle_Button.framework */; }; 14 | DE81192F214C4F5500AAC951 /* mParticle-ButtonTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = DE81192D214C4F5400AAC951 /* mParticle-ButtonTests.swift */; }; 15 | DEAA37222180E11800915875 /* MPKitButton+ButtonTests.m in Sources */ = {isa = PBXBuildFile; fileRef = DEAA37212180E11800915875 /* MPKitButton+ButtonTests.m */; }; 16 | /* End PBXBuildFile section */ 17 | 18 | /* Begin PBXContainerItemProxy section */ 19 | DE811926214C4CF900AAC951 /* PBXContainerItemProxy */ = { 20 | isa = PBXContainerItemProxy; 21 | containerPortal = DB0773CD1DB916610031F3E3 /* Project object */; 22 | proxyType = 1; 23 | remoteGlobalIDString = DB0773D51DB916610031F3E3; 24 | remoteInfo = "mParticle-Button"; 25 | }; 26 | /* End PBXContainerItemProxy section */ 27 | 28 | /* Begin PBXFileReference section */ 29 | DB0773D61DB916610031F3E3 /* mParticle_Button.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = mParticle_Button.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 30 | DB0773D91DB916610031F3E3 /* mParticle_Button.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = mParticle_Button.h; sourceTree = ""; }; 31 | DB0773DA1DB916610031F3E3 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 32 | DB0773E11DB916B80031F3E3 /* MPKitButton.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MPKitButton.h; sourceTree = ""; }; 33 | DB0773E21DB916B80031F3E3 /* MPKitButton.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MPKitButton.m; sourceTree = ""; }; 34 | DE0F93D12149694E00E0FF7F /* mParticle-Button.podspec */ = {isa = PBXFileReference; explicitFileType = text.script.ruby; path = "mParticle-Button.podspec"; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.ruby; }; 35 | DE811920214C4CF900AAC951 /* mParticle-ButtonTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = "mParticle-ButtonTests.xctest"; sourceTree = BUILT_PRODUCTS_DIR; }; 36 | DE81192D214C4F5400AAC951 /* mParticle-ButtonTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "mParticle-ButtonTests.swift"; sourceTree = ""; }; 37 | DE81192E214C4F5400AAC951 /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 38 | DEAA371F2180E11700915875 /* mParticle-ButtonTests-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "mParticle-ButtonTests-Bridging-Header.h"; sourceTree = ""; }; 39 | DEAA37202180E11800915875 /* MPKitButton+ButtonTests.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "MPKitButton+ButtonTests.h"; sourceTree = ""; }; 40 | DEAA37212180E11800915875 /* MPKitButton+ButtonTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = "MPKitButton+ButtonTests.m"; sourceTree = ""; }; 41 | DEEEE6A3214C57BF006B5C06 /* ButtonMerchant.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = ButtonMerchant.framework; path = Carthage/Build/iOS/ButtonMerchant.framework; sourceTree = ""; }; 42 | DEEEE6A4214C57CA006B5C06 /* mParticle_Apple_SDK.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = mParticle_Apple_SDK.framework; path = Carthage/Build/iOS/mParticle_Apple_SDK.framework; sourceTree = ""; }; 43 | /* End PBXFileReference section */ 44 | 45 | /* Begin PBXFrameworksBuildPhase section */ 46 | DB0773D21DB916610031F3E3 /* Frameworks */ = { 47 | isa = PBXFrameworksBuildPhase; 48 | buildActionMask = 2147483647; 49 | files = ( 50 | ); 51 | runOnlyForDeploymentPostprocessing = 0; 52 | }; 53 | DE81191D214C4CF900AAC951 /* Frameworks */ = { 54 | isa = PBXFrameworksBuildPhase; 55 | buildActionMask = 2147483647; 56 | files = ( 57 | DE811925214C4CF900AAC951 /* mParticle_Button.framework in Frameworks */, 58 | ); 59 | runOnlyForDeploymentPostprocessing = 0; 60 | }; 61 | /* End PBXFrameworksBuildPhase section */ 62 | 63 | /* Begin PBXGroup section */ 64 | 9E95DB5F21484465006F257C /* Frameworks */ = { 65 | isa = PBXGroup; 66 | children = ( 67 | DEEEE6A4214C57CA006B5C06 /* mParticle_Apple_SDK.framework */, 68 | DEEEE6A3214C57BF006B5C06 /* ButtonMerchant.framework */, 69 | ); 70 | name = Frameworks; 71 | sourceTree = ""; 72 | }; 73 | DB0773CC1DB916610031F3E3 = { 74 | isa = PBXGroup; 75 | children = ( 76 | DE0F93D12149694E00E0FF7F /* mParticle-Button.podspec */, 77 | DB0773D81DB916610031F3E3 /* mParticle-Button */, 78 | DE81192C214C4F5400AAC951 /* mParticle-ButtonTests */, 79 | DB0773D71DB916610031F3E3 /* Products */, 80 | 9E95DB5F21484465006F257C /* Frameworks */, 81 | ); 82 | sourceTree = ""; 83 | }; 84 | DB0773D71DB916610031F3E3 /* Products */ = { 85 | isa = PBXGroup; 86 | children = ( 87 | DB0773D61DB916610031F3E3 /* mParticle_Button.framework */, 88 | DE811920214C4CF900AAC951 /* mParticle-ButtonTests.xctest */, 89 | ); 90 | name = Products; 91 | sourceTree = ""; 92 | }; 93 | DB0773D81DB916610031F3E3 /* mParticle-Button */ = { 94 | isa = PBXGroup; 95 | children = ( 96 | DB0773E11DB916B80031F3E3 /* MPKitButton.h */, 97 | DB0773E21DB916B80031F3E3 /* MPKitButton.m */, 98 | DB0773D91DB916610031F3E3 /* mParticle_Button.h */, 99 | DB0773DA1DB916610031F3E3 /* Info.plist */, 100 | ); 101 | path = "mParticle-Button"; 102 | sourceTree = ""; 103 | }; 104 | DE81192C214C4F5400AAC951 /* mParticle-ButtonTests */ = { 105 | isa = PBXGroup; 106 | children = ( 107 | DEAA37232180E11F00915875 /* Helpers */, 108 | DE81192D214C4F5400AAC951 /* mParticle-ButtonTests.swift */, 109 | DE81192E214C4F5400AAC951 /* Info.plist */, 110 | ); 111 | path = "mParticle-ButtonTests"; 112 | sourceTree = ""; 113 | }; 114 | DEAA37232180E11F00915875 /* Helpers */ = { 115 | isa = PBXGroup; 116 | children = ( 117 | DEAA371F2180E11700915875 /* mParticle-ButtonTests-Bridging-Header.h */, 118 | DEAA37202180E11800915875 /* MPKitButton+ButtonTests.h */, 119 | DEAA37212180E11800915875 /* MPKitButton+ButtonTests.m */, 120 | ); 121 | path = Helpers; 122 | sourceTree = ""; 123 | }; 124 | /* End PBXGroup section */ 125 | 126 | /* Begin PBXHeadersBuildPhase section */ 127 | DB0773D31DB916610031F3E3 /* Headers */ = { 128 | isa = PBXHeadersBuildPhase; 129 | buildActionMask = 2147483647; 130 | files = ( 131 | DB0773E31DB916B80031F3E3 /* MPKitButton.h in Headers */, 132 | DB0773DB1DB916610031F3E3 /* mParticle_Button.h in Headers */, 133 | ); 134 | runOnlyForDeploymentPostprocessing = 0; 135 | }; 136 | /* End PBXHeadersBuildPhase section */ 137 | 138 | /* Begin PBXNativeTarget section */ 139 | DB0773D51DB916610031F3E3 /* mParticle-Button */ = { 140 | isa = PBXNativeTarget; 141 | buildConfigurationList = DB0773DE1DB916610031F3E3 /* Build configuration list for PBXNativeTarget "mParticle-Button" */; 142 | buildPhases = ( 143 | DB0773D11DB916610031F3E3 /* Sources */, 144 | DB0773D21DB916610031F3E3 /* Frameworks */, 145 | DB0773D31DB916610031F3E3 /* Headers */, 146 | DE0F93A621486B3900E0FF7F /* Carthage */, 147 | DB0773D41DB916610031F3E3 /* Resources */, 148 | ); 149 | buildRules = ( 150 | ); 151 | dependencies = ( 152 | ); 153 | name = "mParticle-Button"; 154 | productName = "mParticle-Button"; 155 | productReference = DB0773D61DB916610031F3E3 /* mParticle_Button.framework */; 156 | productType = "com.apple.product-type.framework"; 157 | }; 158 | DE81191F214C4CF900AAC951 /* mParticle-ButtonTests */ = { 159 | isa = PBXNativeTarget; 160 | buildConfigurationList = DE811928214C4CF900AAC951 /* Build configuration list for PBXNativeTarget "mParticle-ButtonTests" */; 161 | buildPhases = ( 162 | DE81191C214C4CF900AAC951 /* Sources */, 163 | DE81191D214C4CF900AAC951 /* Frameworks */, 164 | DE81191E214C4CF900AAC951 /* Resources */, 165 | DE81192B214C4E9F00AAC951 /* Carthage */, 166 | ); 167 | buildRules = ( 168 | ); 169 | dependencies = ( 170 | DE811927214C4CF900AAC951 /* PBXTargetDependency */, 171 | ); 172 | name = "mParticle-ButtonTests"; 173 | productName = "mParticle-ButtonTests"; 174 | productReference = DE811920214C4CF900AAC951 /* mParticle-ButtonTests.xctest */; 175 | productType = "com.apple.product-type.bundle.unit-test"; 176 | }; 177 | /* End PBXNativeTarget section */ 178 | 179 | /* Begin PBXProject section */ 180 | DB0773CD1DB916610031F3E3 /* Project object */ = { 181 | isa = PBXProject; 182 | attributes = { 183 | LastSwiftUpdateCheck = 0940; 184 | LastUpgradeCheck = 1010; 185 | ORGANIZATIONNAME = mParticle; 186 | TargetAttributes = { 187 | DB0773D51DB916610031F3E3 = { 188 | CreatedOnToolsVersion = 8.0; 189 | DevelopmentTeam = 39F27QYP2C; 190 | LastSwiftMigration = 0940; 191 | ProvisioningStyle = Automatic; 192 | }; 193 | DE81191F214C4CF900AAC951 = { 194 | CreatedOnToolsVersion = 9.4.1; 195 | DevelopmentTeam = 39F27QYP2C; 196 | LastSwiftMigration = 0940; 197 | ProvisioningStyle = Automatic; 198 | }; 199 | }; 200 | }; 201 | buildConfigurationList = DB0773D01DB916610031F3E3 /* Build configuration list for PBXProject "mParticle-Button" */; 202 | compatibilityVersion = "Xcode 3.2"; 203 | developmentRegion = English; 204 | hasScannedForEncodings = 0; 205 | knownRegions = ( 206 | en, 207 | ); 208 | mainGroup = DB0773CC1DB916610031F3E3; 209 | productRefGroup = DB0773D71DB916610031F3E3 /* Products */; 210 | projectDirPath = ""; 211 | projectRoot = ""; 212 | targets = ( 213 | DB0773D51DB916610031F3E3 /* mParticle-Button */, 214 | DE81191F214C4CF900AAC951 /* mParticle-ButtonTests */, 215 | ); 216 | }; 217 | /* End PBXProject section */ 218 | 219 | /* Begin PBXResourcesBuildPhase section */ 220 | DB0773D41DB916610031F3E3 /* Resources */ = { 221 | isa = PBXResourcesBuildPhase; 222 | buildActionMask = 2147483647; 223 | files = ( 224 | ); 225 | runOnlyForDeploymentPostprocessing = 0; 226 | }; 227 | DE81191E214C4CF900AAC951 /* Resources */ = { 228 | isa = PBXResourcesBuildPhase; 229 | buildActionMask = 2147483647; 230 | files = ( 231 | ); 232 | runOnlyForDeploymentPostprocessing = 0; 233 | }; 234 | /* End PBXResourcesBuildPhase section */ 235 | 236 | /* Begin PBXShellScriptBuildPhase section */ 237 | DE0F93A621486B3900E0FF7F /* Carthage */ = { 238 | isa = PBXShellScriptBuildPhase; 239 | buildActionMask = 2147483647; 240 | files = ( 241 | ); 242 | inputPaths = ( 243 | "$(SRCROOT)/Carthage/Build/iOS/ButtonMerchant.framework", 244 | "$(SRCROOT)/Carthage/Build/iOS/mParticle_Apple_SDK.framework", 245 | ); 246 | name = Carthage; 247 | outputPaths = ( 248 | ); 249 | runOnlyForDeploymentPostprocessing = 0; 250 | shellPath = /bin/sh; 251 | shellScript = "#/usr/local/bin/carthage copy-frameworks"; 252 | }; 253 | DE81192B214C4E9F00AAC951 /* Carthage */ = { 254 | isa = PBXShellScriptBuildPhase; 255 | buildActionMask = 2147483647; 256 | files = ( 257 | ); 258 | inputPaths = ( 259 | "$(SRCROOT)/Carthage/Build/iOS/ButtonMerchant.framework", 260 | "$(SRCROOT)/Carthage/Build/iOS/mParticle_Apple_SDK.framework", 261 | ); 262 | name = Carthage; 263 | outputPaths = ( 264 | ); 265 | runOnlyForDeploymentPostprocessing = 0; 266 | shellPath = /bin/sh; 267 | shellScript = "/usr/local/bin/carthage copy-frameworks"; 268 | }; 269 | /* End PBXShellScriptBuildPhase section */ 270 | 271 | /* Begin PBXSourcesBuildPhase section */ 272 | DB0773D11DB916610031F3E3 /* Sources */ = { 273 | isa = PBXSourcesBuildPhase; 274 | buildActionMask = 2147483647; 275 | files = ( 276 | DB0773E41DB916B80031F3E3 /* MPKitButton.m in Sources */, 277 | ); 278 | runOnlyForDeploymentPostprocessing = 0; 279 | }; 280 | DE81191C214C4CF900AAC951 /* Sources */ = { 281 | isa = PBXSourcesBuildPhase; 282 | buildActionMask = 2147483647; 283 | files = ( 284 | DE81192F214C4F5500AAC951 /* mParticle-ButtonTests.swift in Sources */, 285 | DEAA37222180E11800915875 /* MPKitButton+ButtonTests.m in Sources */, 286 | ); 287 | runOnlyForDeploymentPostprocessing = 0; 288 | }; 289 | /* End PBXSourcesBuildPhase section */ 290 | 291 | /* Begin PBXTargetDependency section */ 292 | DE811927214C4CF900AAC951 /* PBXTargetDependency */ = { 293 | isa = PBXTargetDependency; 294 | target = DB0773D51DB916610031F3E3 /* mParticle-Button */; 295 | targetProxy = DE811926214C4CF900AAC951 /* PBXContainerItemProxy */; 296 | }; 297 | /* End PBXTargetDependency section */ 298 | 299 | /* Begin XCBuildConfiguration section */ 300 | DB0773DC1DB916610031F3E3 /* Debug */ = { 301 | isa = XCBuildConfiguration; 302 | buildSettings = { 303 | ALWAYS_SEARCH_USER_PATHS = NO; 304 | CLANG_ANALYZER_NONNULL = YES; 305 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 306 | CLANG_CXX_LIBRARY = "libc++"; 307 | CLANG_ENABLE_MODULES = YES; 308 | CLANG_ENABLE_OBJC_ARC = YES; 309 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 310 | CLANG_WARN_BOOL_CONVERSION = YES; 311 | CLANG_WARN_COMMA = YES; 312 | CLANG_WARN_CONSTANT_CONVERSION = YES; 313 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 314 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 315 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 316 | CLANG_WARN_EMPTY_BODY = YES; 317 | CLANG_WARN_ENUM_CONVERSION = YES; 318 | CLANG_WARN_INFINITE_RECURSION = YES; 319 | CLANG_WARN_INT_CONVERSION = YES; 320 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 321 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; 322 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 323 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 324 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 325 | CLANG_WARN_STRICT_PROTOTYPES = YES; 326 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 327 | CLANG_WARN_SUSPICIOUS_MOVES = YES; 328 | CLANG_WARN_UNREACHABLE_CODE = YES; 329 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 330 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 331 | COPY_PHASE_STRIP = NO; 332 | CURRENT_PROJECT_VERSION = 1; 333 | DEBUG_INFORMATION_FORMAT = dwarf; 334 | ENABLE_STRICT_OBJC_MSGSEND = YES; 335 | ENABLE_TESTABILITY = YES; 336 | GCC_C_LANGUAGE_STANDARD = gnu99; 337 | GCC_DYNAMIC_NO_PIC = NO; 338 | GCC_NO_COMMON_BLOCKS = YES; 339 | GCC_OPTIMIZATION_LEVEL = 0; 340 | GCC_PREPROCESSOR_DEFINITIONS = ( 341 | "DEBUG=1", 342 | "$(inherited)", 343 | ); 344 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 345 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 346 | GCC_WARN_UNDECLARED_SELECTOR = YES; 347 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 348 | GCC_WARN_UNUSED_FUNCTION = YES; 349 | GCC_WARN_UNUSED_VARIABLE = YES; 350 | IPHONEOS_DEPLOYMENT_TARGET = 10.0; 351 | MTL_ENABLE_DEBUG_INFO = YES; 352 | ONLY_ACTIVE_ARCH = YES; 353 | SDKROOT = iphoneos; 354 | TARGETED_DEVICE_FAMILY = "1,2"; 355 | VERSIONING_SYSTEM = "apple-generic"; 356 | VERSION_INFO_PREFIX = ""; 357 | }; 358 | name = Debug; 359 | }; 360 | DB0773DD1DB916610031F3E3 /* Release */ = { 361 | isa = XCBuildConfiguration; 362 | buildSettings = { 363 | ALWAYS_SEARCH_USER_PATHS = NO; 364 | CLANG_ANALYZER_NONNULL = YES; 365 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 366 | CLANG_CXX_LIBRARY = "libc++"; 367 | CLANG_ENABLE_MODULES = YES; 368 | CLANG_ENABLE_OBJC_ARC = YES; 369 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 370 | CLANG_WARN_BOOL_CONVERSION = YES; 371 | CLANG_WARN_COMMA = YES; 372 | CLANG_WARN_CONSTANT_CONVERSION = YES; 373 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 374 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 375 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 376 | CLANG_WARN_EMPTY_BODY = YES; 377 | CLANG_WARN_ENUM_CONVERSION = YES; 378 | CLANG_WARN_INFINITE_RECURSION = YES; 379 | CLANG_WARN_INT_CONVERSION = YES; 380 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 381 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; 382 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 383 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 384 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 385 | CLANG_WARN_STRICT_PROTOTYPES = YES; 386 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 387 | CLANG_WARN_SUSPICIOUS_MOVES = YES; 388 | CLANG_WARN_UNREACHABLE_CODE = YES; 389 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 390 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 391 | COPY_PHASE_STRIP = NO; 392 | CURRENT_PROJECT_VERSION = 1; 393 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 394 | ENABLE_NS_ASSERTIONS = NO; 395 | ENABLE_STRICT_OBJC_MSGSEND = YES; 396 | GCC_C_LANGUAGE_STANDARD = gnu99; 397 | GCC_NO_COMMON_BLOCKS = YES; 398 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 399 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 400 | GCC_WARN_UNDECLARED_SELECTOR = YES; 401 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 402 | GCC_WARN_UNUSED_FUNCTION = YES; 403 | GCC_WARN_UNUSED_VARIABLE = YES; 404 | IPHONEOS_DEPLOYMENT_TARGET = 10.0; 405 | MTL_ENABLE_DEBUG_INFO = NO; 406 | SDKROOT = iphoneos; 407 | TARGETED_DEVICE_FAMILY = "1,2"; 408 | VALIDATE_PRODUCT = YES; 409 | VERSIONING_SYSTEM = "apple-generic"; 410 | VERSION_INFO_PREFIX = ""; 411 | }; 412 | name = Release; 413 | }; 414 | DB0773DF1DB916610031F3E3 /* Debug */ = { 415 | isa = XCBuildConfiguration; 416 | buildSettings = { 417 | CLANG_ENABLE_MODULES = YES; 418 | CODE_SIGN_IDENTITY = "iPhone Developer"; 419 | CODE_SIGN_STYLE = Automatic; 420 | DEFINES_MODULE = YES; 421 | DEVELOPMENT_TEAM = 39F27QYP2C; 422 | DYLIB_COMPATIBILITY_VERSION = 1; 423 | DYLIB_CURRENT_VERSION = 1; 424 | DYLIB_INSTALL_NAME_BASE = "@rpath"; 425 | FRAMEWORK_SEARCH_PATHS = ( 426 | "$(inherited)", 427 | "$(PROJECT_DIR)/Carthage/Build/iOS", 428 | ); 429 | INFOPLIST_FILE = "mParticle-Button/Info.plist"; 430 | INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; 431 | IPHONEOS_DEPLOYMENT_TARGET = 9.0; 432 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; 433 | PRODUCT_BUNDLE_IDENTIFIER = "com.mparticle.mParticle-Button"; 434 | PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)"; 435 | PROVISIONING_PROFILE_SPECIFIER = ""; 436 | SKIP_INSTALL = YES; 437 | SWIFT_OPTIMIZATION_LEVEL = "-Onone"; 438 | SWIFT_VERSION = 3.0; 439 | }; 440 | name = Debug; 441 | }; 442 | DB0773E01DB916610031F3E3 /* Release */ = { 443 | isa = XCBuildConfiguration; 444 | buildSettings = { 445 | CLANG_ENABLE_MODULES = YES; 446 | CODE_SIGN_IDENTITY = "iPhone Developer"; 447 | CODE_SIGN_STYLE = Automatic; 448 | DEFINES_MODULE = YES; 449 | DEVELOPMENT_TEAM = 39F27QYP2C; 450 | DYLIB_COMPATIBILITY_VERSION = 1; 451 | DYLIB_CURRENT_VERSION = 1; 452 | DYLIB_INSTALL_NAME_BASE = "@rpath"; 453 | FRAMEWORK_SEARCH_PATHS = ( 454 | "$(inherited)", 455 | "$(PROJECT_DIR)/Carthage/Build/iOS", 456 | ); 457 | INFOPLIST_FILE = "mParticle-Button/Info.plist"; 458 | INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; 459 | IPHONEOS_DEPLOYMENT_TARGET = 9.0; 460 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; 461 | PRODUCT_BUNDLE_IDENTIFIER = "com.mparticle.mParticle-Button"; 462 | PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)"; 463 | PROVISIONING_PROFILE_SPECIFIER = ""; 464 | SKIP_INSTALL = YES; 465 | SWIFT_VERSION = 3.0; 466 | }; 467 | name = Release; 468 | }; 469 | DE811929214C4CF900AAC951 /* Debug */ = { 470 | isa = XCBuildConfiguration; 471 | buildSettings = { 472 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; 473 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; 474 | CLANG_ENABLE_MODULES = YES; 475 | CLANG_ENABLE_OBJC_WEAK = YES; 476 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; 477 | CODE_SIGN_IDENTITY = "iPhone Developer"; 478 | CODE_SIGN_STYLE = Automatic; 479 | DEVELOPMENT_TEAM = 39F27QYP2C; 480 | FRAMEWORK_SEARCH_PATHS = ( 481 | "$(SRCROOT)/Carthage/Build/iOS/**", 482 | "$(PROJECT_DIR)/Carthage/Build/iOS", 483 | ); 484 | GCC_C_LANGUAGE_STANDARD = gnu11; 485 | INFOPLIST_FILE = "mParticle-ButtonTests/Info.plist"; 486 | IPHONEOS_DEPLOYMENT_TARGET = 9.0; 487 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; 488 | PRODUCT_BUNDLE_IDENTIFIER = "com.usebutton.mParticle-ButtonTests"; 489 | PRODUCT_NAME = "$(TARGET_NAME)"; 490 | PROVISIONING_PROFILE_SPECIFIER = ""; 491 | SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; 492 | SWIFT_OBJC_BRIDGING_HEADER = "mParticle-ButtonTests/Helpers/mParticle-ButtonTests-Bridging-Header.h"; 493 | SWIFT_OPTIMIZATION_LEVEL = "-Onone"; 494 | SWIFT_VERSION = 4.0; 495 | TARGETED_DEVICE_FAMILY = "1,2"; 496 | }; 497 | name = Debug; 498 | }; 499 | DE81192A214C4CF900AAC951 /* Release */ = { 500 | isa = XCBuildConfiguration; 501 | buildSettings = { 502 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; 503 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; 504 | CLANG_ENABLE_MODULES = YES; 505 | CLANG_ENABLE_OBJC_WEAK = YES; 506 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; 507 | CODE_SIGN_IDENTITY = "iPhone Developer"; 508 | CODE_SIGN_STYLE = Automatic; 509 | DEVELOPMENT_TEAM = 39F27QYP2C; 510 | FRAMEWORK_SEARCH_PATHS = ( 511 | "$(SRCROOT)/Carthage/Build/iOS/**", 512 | "$(PROJECT_DIR)/Carthage/Build/iOS", 513 | ); 514 | GCC_C_LANGUAGE_STANDARD = gnu11; 515 | INFOPLIST_FILE = "mParticle-ButtonTests/Info.plist"; 516 | IPHONEOS_DEPLOYMENT_TARGET = 9.0; 517 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; 518 | PRODUCT_BUNDLE_IDENTIFIER = "com.usebutton.mParticle-ButtonTests"; 519 | PRODUCT_NAME = "$(TARGET_NAME)"; 520 | PROVISIONING_PROFILE_SPECIFIER = ""; 521 | SWIFT_OBJC_BRIDGING_HEADER = "mParticle-ButtonTests/Helpers/mParticle-ButtonTests-Bridging-Header.h"; 522 | SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule"; 523 | SWIFT_VERSION = 4.0; 524 | TARGETED_DEVICE_FAMILY = "1,2"; 525 | }; 526 | name = Release; 527 | }; 528 | /* End XCBuildConfiguration section */ 529 | 530 | /* Begin XCConfigurationList section */ 531 | DB0773D01DB916610031F3E3 /* Build configuration list for PBXProject "mParticle-Button" */ = { 532 | isa = XCConfigurationList; 533 | buildConfigurations = ( 534 | DB0773DC1DB916610031F3E3 /* Debug */, 535 | DB0773DD1DB916610031F3E3 /* Release */, 536 | ); 537 | defaultConfigurationIsVisible = 0; 538 | defaultConfigurationName = Release; 539 | }; 540 | DB0773DE1DB916610031F3E3 /* Build configuration list for PBXNativeTarget "mParticle-Button" */ = { 541 | isa = XCConfigurationList; 542 | buildConfigurations = ( 543 | DB0773DF1DB916610031F3E3 /* Debug */, 544 | DB0773E01DB916610031F3E3 /* Release */, 545 | ); 546 | defaultConfigurationIsVisible = 0; 547 | defaultConfigurationName = Release; 548 | }; 549 | DE811928214C4CF900AAC951 /* Build configuration list for PBXNativeTarget "mParticle-ButtonTests" */ = { 550 | isa = XCConfigurationList; 551 | buildConfigurations = ( 552 | DE811929214C4CF900AAC951 /* Debug */, 553 | DE81192A214C4CF900AAC951 /* Release */, 554 | ); 555 | defaultConfigurationIsVisible = 0; 556 | defaultConfigurationName = Release; 557 | }; 558 | /* End XCConfigurationList section */ 559 | }; 560 | rootObject = DB0773CD1DB916610031F3E3 /* Project object */; 561 | } 562 | --------------------------------------------------------------------------------