├── .gitignore ├── Cartfile ├── Dlopen.xcodeproj └── project.pbxproj ├── README.md ├── carthage.sh ├── sources └── main │ ├── AppDelegate.swift │ ├── Assets.xcassets │ └── AppIcon.appiconset │ │ └── Contents.json │ ├── CircleView.swift │ ├── View.swift │ └── ViewController.swift ├── targets └── main │ └── Info.plist └── thumbnail.png /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | Cartfile.resolved 3 | Carthage 4 | project.xcworkspace/ 5 | xcuserdata/ 6 | -------------------------------------------------------------------------------- /Cartfile: -------------------------------------------------------------------------------- 1 | github "BoltsFramework/Bolts-Swift" "1.3.0" 2 | github "braintree/braintree_ios" # add braintree, apple-pay, paymentflow 3 | github "facebook/Facebook-SDK-Swift" # add core 0.2.0, login 0.2.0 - fails if you build twice. wtf. 4 | github "Hearst-DD/ObjectMapper" "3.1.0" 5 | github "matthewpalmer/Locksmith" "4.0.0" 6 | github "misterwell/MMMaterialDesignSpinner" "0.2.3" 7 | github "ninjaprox/NVActivityIndicatorView" "v3.2" 8 | github "realm/realm-cocoa" "v2.10.0" 9 | github "stripe/stripe-ios" "v8.0.4" 10 | github "SVProgressHUD/SVProgressHUD" 11 | github "urbanairship/ios-library" "8.6.3" # AirshipKit 12 | github "Yalantis/Koloda" "4.3.1" 13 | -------------------------------------------------------------------------------- /Dlopen.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 48; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | 3A9533FA206A4358002FBA50 /* CircleView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3A9533F9206A4358002FBA50 /* CircleView.swift */; }; 11 | 3A9533FC206A4E6C002FBA50 /* View.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3A9533FB206A4E6C002FBA50 /* View.swift */; }; 12 | 3A98CC272069A40200C881E2 /* AirshipAppExtensions.framework in CopyFiles */ = {isa = PBXBuildFile; fileRef = 3A98CBBE206998C000C881E2 /* AirshipAppExtensions.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; 13 | 3A98CC282069A40200C881E2 /* AirshipKit.framework in CopyFiles */ = {isa = PBXBuildFile; fileRef = 3A98CBD3206998C200C881E2 /* AirshipKit.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; 14 | 3A98CC292069A40200C881E2 /* Bolts.framework in CopyFiles */ = {isa = PBXBuildFile; fileRef = 3A98CBCE206998C100C881E2 /* Bolts.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; 15 | 3A98CC2A2069A40200C881E2 /* BoltsSwift.framework in CopyFiles */ = {isa = PBXBuildFile; fileRef = 3A98CBC3206998C000C881E2 /* BoltsSwift.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; 16 | 3A98CC2B2069A40200C881E2 /* Braintree3DSecure.framework in CopyFiles */ = {isa = PBXBuildFile; fileRef = 3A98CBC0206998C000C881E2 /* Braintree3DSecure.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; 17 | 3A98CC2C2069A40200C881E2 /* BraintreeAmericanExpress.framework in CopyFiles */ = {isa = PBXBuildFile; fileRef = 3A98CBBF206998C000C881E2 /* BraintreeAmericanExpress.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; 18 | 3A98CC2D2069A40200C881E2 /* BraintreeApplePay.framework in CopyFiles */ = {isa = PBXBuildFile; fileRef = 3A98CBD0206998C200C881E2 /* BraintreeApplePay.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; 19 | 3A98CC2E2069A40200C881E2 /* BraintreeCard.framework in CopyFiles */ = {isa = PBXBuildFile; fileRef = 3A98CBC9206998C100C881E2 /* BraintreeCard.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; 20 | 3A98CC2F2069A40200C881E2 /* BraintreeCore.framework in CopyFiles */ = {isa = PBXBuildFile; fileRef = 3A98CBDD206998C300C881E2 /* BraintreeCore.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; 21 | 3A98CC302069A40200C881E2 /* BraintreeDataCollector.framework in CopyFiles */ = {isa = PBXBuildFile; fileRef = 3A98CBC7206998C100C881E2 /* BraintreeDataCollector.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; 22 | 3A98CC312069A40200C881E2 /* BraintreePaymentFlow.framework in CopyFiles */ = {isa = PBXBuildFile; fileRef = 3A98CBCD206998C100C881E2 /* BraintreePaymentFlow.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; 23 | 3A98CC322069A40200C881E2 /* BraintreePayPal.framework in CopyFiles */ = {isa = PBXBuildFile; fileRef = 3A98CBD1206998C200C881E2 /* BraintreePayPal.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; 24 | 3A98CC332069A40200C881E2 /* BraintreeUI.framework in CopyFiles */ = {isa = PBXBuildFile; fileRef = 3A98CBC1206998C000C881E2 /* BraintreeUI.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; 25 | 3A98CC342069A40200C881E2 /* BraintreeUnionPay.framework in CopyFiles */ = {isa = PBXBuildFile; fileRef = 3A98CBC2206998C000C881E2 /* BraintreeUnionPay.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; 26 | 3A98CC352069A40200C881E2 /* BraintreeVenmo.framework in CopyFiles */ = {isa = PBXBuildFile; fileRef = 3A98CBC6206998C100C881E2 /* BraintreeVenmo.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; 27 | 3A98CC362069A40200C881E2 /* FacebookCore.framework in CopyFiles */ = {isa = PBXBuildFile; fileRef = 3A98CBD7206998C200C881E2 /* FacebookCore.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; 28 | 3A98CC372069A40200C881E2 /* FacebookLogin.framework in CopyFiles */ = {isa = PBXBuildFile; fileRef = 3A98CBC4206998C100C881E2 /* FacebookLogin.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; 29 | 3A98CC382069A40200C881E2 /* FacebookShare.framework in CopyFiles */ = {isa = PBXBuildFile; fileRef = 3A98CBBD206998C000C881E2 /* FacebookShare.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; 30 | 3A98CC392069A40200C881E2 /* FBSDKCoreKit.framework in CopyFiles */ = {isa = PBXBuildFile; fileRef = 3A98CBDE206998C300C881E2 /* FBSDKCoreKit.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; 31 | 3A98CC3A2069A40200C881E2 /* FBSDKLoginKit.framework in CopyFiles */ = {isa = PBXBuildFile; fileRef = 3A98CBD2206998C200C881E2 /* FBSDKLoginKit.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; 32 | 3A98CC3B2069A40200C881E2 /* FBSDKPlacesKit.framework in CopyFiles */ = {isa = PBXBuildFile; fileRef = 3A98CBCB206998C100C881E2 /* FBSDKPlacesKit.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; 33 | 3A98CC3C2069A40200C881E2 /* FBSDKShareKit.framework in CopyFiles */ = {isa = PBXBuildFile; fileRef = 3A98CBCA206998C100C881E2 /* FBSDKShareKit.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; 34 | 3A98CC3D2069A40200C881E2 /* Koloda.framework in CopyFiles */ = {isa = PBXBuildFile; fileRef = 3A98CBC5206998C100C881E2 /* Koloda.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; 35 | 3A98CC3E2069A40200C881E2 /* Locksmith.framework in CopyFiles */ = {isa = PBXBuildFile; fileRef = 3A98CBDA206998C300C881E2 /* Locksmith.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; 36 | 3A98CC3F2069A40200C881E2 /* MMMaterialDesignSpinner.framework in CopyFiles */ = {isa = PBXBuildFile; fileRef = 3A98CBC8206998C100C881E2 /* MMMaterialDesignSpinner.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; 37 | 3A98CC402069A40200C881E2 /* NVActivityIndicatorView.framework in CopyFiles */ = {isa = PBXBuildFile; fileRef = 3A98CBD5206998C200C881E2 /* NVActivityIndicatorView.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; 38 | 3A98CC412069A40200C881E2 /* ObjectMapper.framework in CopyFiles */ = {isa = PBXBuildFile; fileRef = 3A98CBD6206998C200C881E2 /* ObjectMapper.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; 39 | 3A98CC422069A40200C881E2 /* PayPalDataCollector.framework in CopyFiles */ = {isa = PBXBuildFile; fileRef = 3A98CBCF206998C100C881E2 /* PayPalDataCollector.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; 40 | 3A98CC432069A40200C881E2 /* PayPalOneTouch.framework in CopyFiles */ = {isa = PBXBuildFile; fileRef = 3A98CBDF206998C300C881E2 /* PayPalOneTouch.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; 41 | 3A98CC442069A40200C881E2 /* PayPalUtils.framework in CopyFiles */ = {isa = PBXBuildFile; fileRef = 3A98CBCC206998C100C881E2 /* PayPalUtils.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; 42 | 3A98CC452069A40200C881E2 /* pop.framework in CopyFiles */ = {isa = PBXBuildFile; fileRef = 3A98CBDC206998C300C881E2 /* pop.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; 43 | 3A98CC462069A40200C881E2 /* Realm.framework in CopyFiles */ = {isa = PBXBuildFile; fileRef = 3A98CBD8206998C200C881E2 /* Realm.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; 44 | 3A98CC472069A40200C881E2 /* RealmSwift.framework in CopyFiles */ = {isa = PBXBuildFile; fileRef = 3A98CBD9206998C300C881E2 /* RealmSwift.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; 45 | 3A98CC482069A40200C881E2 /* Stripe.framework in CopyFiles */ = {isa = PBXBuildFile; fileRef = 3A98CBDB206998C300C881E2 /* Stripe.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; 46 | 3A98CC492069A40200C881E2 /* SVProgressHUD.framework in CopyFiles */ = {isa = PBXBuildFile; fileRef = 3A98CBD4206998C200C881E2 /* SVProgressHUD.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; 47 | 3AEEEB0320697EC700B91A2D /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3AEEEB0220697EC700B91A2D /* AppDelegate.swift */; }; 48 | 3AEEEB0520697EC700B91A2D /* ViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3AEEEB0420697EC700B91A2D /* ViewController.swift */; }; 49 | 3AEEEB0A20697EC700B91A2D /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 3AEEEB0920697EC700B91A2D /* Assets.xcassets */; }; 50 | /* End PBXBuildFile section */ 51 | 52 | /* Begin PBXCopyFilesBuildPhase section */ 53 | 3A98CC262069A3F900C881E2 /* CopyFiles */ = { 54 | isa = PBXCopyFilesBuildPhase; 55 | buildActionMask = 2147483647; 56 | dstPath = ""; 57 | dstSubfolderSpec = 10; 58 | files = ( 59 | 3A98CC272069A40200C881E2 /* AirshipAppExtensions.framework in CopyFiles */, 60 | 3A98CC282069A40200C881E2 /* AirshipKit.framework in CopyFiles */, 61 | 3A98CC292069A40200C881E2 /* Bolts.framework in CopyFiles */, 62 | 3A98CC2A2069A40200C881E2 /* BoltsSwift.framework in CopyFiles */, 63 | 3A98CC2B2069A40200C881E2 /* Braintree3DSecure.framework in CopyFiles */, 64 | 3A98CC2C2069A40200C881E2 /* BraintreeAmericanExpress.framework in CopyFiles */, 65 | 3A98CC2D2069A40200C881E2 /* BraintreeApplePay.framework in CopyFiles */, 66 | 3A98CC2E2069A40200C881E2 /* BraintreeCard.framework in CopyFiles */, 67 | 3A98CC2F2069A40200C881E2 /* BraintreeCore.framework in CopyFiles */, 68 | 3A98CC302069A40200C881E2 /* BraintreeDataCollector.framework in CopyFiles */, 69 | 3A98CC312069A40200C881E2 /* BraintreePaymentFlow.framework in CopyFiles */, 70 | 3A98CC322069A40200C881E2 /* BraintreePayPal.framework in CopyFiles */, 71 | 3A98CC332069A40200C881E2 /* BraintreeUI.framework in CopyFiles */, 72 | 3A98CC342069A40200C881E2 /* BraintreeUnionPay.framework in CopyFiles */, 73 | 3A98CC352069A40200C881E2 /* BraintreeVenmo.framework in CopyFiles */, 74 | 3A98CC362069A40200C881E2 /* FacebookCore.framework in CopyFiles */, 75 | 3A98CC372069A40200C881E2 /* FacebookLogin.framework in CopyFiles */, 76 | 3A98CC382069A40200C881E2 /* FacebookShare.framework in CopyFiles */, 77 | 3A98CC392069A40200C881E2 /* FBSDKCoreKit.framework in CopyFiles */, 78 | 3A98CC3A2069A40200C881E2 /* FBSDKLoginKit.framework in CopyFiles */, 79 | 3A98CC3B2069A40200C881E2 /* FBSDKPlacesKit.framework in CopyFiles */, 80 | 3A98CC3C2069A40200C881E2 /* FBSDKShareKit.framework in CopyFiles */, 81 | 3A98CC3D2069A40200C881E2 /* Koloda.framework in CopyFiles */, 82 | 3A98CC3E2069A40200C881E2 /* Locksmith.framework in CopyFiles */, 83 | 3A98CC3F2069A40200C881E2 /* MMMaterialDesignSpinner.framework in CopyFiles */, 84 | 3A98CC402069A40200C881E2 /* NVActivityIndicatorView.framework in CopyFiles */, 85 | 3A98CC412069A40200C881E2 /* ObjectMapper.framework in CopyFiles */, 86 | 3A98CC422069A40200C881E2 /* PayPalDataCollector.framework in CopyFiles */, 87 | 3A98CC432069A40200C881E2 /* PayPalOneTouch.framework in CopyFiles */, 88 | 3A98CC442069A40200C881E2 /* PayPalUtils.framework in CopyFiles */, 89 | 3A98CC452069A40200C881E2 /* pop.framework in CopyFiles */, 90 | 3A98CC462069A40200C881E2 /* Realm.framework in CopyFiles */, 91 | 3A98CC472069A40200C881E2 /* RealmSwift.framework in CopyFiles */, 92 | 3A98CC482069A40200C881E2 /* Stripe.framework in CopyFiles */, 93 | 3A98CC492069A40200C881E2 /* SVProgressHUD.framework in CopyFiles */, 94 | ); 95 | runOnlyForDeploymentPostprocessing = 0; 96 | }; 97 | /* End PBXCopyFilesBuildPhase section */ 98 | 99 | /* Begin PBXFileReference section */ 100 | 3A9533F9206A4358002FBA50 /* CircleView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CircleView.swift; sourceTree = ""; }; 101 | 3A9533FB206A4E6C002FBA50 /* View.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = View.swift; sourceTree = ""; }; 102 | 3A9533FD206A85D5002FBA50 /* README.md */ = {isa = PBXFileReference; lastKnownFileType = net.daringfireball.markdown; path = README.md; sourceTree = ""; }; 103 | 3A9533FE206A86B1002FBA50 /* Cartfile */ = {isa = PBXFileReference; lastKnownFileType = text; path = Cartfile; sourceTree = ""; }; 104 | 3A9533FF206A86B1002FBA50 /* carthage.sh */ = {isa = PBXFileReference; lastKnownFileType = text.script.sh; path = carthage.sh; sourceTree = ""; }; 105 | 3A98CBBD206998C000C881E2 /* FacebookShare.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = FacebookShare.framework; path = Carthage/Build/iOS/FacebookShare.framework; sourceTree = ""; }; 106 | 3A98CBBE206998C000C881E2 /* AirshipAppExtensions.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AirshipAppExtensions.framework; path = Carthage/Build/iOS/AirshipAppExtensions.framework; sourceTree = ""; }; 107 | 3A98CBBF206998C000C881E2 /* BraintreeAmericanExpress.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = BraintreeAmericanExpress.framework; path = Carthage/Build/iOS/BraintreeAmericanExpress.framework; sourceTree = ""; }; 108 | 3A98CBC0206998C000C881E2 /* Braintree3DSecure.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Braintree3DSecure.framework; path = Carthage/Build/iOS/Braintree3DSecure.framework; sourceTree = ""; }; 109 | 3A98CBC1206998C000C881E2 /* BraintreeUI.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = BraintreeUI.framework; path = Carthage/Build/iOS/BraintreeUI.framework; sourceTree = ""; }; 110 | 3A98CBC2206998C000C881E2 /* BraintreeUnionPay.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = BraintreeUnionPay.framework; path = Carthage/Build/iOS/BraintreeUnionPay.framework; sourceTree = ""; }; 111 | 3A98CBC3206998C000C881E2 /* BoltsSwift.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = BoltsSwift.framework; path = Carthage/Build/iOS/BoltsSwift.framework; sourceTree = ""; }; 112 | 3A98CBC4206998C100C881E2 /* FacebookLogin.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = FacebookLogin.framework; path = Carthage/Build/iOS/FacebookLogin.framework; sourceTree = ""; }; 113 | 3A98CBC5206998C100C881E2 /* Koloda.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Koloda.framework; path = Carthage/Build/iOS/Koloda.framework; sourceTree = ""; }; 114 | 3A98CBC6206998C100C881E2 /* BraintreeVenmo.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = BraintreeVenmo.framework; path = Carthage/Build/iOS/BraintreeVenmo.framework; sourceTree = ""; }; 115 | 3A98CBC7206998C100C881E2 /* BraintreeDataCollector.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = BraintreeDataCollector.framework; path = Carthage/Build/iOS/BraintreeDataCollector.framework; sourceTree = ""; }; 116 | 3A98CBC8206998C100C881E2 /* MMMaterialDesignSpinner.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = MMMaterialDesignSpinner.framework; path = Carthage/Build/iOS/MMMaterialDesignSpinner.framework; sourceTree = ""; }; 117 | 3A98CBC9206998C100C881E2 /* BraintreeCard.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = BraintreeCard.framework; path = Carthage/Build/iOS/BraintreeCard.framework; sourceTree = ""; }; 118 | 3A98CBCA206998C100C881E2 /* FBSDKShareKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = FBSDKShareKit.framework; path = Carthage/Build/iOS/FBSDKShareKit.framework; sourceTree = ""; }; 119 | 3A98CBCB206998C100C881E2 /* FBSDKPlacesKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = FBSDKPlacesKit.framework; path = Carthage/Build/iOS/FBSDKPlacesKit.framework; sourceTree = ""; }; 120 | 3A98CBCC206998C100C881E2 /* PayPalUtils.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = PayPalUtils.framework; path = Carthage/Build/iOS/PayPalUtils.framework; sourceTree = ""; }; 121 | 3A98CBCD206998C100C881E2 /* BraintreePaymentFlow.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = BraintreePaymentFlow.framework; path = Carthage/Build/iOS/BraintreePaymentFlow.framework; sourceTree = ""; }; 122 | 3A98CBCE206998C100C881E2 /* Bolts.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Bolts.framework; path = Carthage/Build/iOS/Bolts.framework; sourceTree = ""; }; 123 | 3A98CBCF206998C100C881E2 /* PayPalDataCollector.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = PayPalDataCollector.framework; path = Carthage/Build/iOS/PayPalDataCollector.framework; sourceTree = ""; }; 124 | 3A98CBD0206998C200C881E2 /* BraintreeApplePay.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = BraintreeApplePay.framework; path = Carthage/Build/iOS/BraintreeApplePay.framework; sourceTree = ""; }; 125 | 3A98CBD1206998C200C881E2 /* BraintreePayPal.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = BraintreePayPal.framework; path = Carthage/Build/iOS/BraintreePayPal.framework; sourceTree = ""; }; 126 | 3A98CBD2206998C200C881E2 /* FBSDKLoginKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = FBSDKLoginKit.framework; path = Carthage/Build/iOS/FBSDKLoginKit.framework; sourceTree = ""; }; 127 | 3A98CBD3206998C200C881E2 /* AirshipKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AirshipKit.framework; path = Carthage/Build/iOS/AirshipKit.framework; sourceTree = ""; }; 128 | 3A98CBD4206998C200C881E2 /* SVProgressHUD.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = SVProgressHUD.framework; path = Carthage/Build/iOS/SVProgressHUD.framework; sourceTree = ""; }; 129 | 3A98CBD5206998C200C881E2 /* NVActivityIndicatorView.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = NVActivityIndicatorView.framework; path = Carthage/Build/iOS/NVActivityIndicatorView.framework; sourceTree = ""; }; 130 | 3A98CBD6206998C200C881E2 /* ObjectMapper.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = ObjectMapper.framework; path = Carthage/Build/iOS/ObjectMapper.framework; sourceTree = ""; }; 131 | 3A98CBD7206998C200C881E2 /* FacebookCore.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = FacebookCore.framework; path = Carthage/Build/iOS/FacebookCore.framework; sourceTree = ""; }; 132 | 3A98CBD8206998C200C881E2 /* Realm.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Realm.framework; path = Carthage/Build/iOS/Realm.framework; sourceTree = ""; }; 133 | 3A98CBD9206998C300C881E2 /* RealmSwift.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = RealmSwift.framework; path = Carthage/Build/iOS/RealmSwift.framework; sourceTree = ""; }; 134 | 3A98CBDA206998C300C881E2 /* Locksmith.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Locksmith.framework; path = Carthage/Build/iOS/Locksmith.framework; sourceTree = ""; }; 135 | 3A98CBDB206998C300C881E2 /* Stripe.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Stripe.framework; path = Carthage/Build/iOS/Stripe.framework; sourceTree = ""; }; 136 | 3A98CBDC206998C300C881E2 /* pop.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = pop.framework; path = Carthage/Build/iOS/pop.framework; sourceTree = ""; }; 137 | 3A98CBDD206998C300C881E2 /* BraintreeCore.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = BraintreeCore.framework; path = Carthage/Build/iOS/BraintreeCore.framework; sourceTree = ""; }; 138 | 3A98CBDE206998C300C881E2 /* FBSDKCoreKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = FBSDKCoreKit.framework; path = Carthage/Build/iOS/FBSDKCoreKit.framework; sourceTree = ""; }; 139 | 3A98CBDF206998C300C881E2 /* PayPalOneTouch.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = PayPalOneTouch.framework; path = Carthage/Build/iOS/PayPalOneTouch.framework; sourceTree = ""; }; 140 | 3AEEEAFF20697EC700B91A2D /* Dlopen.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Dlopen.app; sourceTree = BUILT_PRODUCTS_DIR; }; 141 | 3AEEEB0220697EC700B91A2D /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; 142 | 3AEEEB0420697EC700B91A2D /* ViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ViewController.swift; sourceTree = ""; }; 143 | 3AEEEB0920697EC700B91A2D /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; 144 | 3AEEEB0E20697EC700B91A2D /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 145 | /* End PBXFileReference section */ 146 | 147 | /* Begin PBXFrameworksBuildPhase section */ 148 | 3AEEEAFC20697EC700B91A2D /* Frameworks */ = { 149 | isa = PBXFrameworksBuildPhase; 150 | buildActionMask = 2147483647; 151 | files = ( 152 | ); 153 | runOnlyForDeploymentPostprocessing = 0; 154 | }; 155 | /* End PBXFrameworksBuildPhase section */ 156 | 157 | /* Begin PBXGroup section */ 158 | 3AEEEAF620697EC700B91A2D = { 159 | isa = PBXGroup; 160 | children = ( 161 | 3AEEEB982069985C00B91A2D /* Frameworks */, 162 | 3AEEEB1520697ED200B91A2D /* targets */, 163 | 3AEEEB1420697ECD00B91A2D /* sources */, 164 | 3AEEEB0020697EC700B91A2D /* Products */, 165 | 3A9533FE206A86B1002FBA50 /* Cartfile */, 166 | 3A9533FF206A86B1002FBA50 /* carthage.sh */, 167 | 3A9533FD206A85D5002FBA50 /* README.md */, 168 | ); 169 | sourceTree = ""; 170 | }; 171 | 3AEEEB0020697EC700B91A2D /* Products */ = { 172 | isa = PBXGroup; 173 | children = ( 174 | 3AEEEAFF20697EC700B91A2D /* Dlopen.app */, 175 | ); 176 | name = Products; 177 | sourceTree = ""; 178 | }; 179 | 3AEEEB1420697ECD00B91A2D /* sources */ = { 180 | isa = PBXGroup; 181 | children = ( 182 | 3AEEEB1620697EDA00B91A2D /* main */, 183 | ); 184 | path = sources; 185 | sourceTree = ""; 186 | }; 187 | 3AEEEB1520697ED200B91A2D /* targets */ = { 188 | isa = PBXGroup; 189 | children = ( 190 | 3AEEEB1720697EDF00B91A2D /* main */, 191 | ); 192 | path = targets; 193 | sourceTree = ""; 194 | }; 195 | 3AEEEB1620697EDA00B91A2D /* main */ = { 196 | isa = PBXGroup; 197 | children = ( 198 | 3AEEEB0220697EC700B91A2D /* AppDelegate.swift */, 199 | 3AEEEB0420697EC700B91A2D /* ViewController.swift */, 200 | 3AEEEB0920697EC700B91A2D /* Assets.xcassets */, 201 | 3A9533F9206A4358002FBA50 /* CircleView.swift */, 202 | 3A9533FB206A4E6C002FBA50 /* View.swift */, 203 | ); 204 | path = main; 205 | sourceTree = ""; 206 | }; 207 | 3AEEEB1720697EDF00B91A2D /* main */ = { 208 | isa = PBXGroup; 209 | children = ( 210 | 3AEEEB0E20697EC700B91A2D /* Info.plist */, 211 | ); 212 | path = main; 213 | sourceTree = ""; 214 | }; 215 | 3AEEEB982069985C00B91A2D /* Frameworks */ = { 216 | isa = PBXGroup; 217 | children = ( 218 | 3A98CBBE206998C000C881E2 /* AirshipAppExtensions.framework */, 219 | 3A98CBD3206998C200C881E2 /* AirshipKit.framework */, 220 | 3A98CBCE206998C100C881E2 /* Bolts.framework */, 221 | 3A98CBC3206998C000C881E2 /* BoltsSwift.framework */, 222 | 3A98CBC0206998C000C881E2 /* Braintree3DSecure.framework */, 223 | 3A98CBBF206998C000C881E2 /* BraintreeAmericanExpress.framework */, 224 | 3A98CBD0206998C200C881E2 /* BraintreeApplePay.framework */, 225 | 3A98CBC9206998C100C881E2 /* BraintreeCard.framework */, 226 | 3A98CBDD206998C300C881E2 /* BraintreeCore.framework */, 227 | 3A98CBC7206998C100C881E2 /* BraintreeDataCollector.framework */, 228 | 3A98CBCD206998C100C881E2 /* BraintreePaymentFlow.framework */, 229 | 3A98CBD1206998C200C881E2 /* BraintreePayPal.framework */, 230 | 3A98CBC1206998C000C881E2 /* BraintreeUI.framework */, 231 | 3A98CBC2206998C000C881E2 /* BraintreeUnionPay.framework */, 232 | 3A98CBC6206998C100C881E2 /* BraintreeVenmo.framework */, 233 | 3A98CBD7206998C200C881E2 /* FacebookCore.framework */, 234 | 3A98CBC4206998C100C881E2 /* FacebookLogin.framework */, 235 | 3A98CBBD206998C000C881E2 /* FacebookShare.framework */, 236 | 3A98CBDE206998C300C881E2 /* FBSDKCoreKit.framework */, 237 | 3A98CBD2206998C200C881E2 /* FBSDKLoginKit.framework */, 238 | 3A98CBCB206998C100C881E2 /* FBSDKPlacesKit.framework */, 239 | 3A98CBCA206998C100C881E2 /* FBSDKShareKit.framework */, 240 | 3A98CBC5206998C100C881E2 /* Koloda.framework */, 241 | 3A98CBDA206998C300C881E2 /* Locksmith.framework */, 242 | 3A98CBC8206998C100C881E2 /* MMMaterialDesignSpinner.framework */, 243 | 3A98CBD5206998C200C881E2 /* NVActivityIndicatorView.framework */, 244 | 3A98CBD6206998C200C881E2 /* ObjectMapper.framework */, 245 | 3A98CBCF206998C100C881E2 /* PayPalDataCollector.framework */, 246 | 3A98CBDF206998C300C881E2 /* PayPalOneTouch.framework */, 247 | 3A98CBCC206998C100C881E2 /* PayPalUtils.framework */, 248 | 3A98CBDC206998C300C881E2 /* pop.framework */, 249 | 3A98CBD8206998C200C881E2 /* Realm.framework */, 250 | 3A98CBD9206998C300C881E2 /* RealmSwift.framework */, 251 | 3A98CBDB206998C300C881E2 /* Stripe.framework */, 252 | 3A98CBD4206998C200C881E2 /* SVProgressHUD.framework */, 253 | ); 254 | name = Frameworks; 255 | sourceTree = ""; 256 | }; 257 | /* End PBXGroup section */ 258 | 259 | /* Begin PBXNativeTarget section */ 260 | 3AEEEAFE20697EC700B91A2D /* Dlopen */ = { 261 | isa = PBXNativeTarget; 262 | buildConfigurationList = 3AEEEB1120697EC700B91A2D /* Build configuration list for PBXNativeTarget "Dlopen" */; 263 | buildPhases = ( 264 | 3AEEEAFB20697EC700B91A2D /* Sources */, 265 | 3AEEEAFC20697EC700B91A2D /* Frameworks */, 266 | 3AEEEAFD20697EC700B91A2D /* Resources */, 267 | 3A98CC262069A3F900C881E2 /* CopyFiles */, 268 | ); 269 | buildRules = ( 270 | ); 271 | dependencies = ( 272 | ); 273 | name = Dlopen; 274 | productName = Dlopen; 275 | productReference = 3AEEEAFF20697EC700B91A2D /* Dlopen.app */; 276 | productType = "com.apple.product-type.application"; 277 | }; 278 | /* End PBXNativeTarget section */ 279 | 280 | /* Begin PBXProject section */ 281 | 3AEEEAF720697EC700B91A2D /* Project object */ = { 282 | isa = PBXProject; 283 | attributes = { 284 | LastSwiftUpdateCheck = 0920; 285 | LastUpgradeCheck = 0920; 286 | ORGANIZATIONNAME = Me; 287 | TargetAttributes = { 288 | 3AEEEAFE20697EC700B91A2D = { 289 | CreatedOnToolsVersion = 9.2; 290 | ProvisioningStyle = Automatic; 291 | }; 292 | }; 293 | }; 294 | buildConfigurationList = 3AEEEAFA20697EC700B91A2D /* Build configuration list for PBXProject "Dlopen" */; 295 | compatibilityVersion = "Xcode 8.0"; 296 | developmentRegion = en; 297 | hasScannedForEncodings = 0; 298 | knownRegions = ( 299 | en, 300 | Base, 301 | ); 302 | mainGroup = 3AEEEAF620697EC700B91A2D; 303 | productRefGroup = 3AEEEB0020697EC700B91A2D /* Products */; 304 | projectDirPath = ""; 305 | projectRoot = ""; 306 | targets = ( 307 | 3AEEEAFE20697EC700B91A2D /* Dlopen */, 308 | ); 309 | }; 310 | /* End PBXProject section */ 311 | 312 | /* Begin PBXResourcesBuildPhase section */ 313 | 3AEEEAFD20697EC700B91A2D /* Resources */ = { 314 | isa = PBXResourcesBuildPhase; 315 | buildActionMask = 2147483647; 316 | files = ( 317 | 3AEEEB0A20697EC700B91A2D /* Assets.xcassets in Resources */, 318 | ); 319 | runOnlyForDeploymentPostprocessing = 0; 320 | }; 321 | /* End PBXResourcesBuildPhase section */ 322 | 323 | /* Begin PBXSourcesBuildPhase section */ 324 | 3AEEEAFB20697EC700B91A2D /* Sources */ = { 325 | isa = PBXSourcesBuildPhase; 326 | buildActionMask = 2147483647; 327 | files = ( 328 | 3A9533FC206A4E6C002FBA50 /* View.swift in Sources */, 329 | 3A9533FA206A4358002FBA50 /* CircleView.swift in Sources */, 330 | 3AEEEB0520697EC700B91A2D /* ViewController.swift in Sources */, 331 | 3AEEEB0320697EC700B91A2D /* AppDelegate.swift in Sources */, 332 | ); 333 | runOnlyForDeploymentPostprocessing = 0; 334 | }; 335 | /* End PBXSourcesBuildPhase section */ 336 | 337 | /* Begin XCBuildConfiguration section */ 338 | 3AEEEB0F20697EC700B91A2D /* Debug */ = { 339 | isa = XCBuildConfiguration; 340 | buildSettings = { 341 | ALWAYS_SEARCH_USER_PATHS = NO; 342 | CLANG_ANALYZER_NONNULL = YES; 343 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; 344 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; 345 | CLANG_CXX_LIBRARY = "libc++"; 346 | CLANG_ENABLE_MODULES = YES; 347 | CLANG_ENABLE_OBJC_ARC = YES; 348 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 349 | CLANG_WARN_BOOL_CONVERSION = YES; 350 | CLANG_WARN_COMMA = YES; 351 | CLANG_WARN_CONSTANT_CONVERSION = YES; 352 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 353 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 354 | CLANG_WARN_EMPTY_BODY = YES; 355 | CLANG_WARN_ENUM_CONVERSION = YES; 356 | CLANG_WARN_INFINITE_RECURSION = YES; 357 | CLANG_WARN_INT_CONVERSION = YES; 358 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 359 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 360 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 361 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 362 | CLANG_WARN_STRICT_PROTOTYPES = YES; 363 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 364 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; 365 | CLANG_WARN_UNREACHABLE_CODE = YES; 366 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 367 | CODE_SIGN_IDENTITY = "iPhone Developer"; 368 | COPY_PHASE_STRIP = NO; 369 | DEBUG_INFORMATION_FORMAT = dwarf; 370 | ENABLE_STRICT_OBJC_MSGSEND = YES; 371 | ENABLE_TESTABILITY = YES; 372 | GCC_C_LANGUAGE_STANDARD = gnu11; 373 | GCC_DYNAMIC_NO_PIC = NO; 374 | GCC_NO_COMMON_BLOCKS = YES; 375 | GCC_OPTIMIZATION_LEVEL = 0; 376 | GCC_PREPROCESSOR_DEFINITIONS = ( 377 | "DEBUG=1", 378 | "$(inherited)", 379 | ); 380 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 381 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 382 | GCC_WARN_UNDECLARED_SELECTOR = YES; 383 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 384 | GCC_WARN_UNUSED_FUNCTION = YES; 385 | GCC_WARN_UNUSED_VARIABLE = YES; 386 | IPHONEOS_DEPLOYMENT_TARGET = 11.2; 387 | MTL_ENABLE_DEBUG_INFO = YES; 388 | ONLY_ACTIVE_ARCH = YES; 389 | SDKROOT = iphoneos; 390 | SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; 391 | SWIFT_OPTIMIZATION_LEVEL = "-Onone"; 392 | }; 393 | name = Debug; 394 | }; 395 | 3AEEEB1020697EC700B91A2D /* Release */ = { 396 | isa = XCBuildConfiguration; 397 | buildSettings = { 398 | ALWAYS_SEARCH_USER_PATHS = NO; 399 | CLANG_ANALYZER_NONNULL = YES; 400 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; 401 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; 402 | CLANG_CXX_LIBRARY = "libc++"; 403 | CLANG_ENABLE_MODULES = YES; 404 | CLANG_ENABLE_OBJC_ARC = YES; 405 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 406 | CLANG_WARN_BOOL_CONVERSION = YES; 407 | CLANG_WARN_COMMA = YES; 408 | CLANG_WARN_CONSTANT_CONVERSION = YES; 409 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 410 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 411 | CLANG_WARN_EMPTY_BODY = YES; 412 | CLANG_WARN_ENUM_CONVERSION = YES; 413 | CLANG_WARN_INFINITE_RECURSION = YES; 414 | CLANG_WARN_INT_CONVERSION = YES; 415 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 416 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 417 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 418 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 419 | CLANG_WARN_STRICT_PROTOTYPES = YES; 420 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 421 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; 422 | CLANG_WARN_UNREACHABLE_CODE = YES; 423 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 424 | CODE_SIGN_IDENTITY = "iPhone Developer"; 425 | COPY_PHASE_STRIP = NO; 426 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 427 | ENABLE_NS_ASSERTIONS = NO; 428 | ENABLE_STRICT_OBJC_MSGSEND = YES; 429 | GCC_C_LANGUAGE_STANDARD = gnu11; 430 | GCC_NO_COMMON_BLOCKS = YES; 431 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 432 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 433 | GCC_WARN_UNDECLARED_SELECTOR = YES; 434 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 435 | GCC_WARN_UNUSED_FUNCTION = YES; 436 | GCC_WARN_UNUSED_VARIABLE = YES; 437 | IPHONEOS_DEPLOYMENT_TARGET = 11.2; 438 | MTL_ENABLE_DEBUG_INFO = NO; 439 | SDKROOT = iphoneos; 440 | SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule"; 441 | VALIDATE_PRODUCT = YES; 442 | }; 443 | name = Release; 444 | }; 445 | 3AEEEB1220697EC700B91A2D /* Debug */ = { 446 | isa = XCBuildConfiguration; 447 | buildSettings = { 448 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 449 | CODE_SIGN_IDENTITY = "iPhone Developer: alejandro.ramirez@poqcommerce.com (M2BEM84LUM)"; 450 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 451 | CODE_SIGN_STYLE = Automatic; 452 | DEVELOPMENT_TEAM = RPRLABY6AE; 453 | FRAMEWORK_SEARCH_PATHS = ( 454 | "$(inherited)", 455 | "$(PROJECT_DIR)/Carthage/Build/iOS", 456 | ); 457 | INFOPLIST_FILE = "$(SRCROOT)/targets/main/Info.plist"; 458 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; 459 | PRODUCT_BUNDLE_IDENTIFIER = com.poq.foobartennieltenniel; 460 | PRODUCT_NAME = "$(TARGET_NAME)"; 461 | PROVISIONING_PROFILE = ""; 462 | PROVISIONING_PROFILE_SPECIFIER = ""; 463 | SWIFT_VERSION = 4.0; 464 | TARGETED_DEVICE_FAMILY = "1,2"; 465 | }; 466 | name = Debug; 467 | }; 468 | 3AEEEB1320697EC700B91A2D /* Release */ = { 469 | isa = XCBuildConfiguration; 470 | buildSettings = { 471 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 472 | CODE_SIGN_IDENTITY = "iPhone Developer: alejandro.ramirez@poqcommerce.com (M2BEM84LUM)"; 473 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 474 | CODE_SIGN_STYLE = Automatic; 475 | DEVELOPMENT_TEAM = RPRLABY6AE; 476 | FRAMEWORK_SEARCH_PATHS = ( 477 | "$(inherited)", 478 | "$(PROJECT_DIR)/Carthage/Build/iOS", 479 | ); 480 | INFOPLIST_FILE = "$(SRCROOT)/targets/main/Info.plist"; 481 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; 482 | PRODUCT_BUNDLE_IDENTIFIER = com.poq.foobartennieltenniel; 483 | PRODUCT_NAME = "$(TARGET_NAME)"; 484 | PROVISIONING_PROFILE_SPECIFIER = ""; 485 | SWIFT_VERSION = 4.0; 486 | TARGETED_DEVICE_FAMILY = "1,2"; 487 | }; 488 | name = Release; 489 | }; 490 | /* End XCBuildConfiguration section */ 491 | 492 | /* Begin XCConfigurationList section */ 493 | 3AEEEAFA20697EC700B91A2D /* Build configuration list for PBXProject "Dlopen" */ = { 494 | isa = XCConfigurationList; 495 | buildConfigurations = ( 496 | 3AEEEB0F20697EC700B91A2D /* Debug */, 497 | 3AEEEB1020697EC700B91A2D /* Release */, 498 | ); 499 | defaultConfigurationIsVisible = 0; 500 | defaultConfigurationName = Release; 501 | }; 502 | 3AEEEB1120697EC700B91A2D /* Build configuration list for PBXNativeTarget "Dlopen" */ = { 503 | isa = XCConfigurationList; 504 | buildConfigurations = ( 505 | 3AEEEB1220697EC700B91A2D /* Debug */, 506 | 3AEEEB1320697EC700B91A2D /* Release */, 507 | ); 508 | defaultConfigurationIsVisible = 0; 509 | defaultConfigurationName = Release; 510 | }; 511 | /* End XCConfigurationList section */ 512 | }; 513 | rootObject = 3AEEEAF720697EC700B91A2D /* Project object */; 514 | } 515 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ### What is this? 2 | 3 | This application starts in 1.3 seconds and then loads 34 frameworks *at runtime*. 4 | 5 | Click below to see the video in youtube. 6 | 7 | [![Watch the video](https://raw.githubusercontent.com/j4n0/dlopen/master/thumbnail.png)](https://youtu.be/zJ0CKdZREWI) 8 | 9 | It takes 1.3s to load because the app contains 34 fat frameworks that weight 167Mb. Then it starts loading frameworks one by one. Loading a framework is a costly operation that slows down the application (I don’t know the specifics), however: 10 | 11 | - Core Animation keeps running smoothly. 12 | - I’m still able to type. 13 | 14 | To allow typing I only load frameworks during 1/3 of every second. This keeps the application more or less responsive. 15 | 16 | ### How I did it? 17 | 18 | To load the frameworks I used dlopen: 19 | ``` 20 | dlopen("MyFramework.framework/MyFramework", RTLD_LAZY) 21 | ``` 22 | 23 | Is this legal? Yes, Apple only demands that the application reviewed is the same your users will see. For instance, the app will fail review if you pass a dynamic parameter to dlopen. 24 | 25 | To use this technique you should be using dependency injection, which you should be doing anyway because it facilitates testing, understanding, splitting the work between teams, and speeds up developer iterations. Productivity is way higher when you are able to work on sets of screens disconnected from the main app. 26 | 27 | To load classes you have to use `NSClassFromString` then force cast it to an implementation of an interface. This is because if you import or reference a class anywhere, the framework will be automatically loaded. 28 | ``` 29 | print("\(NSClassFromString("MyFramework.AccountVC"))") 30 | ``` 31 | 32 | ### Why is this interesting? 33 | 34 | The use case for this technique is applications where features are presented linearly, like levels of a game, or those requiring signup –like bank applications. If the user is already logged, you can programmatically load all frameworks in advance while running a smooth animation to distract the user. Twitter animates their logo after startup time, you could be doing this while loading frameworks. I currently don’t know if loading at runtime is slower, or if loading more than one at once speeds up the process 35 | 36 | If you run the application until it finishes loading, then kill it, then run it again, it will load all frameworks within a second. This happens because the application contents remains cached in memory. 37 | 38 | Whether this is useful or not, it depends on its use case. Also keep in mind that this is an insane example with 34 fat frameworks. 39 | 40 | ### How do I test this example? 41 | ``` 42 | brew install carthage 43 | ./carthage.sh 44 | ``` 45 | Carthage will take half an hour to build all frameworks. 46 | 47 | On my iPhone 6 plus the console looks like this: 48 | ``` 49 | Animating circle 50 | Loading frameworks 51 | Frameworks loading --------- 52 | 1038ms 01/34 AirshipKit 53 | wait 700ms 54 | 117ms 02/34 Bolts 55 | wait 700ms 56 | 132ms 03/34 BoltsSwift 57 | 360ms 04/34 Braintree3DSecure 58 | wait 700ms 59 | 131ms 05/34 BraintreeAmericanExpress 60 | 133ms 06/34 BraintreeApplePay 61 | wait 700ms 62 | 00ms 07/34 BraintreeCard 63 | 00ms 08/34 BraintreeCore 64 | 129ms 09/34 BraintreeDataCollector 65 | 556ms 10/34 BraintreePayPal 66 | wait 700ms 67 | 209ms 11/34 BraintreePaymentFlow 68 | wait 700ms 69 | 161ms 12/34 BraintreeUI 70 | 143ms 13/34 BraintreeUnionPay 71 | wait 700ms 72 | 132ms 14/34 BraintreeVenmo 73 | 150ms 15/34 FBSDKCoreKit 74 | wait 700ms 75 | 157ms 16/34 FBSDKLoginKit 76 | 134ms 17/34 FBSDKPlacesKit 77 | wait 700ms 78 | 149ms 18/34 FBSDKShareKit 79 | 150ms 19/34 FacebookCore 80 | wait 700ms 81 | 138ms 20/34 FacebookLogin 82 | 154ms 21/34 FacebookShare 83 | wait 700ms 84 | 232ms 22/34 Koloda 85 | wait 700ms 86 | 153ms 23/34 Locksmith 87 | 120ms 24/34 MMMaterialDesignSpinner 88 | wait 700ms 89 | 114ms 25/34 NVActivityIndicatorView 90 | 131ms 26/34 ObjectMapper 91 | wait 700ms 92 | 00ms 27/34 PayPalDataCollector 93 | 00ms 28/34 PayPalOneTouch 94 | 00ms 29/34 PayPalUtils 95 | 167ms 30/34 Realm 96 | 120ms 31/34 RealmSwift 97 | wait 700ms 98 | 119ms 32/34 SVProgressHUD 99 | 130ms 33/34 Stripe 100 | wait 700ms 101 | 01ms 34/34 pop 102 | Loading time: 5560 103 | Loading time plus pauses: 16760 104 | ``` 105 | -------------------------------------------------------------------------------- /carthage.sh: -------------------------------------------------------------------------------- 1 | carthage update --use-ssh --platform ios --color always --cache-builds --no-use-binaries 2 | -------------------------------------------------------------------------------- /sources/main/AppDelegate.swift: -------------------------------------------------------------------------------- 1 | 2 | import UIKit 3 | 4 | @UIApplicationMain 5 | class AppDelegate: UIResponder, UIApplicationDelegate { 6 | 7 | var window: UIWindow? 8 | 9 | func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey : Any]? = nil) -> Bool 10 | { 11 | window = UIWindow() 12 | installRootViewController() 13 | window?.makeKeyAndVisible() 14 | return true 15 | } 16 | 17 | func applicationWillResignActive(_ application: UIApplication) {} 18 | func applicationDidEnterBackground(_ application: UIApplication) {} 19 | func applicationWillEnterForeground(_ application: UIApplication) {} 20 | func applicationDidBecomeActive(_ application: UIApplication) {} 21 | func applicationWillTerminate(_ application: UIApplication) {} 22 | 23 | private func installRootViewController() 24 | { 25 | let navigationController = UINavigationController() 26 | navigationController.pushViewController(ViewController(), animated: false) 27 | window?.rootViewController = navigationController 28 | } 29 | 30 | } 31 | -------------------------------------------------------------------------------- /sources/main/Assets.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "iphone", 5 | "size" : "20x20", 6 | "scale" : "2x" 7 | }, 8 | { 9 | "idiom" : "iphone", 10 | "size" : "20x20", 11 | "scale" : "3x" 12 | }, 13 | { 14 | "idiom" : "iphone", 15 | "size" : "29x29", 16 | "scale" : "2x" 17 | }, 18 | { 19 | "idiom" : "iphone", 20 | "size" : "29x29", 21 | "scale" : "3x" 22 | }, 23 | { 24 | "idiom" : "iphone", 25 | "size" : "40x40", 26 | "scale" : "2x" 27 | }, 28 | { 29 | "idiom" : "iphone", 30 | "size" : "40x40", 31 | "scale" : "3x" 32 | }, 33 | { 34 | "idiom" : "iphone", 35 | "size" : "60x60", 36 | "scale" : "2x" 37 | }, 38 | { 39 | "idiom" : "iphone", 40 | "size" : "60x60", 41 | "scale" : "3x" 42 | }, 43 | { 44 | "idiom" : "ipad", 45 | "size" : "20x20", 46 | "scale" : "1x" 47 | }, 48 | { 49 | "idiom" : "ipad", 50 | "size" : "20x20", 51 | "scale" : "2x" 52 | }, 53 | { 54 | "idiom" : "ipad", 55 | "size" : "29x29", 56 | "scale" : "1x" 57 | }, 58 | { 59 | "idiom" : "ipad", 60 | "size" : "29x29", 61 | "scale" : "2x" 62 | }, 63 | { 64 | "idiom" : "ipad", 65 | "size" : "40x40", 66 | "scale" : "1x" 67 | }, 68 | { 69 | "idiom" : "ipad", 70 | "size" : "40x40", 71 | "scale" : "2x" 72 | }, 73 | { 74 | "idiom" : "ipad", 75 | "size" : "76x76", 76 | "scale" : "1x" 77 | }, 78 | { 79 | "idiom" : "ipad", 80 | "size" : "76x76", 81 | "scale" : "2x" 82 | }, 83 | { 84 | "idiom" : "ipad", 85 | "size" : "83.5x83.5", 86 | "scale" : "2x" 87 | }, 88 | { 89 | "idiom" : "ios-marketing", 90 | "size" : "1024x1024", 91 | "scale" : "1x" 92 | } 93 | ], 94 | "info" : { 95 | "version" : 1, 96 | "author" : "xcode" 97 | } 98 | } -------------------------------------------------------------------------------- /sources/main/CircleView.swift: -------------------------------------------------------------------------------- 1 | 2 | import UIKit 3 | 4 | class CircleView: UIView 5 | { 6 | private var circleLayer: CAShapeLayer? 7 | 8 | override var superview: UIView? { 9 | get { return super.superview } 10 | set { expandOnSuperview() } 11 | } 12 | 13 | private func initialize(){ 14 | CircleView.removeLayer(layer: self.circleLayer) 15 | let circleLayer = CircleView.createCircleLayerExpandedOnView(self) 16 | layer.addSublayer(circleLayer) 17 | self.circleLayer = circleLayer 18 | } 19 | 20 | func animateCircle(duration: TimeInterval) { 21 | initialize() 22 | let animation = CircleView.createStrokeAnimation(duration: duration) 23 | circleLayer?.strokeEnd = 1.0 24 | circleLayer?.add(animation, forKey: "animateCircle") 25 | } 26 | 27 | private func expandOnSuperview() { 28 | self.translatesAutoresizingMaskIntoConstraints = false 29 | ["H:|[view]|", "V:|[view]|"].forEach { (constraint) in 30 | superview?.addConstraints(NSLayoutConstraint.constraints(withVisualFormat: constraint, options: [], metrics: nil, views: ["view": self])) 31 | } 32 | } 33 | 34 | private static func removeLayer(layer: CALayer?){ 35 | guard let layer = layer else { return } 36 | layer.removeAllAnimations() 37 | layer.removeFromSuperlayer() 38 | } 39 | 40 | private static func createCircleLayerExpandedOnView(_ view: UIView) -> CAShapeLayer { 41 | let center = CGPoint(x: view.frame.size.width / 2.0, y: view.frame.size.height / 2.0) 42 | let radius = (view.frame.size.width - 10)/2 43 | return CircleView.createCircleLayer(center: center, radius: radius) 44 | } 45 | 46 | private static func createCircleLayer(center: CGPoint, radius: CGFloat) -> CAShapeLayer { 47 | let circlePath = UIBezierPath(arcCenter: center, 48 | radius: radius, 49 | startAngle: 0.0, 50 | endAngle: CGFloat(Double.pi * 2.0), 51 | clockwise: true) 52 | let circleLayer = CAShapeLayer() 53 | circleLayer.path = circlePath.cgPath 54 | circleLayer.fillColor = UIColor.clear.cgColor 55 | circleLayer.strokeColor = UIColor.red.cgColor 56 | circleLayer.lineWidth = 50.0; 57 | circleLayer.strokeEnd = 0.0 58 | return circleLayer 59 | } 60 | 61 | private static func createStrokeAnimation(duration: TimeInterval) -> CABasicAnimation 62 | { 63 | let animation = CABasicAnimation(keyPath: "strokeEnd") 64 | animation.duration = duration 65 | animation.fromValue = 0 66 | animation.toValue = 1 67 | animation.timingFunction = CAMediaTimingFunction(name: kCAMediaTimingFunctionLinear) 68 | return animation 69 | } 70 | } 71 | 72 | -------------------------------------------------------------------------------- /sources/main/View.swift: -------------------------------------------------------------------------------- 1 | 2 | import UIKit 3 | 4 | private func configure(_ value: Type, block: (_ object: Type) -> Void) -> Type { 5 | block(value) 6 | return value 7 | } 8 | 9 | class View: UIView 10 | { 11 | private let circle = CircleView() 12 | private let label = configure(UILabel()){ 13 | $0.backgroundColor = .clear 14 | $0.textColor = .white 15 | $0.textAlignment = .center 16 | } 17 | private let field = configure(UITextField()){ 18 | $0.backgroundColor = .white 19 | $0.textAlignment = .center 20 | } 21 | 22 | func animateCircle(duration: TimeInterval){ 23 | circle.animateCircle(duration: duration) 24 | } 25 | func update(status: String){ 26 | label.text = status 27 | } 28 | 29 | init() { 30 | super.init(frame: CGRect.zero) 31 | initialize() 32 | } 33 | 34 | @available(*, unavailable) 35 | required init?(coder aDecoder: NSCoder) { 36 | fatalError("unavailable") 37 | } 38 | 39 | private func initialize() 40 | { 41 | backgroundColor = .black 42 | addSubview(circle) 43 | addSubview(label) 44 | addSubview(field) 45 | 46 | let views: [String: UIView] = [ "circle": circle, "field": field, "label": label] 47 | views.values.forEach { 48 | $0.translatesAutoresizingMaskIntoConstraints = false 49 | } 50 | 51 | [ 52 | "H:|[circle]|", "V:|[circle]|", 53 | "H:|[field]|", "V:[field(30)]", 54 | "H:|-50-[label]|", "V:[field]-10-[label(20)]" 55 | ].forEach { (constraint) in 56 | addConstraints(NSLayoutConstraint.constraints(withVisualFormat: constraint, options: [], metrics: nil, views: views)) 57 | } 58 | View.matchParentValue(attributes: [.centerX, .centerY], for: field) 59 | } 60 | 61 | private static func matchParentValue(attributes: [NSLayoutAttribute], for view: UIView){ 62 | guard let parent = view.superview else { return } 63 | for attribute in attributes { 64 | parent.addConstraint(NSLayoutConstraint(item: view, attribute: attribute, relatedBy: .equal, toItem: parent, attribute: attribute, multiplier: 1, constant: 0)) 65 | } 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /sources/main/ViewController.swift: -------------------------------------------------------------------------------- 1 | import UIKit 2 | 3 | class ViewController: UIViewController 4 | { 5 | private let theView = View() 6 | 7 | override func loadView() { 8 | view = theView 9 | } 10 | 11 | override func viewDidAppear(_ animated: Bool) { 12 | super.viewDidAppear(animated) 13 | 14 | updateLabel("Animating circle") 15 | theView.animateCircle(duration: 6) 16 | 17 | updateLabel("Loading frameworks") 18 | self.loadFrameworks() 19 | } 20 | 21 | func loadFrameworks(){ 22 | updateLabel("Frameworks loading ---------") 23 | let loadQueue = DispatchQueue(label: "loadQueue") 24 | let waitQueue = DispatchQueue(label: "waitQueue") 25 | 26 | var busyCount = 0 27 | var totalCount = 0 28 | var totalCountWithPauses = 0 29 | let pauseMs = 700 30 | let busyThreshold = 200 31 | 32 | let semaphore = DispatchSemaphore(value: 1) 33 | let wait:(Int)->() = { waitMs in 34 | self.log(message: "wait 700ms") 35 | waitQueue.asyncAfter(deadline: DispatchTime.now() + .milliseconds(waitMs), execute: { 36 | semaphore.signal() 37 | }) 38 | semaphore.wait() 39 | } 40 | 41 | loadQueue.async { 42 | let count = ViewController.frameworks.count - 1 43 | for i in 1...count { 44 | let name = ViewController.frameworks[i] 45 | let ms = ViewController.measureMillisecondsForTask { 46 | dlopen("\(name).framework/\(name)", RTLD_LAZY) 47 | } 48 | self.updateLabel(String(format: "%02dms %02d/%d %@", ms, i, count, name)) 49 | busyCount = busyCount + Int(ms) 50 | totalCount = totalCount + Int(ms) 51 | totalCountWithPauses = totalCountWithPauses + Int(ms) 52 | if busyCount > busyThreshold { 53 | wait(pauseMs) 54 | totalCountWithPauses = totalCountWithPauses + pauseMs 55 | busyCount = max(busyCount - pauseMs, 0) 56 | } 57 | } 58 | self.log(message: "Loading time: \(totalCount)") 59 | self.log(message: "Loading time plus pauses: \(totalCountWithPauses)") 60 | } 61 | } 62 | 63 | private func log(message: String){ 64 | DispatchQueue.main.async { 65 | print(message) 66 | } 67 | } 68 | 69 | private func updateLabel(_ status: String){ 70 | DispatchQueue.main.async { 71 | self.theView.update(status: status) 72 | } 73 | log(message: status) 74 | } 75 | 76 | private static func measureMillisecondsForTask(_ task: ()->()) -> UInt64 { 77 | let start = DispatchTime.now() 78 | task() 79 | let end = DispatchTime.now() 80 | return (end.uptimeNanoseconds - start.uptimeNanoseconds) / 1_000_000 81 | } 82 | 83 | private static let frameworks = [ 84 | "AirshipAppExtensions", 85 | "AirshipKit", 86 | "Bolts", 87 | "BoltsSwift", 88 | "Braintree3DSecure", 89 | "BraintreeAmericanExpress", 90 | "BraintreeApplePay", 91 | "BraintreeCard", 92 | "BraintreeCore", 93 | "BraintreeDataCollector", 94 | "BraintreePayPal", 95 | "BraintreePaymentFlow", 96 | "BraintreeUI", 97 | "BraintreeUnionPay", 98 | "BraintreeVenmo", 99 | "FBSDKCoreKit", 100 | "FBSDKLoginKit", 101 | "FBSDKPlacesKit", 102 | "FBSDKShareKit", 103 | "FacebookCore", 104 | "FacebookLogin", 105 | "FacebookShare", 106 | "Koloda", 107 | "Locksmith", 108 | "MMMaterialDesignSpinner", 109 | "NVActivityIndicatorView", 110 | "ObjectMapper", 111 | "PayPalDataCollector", 112 | "PayPalOneTouch", 113 | "PayPalUtils", 114 | "Realm", 115 | "RealmSwift", 116 | "SVProgressHUD", 117 | "Stripe", 118 | "pop" 119 | ] 120 | } 121 | -------------------------------------------------------------------------------- /targets/main/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 | APPL 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleVersion 20 | 1 21 | LSRequiresIPhoneOS 22 | 23 | UILaunchStoryboardName 24 | LaunchScreen 25 | UIRequiredDeviceCapabilities 26 | 27 | armv7 28 | 29 | UISupportedInterfaceOrientations 30 | 31 | UIInterfaceOrientationPortrait 32 | UIInterfaceOrientationLandscapeLeft 33 | UIInterfaceOrientationLandscapeRight 34 | 35 | UISupportedInterfaceOrientations~ipad 36 | 37 | UIInterfaceOrientationPortrait 38 | UIInterfaceOrientationPortraitUpsideDown 39 | UIInterfaceOrientationLandscapeLeft 40 | UIInterfaceOrientationLandscapeRight 41 | 42 | 43 | 44 | -------------------------------------------------------------------------------- /thumbnail.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/janodev/dlopen/8b9b1a4e9d44c72e90cd7e10363470e6478d4366/thumbnail.png --------------------------------------------------------------------------------