Launching Context Insights

In the world of mobile app development, understanding the user is key to creating experiences that resonate and retain. Today, we’re thrilled to introduce Context Insights, a brand new analytics tool designed from the ground up for iOS developers. Context Insights is your gateway to understanding the real-world contexts in which your users engage with your app.

A New Dimension of User Understanding

iOS apps are used in a multitude of circumstances, at home on the couch, during the commute, while out on a walk, or anywhere in-between. Context Insights offers a new approach to user analytics. By analyzing the real-world context of your user base, you can gain insights into how different situations influence app usage. This allows you to segment your users more meaningfully, according to the context in which they interact with your app, providing a deeper understanding of their behavior and preferences.

Unparalleled Ease of Integration

We know how precious development time is. That’s why we’ve made integrating Context Insights into your iOS app as simple as possible. You’re just three steps away from getting brand new insights into how your app is used.

Step 1 - Signup and get your license key

Head over to our signup page and create a free account. We will send you your license key via email immediately.

Step 2 - Download ContextSDK and integrate it into your app

Simply add ContextSDK as a dependency to your Podfile (other integration options are supported as well, see here) and activate it by adding a single line at app start:

import ContextSDK

ContextManager.setup("YOUR_LICENSE_KEY")

Step 3 - Ship an Update

After the super simple integration simply ship an update to the App Store and we will notify you as soon as your insights are ready.

Designed with Performance in Mind

Context Insights is designed to ensure a negligible impact on your app’s performance. Adding less than 700KB to your app’s footprint. Moreover, it operates using less than 1MB of memory while active, ensuring that your apps performance is unaffected.

Privacy First

Finally it’s worth noting that Context Insights has been designed from the ground up to preserve your users privacy. We don’t require the user to authorize tracking, nor do we require any additional permissions to work. All the data collected by Context Insights is non PII (Personally Identifiable Information) and as such doesn’t not fall under GDPR.

Get Started Today

Embark on a journey to deeply understand your users with Context Insights. By integrating this powerful tool, you’re not just enhancing your app; you’re elevating the entire user experience. Discover the untapped potential within your user base and let Context Insights guide you towards creating more engaging, personalized, and successful iOS applications.

We can’t wait to see how you leverage Context Insights to make your app truly exceptional. Welcome to the future of iOS app development.

Get started here: https://insights.contextsdk.com/register

Tags: ios, context, sdk, swift, insights, analytics   |   Edit on GitHub

Automatically build & distribute custom iOS SDK Binaries for each customer

Note: This is a cross-post of the original publication on contextsdk.com.

Introduction

This is a follow-up post to our original publication: How to compile and distribute your iOS SDK as a pre-compiled xcframework.

In this technical article we go into the depths of best practices around

  • How to automate the deployment of different variants of your SDK to provide a fully customized, white-glove service for your customers
  • How this approach allows your SDK to work offline out-of-the box right from the first app start

Build Automation

For everyone who knows me, I love automating iOS app-development processes. Having built fastlane, I learned just how much time you can save, and most importantly: prevent human errors from happening. With ContextSDK, we fully automated the release process.

For example, you need to properly update the version number across many points: your 2 podspec files (see our last blog post), your URLs, adding git tags, updating the docs, etc.

Custom binaries for each customer

With ContextSDK, we train and deploy custom machine learning models for every one of our customers. The easiest way most companies would solve this is by sending a network request the first time the app is launched, to download the latest custom model for that particular app. However, we believe in fast & robust on-device Machine Learning Model execution, that doesn’t rely on an active internet connection. In particular, many major use-cases of ContextSDK rely on reacting to the user’s context within 2 seconds after the app is first launched, to immediately optimize the onboarding flow, permission prompts and other aspects of your app.

We needed a way to distribute each customer’s custom model with the ContextSDK binary, without including any models from other customers. To do this, we fully automated the deployment of custom SDK binaries, each including the exact custom model, and features the customer needs.

Our customer management system provides the list of custom SDKs to build, tied together with the details of the custom models:

[
  {
    "bundle_identifiers": ["com.customer.app"],
    "app_id": "c2d67cdb-e117-4c3e-acca-2ae7f1a42210",
    "customModels": [
      {
        "flowId": 8362,
        "flowName": "onboarding_upsell",
        "modelVersion": 73
      }, …
    ]
  }, …
]

Our deployment scripts will then iterate over each app, and include all custom models for the given app. You can inject custom classes and custom code before each build through multiple approaches. One approach we took to include custom models dynamically depending on the app, is to update our internal podspec to dynamically add files:‍

# ...

source_files = Dir['Classes/**/*.swift']
if ENV["CUSTOM_MODEL_APP_ID"]
  source_files += Dir["Classes/Models/Custom/#{ENV["CUSTOM_MODEL_APP_ID"]}/*.mlmodel"]
end

s.source_files = source_files

# ...

In the above example you can see how we leverage a simple environment variable to tell CocoaPods which custom model files to include.

Thanks to iOS projects being compiled, we can guarantee integrity of the codebase itself. Additionally we have hundreds of automated tests (and manual tests) to guarantee alignment of the custom models, matching SDK versions, model versions and each customer’s integration in a separate, auto-generated Xcode project.

Side-note: ContextSDK also supports over-the-air updates of new CoreML files, to update the ones we bundle the app with. This allows us to continuously improve our machine learning models over-time, as we calibrate our context signals to each individual app. Under the hood we deploy new challenger-models to a subset of users, for which we compare the performance, and gradually roll them out more if it matches expectations.

Conclusion

Building and distributing a custom binary for each customer is easier than you may expect. Once your SDK deployment is automated, taking the extra step to build custom binaries isn’t as complex as you may think.

Having this architecture allows us to iterate and move quickly, while having a very robust development and deployment pipeline. Additionally, once we segment our paid features for ContextSDK more, we can automatically only include the subset of functionality each customer wants enabled. For example, we recently launched AppTrackingTransparency.ai, where a customer may only want to use the ATT-related features of ContextSDK, instead of using it to optimise their in-app conversions.

If you have any questions, feel free to reach out to us on Twitter or LinkedIn, or subscribe to our newsletter on contextsdk.com.

Note: This is a cross-post of the original publication on contextsdk.com.

Tags: ios, context, sdk, swift, xcframework, compile, distribute, automation, fastlane, custom   |   Edit on GitHub

How to automatically compile and distribute your iOS SDK as a pre-compiled xcframework

Note: This is a cross-post of the original publication on contextsdk.com.

Introduction

In this technical article we go into the depths and best practices around

  • Working efficiently on a commercial SDK in a larger team
  • How to compile and distribute your iOS SDK as a pre-compiled xcframework automatically

How to build and debug an iOS SDK?

At ContextSDK we have our whole iOS Swift codebase in a single local CocoaPod. This allows us to iterate quickly as a team, and have our SDK configuration defined in clean code in version control, instead of some plist Xcode settings.

ContextSDK.podspec

Pod::Spec.new do |s|
  s.name             = 'ContextSDK'
  s.version          = '3.2.0'
  s.summary          = 'Introducing the most intelligent way to know when and how to monetize your user'
  s.swift_version    = '5.7'
  s.homepage         = 'https://contextsdk.com'
  s.author           = { 'KrauseFx' => 'felix@contextsdk.com' }
  s.ios.deployment_target = '14.0'

  # via https://github.com/CocoaPods/cocoapods-packager/issues/216
  s.source = { :git => "file://#{File.expand_path("..", __FILE__)}" }

  s.pod_target_xcconfig = {
    "SWIFT_SERIALIZE_DEBUGGING_OPTIONS" => "NO",
    "OTHER_SWIFT_FLAGS" => "-Xfrontend -no-serialize-debugging-options",
    "BUILD_LIBRARY_FOR_DISTRIBUTION" => "YES", # for swift Library Evolution
    "SWIFT_REFLECTION_METADATA_LEVEL" => "none", # to include less metadata in the resulting binary
  }

  s.frameworks = 'AVFoundation'
  s.public_header_files = 'Classes/**/*.h'
  s.source_files = Dir['Classes/**/*.{swift}']
  s.resource_bundles = { 'ContextSDK' => ['PrivacyInfo.xcprivacy'] }

  s.test_spec 'Tests' do |test_spec|
    test_spec.source_files = [
      'Tests/*.{swift}',
      'Tests/Resources/*.{plist}'
    ]

    test_spec.dependency 'Quick', '7.2.0'
    test_spec.dependency 'Nimble', '12.2.0'
  end
end

During development, we want to easily edit our codebase, run the Demo app, and debug using Xcode. To do that, our Demo app has a simple Podfile referencing our local CocoaPod:

target 'ContextSDKDemo' do
  use_frameworks!
  pod 'ContextSDK', :path => '../ContextSDK', :testspecs => ['Tests'] 
end

Running pod install will then nicely setup your Xcode workspace, ready to run the local ContextSDK codebase:

Editing a ContextSDK source file (e.g. Context.swift) will then immediately be accessible and used by Xcode during the next compile. This makes development of SDKs extremely easy & efficient.

How to compile a CocoaPod into a static binary (xcframework)?

The requirement for commercial SDKs is often that its source code isn’t accessible to its user. To do that, you need to pre-compile your SDK into an .xcframework static binary, which can then be used by your customers.

Thanks to the excellent cocoapods-pack project, started by Dimitris by Square, it’s easily possible to compile your SDK for distribution to your customers. After installing the gem, you can use the following command:

bundle exec pod pack ../ContextSDK.podspec https://contextsdk.com --skip-validation

Now open up the folder ./zips/ContextSDK/3.2.0/ and you will see a freshly prepared ContextSDK.zip. You can’t distribute that zip file right-away, as it contains an additional subfolder called ios, which would break the distribution through CocoaPods when we tested it.

As part of our deployment pipeline, we run the following Ruby commands to remove the ios folder, and re-zip the file:

puts "Preparing ContextSDK framework for release..."

sh("rm -rf zips")
sh("bundle exec pod pack ../ContextSDK.podspec https://contextsdk.com --skip-validation") || exit(1)
sh("rm -rf files")

# Important: we need to unzip the zip file, and then zip it again without having the "ios" toplevel folder
# which will break CocoaPods support, as CococaPods only looks inside the root folder, not iOS
zip_file_path = "zips/ContextSDK/#{@version_number}/ContextSDK.zip"
sh("unzip #{zip_file_path} -d zips/current")
sh("cd zips/current/ios && zip -r ../ContextSDK.zip ./*") # Now zip it again, but without the "ios" folder
return "zips/current/ContextSDK.zip"

ContextSDK.zip is now ready for distribution. If you unzip that file, you’ll see the ContextSDK.xcframework contained directly, which is what your users will add to their Xcode project, and will be picked up by CocoaPods.

How to distribute your SDK?

Manual Installation

There are no extra steps needed: the ZIP file you created above is everything that’s needed. Now you can provide the following instructions to your users:

  1. Download the latest release: [URL to your ZIP file]
  2. Drag & Drop the ContextSDK.xcframework folder into the Xcode file list
  3. Go to your project settings, scroll down to Frameworks, Libraries, and Embedded Content, add ContextSDK.xcframework, and select Embed & Sign

Through CocoaPods

Distributing your pre-compiled .xcframework file through CocoaPods requires some extra steps.

You need a second ContextSDK.podspec file, that will be available to the public. That podspec will only point to your pre-compiled binary, instead of your source code, therefore it’s safe to distribute to the public.

Pod::Spec.new do |s|
  s.name                = 'ContextSDK'
  s.version             = '3.2.0'
  s.homepage            = 'https://contextsdk.com'
  s.documentation_url   = 'https://docs.contextsdk.com'
  s.license             = { :type => 'Commercial' }
  s.author              = { 'ContextSDK' => 'support@contextsdk.com' }
  s.summary             = 'Introducing the most intelligent way to know when and how to monetize your use'

  s.platform            = :ios, '14.0'
  s.source              = { :http => '[URL to your ZIP file]' }

  s.xcconfig            = { 'FRAMEWORK_SEARCH_PATHS' => '"$(PODS_ROOT)/ContextSDK/**"' }
  s.frameworks          = 'AVFoundation'
  s.requires_arc        = true
  s.swift_version       = '5.7'
  s.module_name         = 'ContextSDK'

  s.preserve_paths      = 'ContextSDK.xcframework'
  s.vendored_frameworks = 'ContextSDK.xcframework'
end

Make both your podspec, and your ZIP file available to the public. Once complete, you can provide the following instructions to your users:

  1. Add the following dependency to your Podfile:
    pod 'ContextSDK', podspec: '[URL to your public .podspec]'
    
  2. Run pod install

Through Swift Package Manager (SPM)

Create a new git repo (we called it context-sdk-releases), which will contain all your historic and current releases, as well as a newly created Package.swift file:

// swift-tools-version:5.4

import PackageDescription

let package = Package(
    name: "ContextSDK",
    products: [
        .library(
            name: "ContextSDK",
            targets: ["ContextSDK"]),
    ],
    dependencies: [],
    targets: [
        .binaryTarget(
            name: "ContextSDK",
            path: "releases/ContextSDK.zip"
        )
    ]
)

You can use the same zip file we’ve created with SPM as well. Additionally, you’ll need to make use of git tags for releases, so that your customers can pinpoint a specific release. You can either make this repo public, or you’ll need to manually grant read permission to everyone who wants to use SPM.

To your users, you can provide the following instructions:

  1. Add https://github.com/context-sdk/context-sdk-releases as dependency

Conclusion

As we were building out our automated SDK distribution, we noticed there aren’t a lot of guides online around how to best develop, build and distribute your SDK as a pre-compiled binary, so we hope this article helps you to get started.

If you have any questions, feel free to reach out to us on Twitter or LinkedIn, or subscribe to our newsletter on contextsdk.com.

Note: This is a cross-post of the original publication on contextsdk.com.

Tags: ios, context, sdk, swift, xcframework, compile, distribute, automation, fastlane   |   Edit on GitHub

ContextSDK - Optimize your ATT prompts

Launching AppTrackingTransparency.ai - the first, of many hyper-focused ContextSDK products, helping you increase your app’s revenue.

Apps relying on ad-revenue have struggled showing the App Tracking Transparency (ATT) prompt at the right time, reducing their likelihood of an opt-in. Large players in the market have shared that an increase of 10% ATT opt-in can increase their revenue by 5-7%.

Thanks to the new ContextSDK technology, we can significantly increase your opt-in rate, by leveraging on-device Machine Learning and the user’s real-world context to find the perfect moment to trigger the prompt. All of this, while fully preserving the user’s privacy, never using any PII, and minimal footprint of 700 KB in your app’s binary.

You only have one shot at showing the prompt, therefore, timing is crucial. We leverage the user’s real-world context, as well as your specific app’s usage patterns, to find the perfect moment to trigger the ATT prompt in your app.

You can get started using ContextSDK for optimizing your App Tracking Transparency prompt completely risk-free using just a single line of code:

At first your ATT prompt behaviour won’t change, and it’s always shown. Only once we’ve calibrated your model, we will automatically choose the perfect time to prompt the user. The integration is super easy:

  1. Integrate ContextSDK and replace ATTrackingManager with ContextManager
  2. Ship an App Store update, and ContextSDK will automatically calibrate its signals towards your app and user base
  3. Get your own custom ML Model, packaged in your personal ContextSDK Binary, ready to start optimizing your app

For pricing details, and to sign-up, check out AppTrackingTransparency.ai.

Tags: ios, context, sdk, swift, upsell, in-app, prompt, att, app, tracking, transparency   |   Edit on GitHub