iOS SDK
Survey library to monetize your mobile app, provided by inBrain.ai.
Please, check the InBrainSurveys_Demo app for getting integration example.
Requirements
- iOS 12.0+ / Catalyst(macOS 10.15.1+)
- Swift 5.0+
- Xcode 13+
Installation
Swift Package Manager (SPM)
The Swift Package Manager is a tool for automating the distribution of Swift code and is integrated into the swift compiler.
- File > Add Packages...
- Add https://github.com/inbrainai/inBrainSurveys_SDK
- Select "Up to Next Major" with "2.0.0"
- Add
import InBrainSurveys
to begin using SDK in your code.
CocoaPods
CocoaPods is a dependency manager for Cocoa projects. To integrate InBrainSurveys into your Xcode project using CocoaPods, specify it in your Podfile
:
pod 'InBrainSurveys'
Then, from Terminal within the project folder, run
pod install
Once pod install command is complete, from now on open .xcworkspace file for your project.
Add import InBrainSurveys
to begin using SDK in your code.
Please, visit CocoaPods website for additional information.
Manual
Drag and drop the InBrainSurveys.xcframework file into the same folder level as your [AppName].xcodeproj or [AppName].xworkspace file;
Then open your app’s Target in the Project Settings and Choose the General tab.
Scroll down until you hit the Frameworks, Libraries and Embedded Content section...
1) Press ‘+’ to Locate the InBrainSurveys.framework file in your file hierarchy.
2) Once selected, press "Add";
3) Check that "Embed" option is "Embed & Sing". In case of "Don Not Embed" chosen - the app will crash with error
dyld: Library not loaded: @rpath/libswiftCore.dylib ...
4) Add import InBrainSurveys
to begin using SDK in your code.
Get Started
Initialize the SDK
InBrain.shared.setInBrain(apiClientID: "apiClientID",
apiSecret: "apiSecret",
isS2S: false)
apiClientId
: The client ID obtained from your Publisher DashboardapiSecret
: The client secret obtained from your Publisher DashboardisS2S
: Is your app enabled with Server-to-Server(S2S) callbacks? Set to true if so, false if no server architecture.
User identifier
Set uniq identifier of the user within your application. If value not set (or empty) - deviceId
will be used instead. This value is provided via S2S Callbacks as PanelistId
. See more here: S2S Docs.
InBrain.shared.set(userID: "userID")
userID
: The string value that uniquely identifies each user within your application (Example: an email, a username).
inBrain Delegate
InBrain.shared.inBrainDelegate = self
inBrainDelegate
: The object to receive the [events from the inBrain SDK] (#inBrainDelegate-functions).
Usage
Option #1: Use The Survey Wall
Simply show the survey wall and let the inBrain system handle everything else! Be sure to Setup your S2S Callbacks and fully configure your application here: Publisher Dashboard
For best user experience we recommend to check are the surveys available prior to giving the user an option to open the inBrain Survey Wall. DO NOT use this method when working with Native Surveys, as that does not take into account placement and categories filter options.
import InBrainSurveys
class ViewController: UIViewController {
func showSurveyWall(_ sender: UIButton) {
InBrain.shared.checkForAvailableSurveys { [weak self] hasSurveys, _ in
guard hasSurveys else { return }
InBrain.shared.inBrain.openWall(with .surveys)
}
}
}
Option #2: Use The Offers Wall
Simply show the offers wall and let the inBrain system handle everything else! Be sure to Setup your S2S Callbacks and fully configure your application here: Publisher Dashboard Please, note: : Talk to the inBrain inBrain team to enable the offers for the integration.
import InBrainSurveys
class ViewController: UIViewController {
func showOffersWall(_ sender: UIButton) {
InBrain.shared.inBrain.openWall(with .offers)
}
}
Option #3: Use Native Surveys
Native Surveys is similar to an API that can be used within our SDK. Fetch "Surveys" and receive a list of the top surveys for a single user based on their profiler data. inBrain handles collecting profiler data and matching users with the ideal surveys. When fetching surveys, we return a list with details about each survey opportunity such as Reward, Length of Interview, Rating, etc. You are responsible for displaying a representation (button, tile, etc.) for each survey natively within your app.
Important notes:
- Once the survey is completed - it becames invalid and cannot be opened again;
- Please, take care about refreshing surveys with appropriate filter(s). We are proposing to fetch Native Surveys each time after InBbrainWebView closed and some survey(s) completed;
- The same NativeSurvey may fit a few filters at the same time. If you are using a few filters - please, refresh the surveys for each filter where the survey presented;
- If you are using inBrain Wall as well - please take care about refreshing Native Surveys after some survey(s) completed. Use
surveysClosed(byWebView: Bool, completedSurvey: Bool, rewards: [InBrainSurveyReward]?)
method of InBrainDelegate to detect InBbrainWebView dismissal
InBrainSurveys SDK provides two ways to handle Native Surveys, please use the best fits for you:
Native Surveys with NativeSurveysDelegate
import InBrainSurveys
class NativeSurveysViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
InBrain.shared.nativeSurveysDelegate = self
let filter = InBrainSurveyFilter(placementId: "placementId",
categories: [.business],
excludedCategories: nil)
InBrain.shared.getNativeSurveys(filter: filter)
}
}
//MARK: - NativeSurveyDelegate
extension NativeSurveysViewController: NativeSurveyDelegate {
func nativeSurveysLoadingStarted(filter: InBrainSurveyFilter?) {
//Show some activity to the user while surveys loading is in process
}
func nativeSurveysReceived(_ surveys: [InBrainNativeSurvey], filter: InBrainSurveyFilter?) {
//Cache surveys and show them to the user
}
func failedToReceiveNativeSurveys(error: Error, filter: InBrainSurveyFilter?) {
//Handle error depends on app logic
}
}
Native Surveys with closures
import InBrainSurveys
class NativeSurveysViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
//Show some activity to the user while surveys loading is in process
InBrain.shared.getNativeSurveys(filter: nil, success: { surveys in
//Cache surveys and show them to the user
}, failed: {error in
//Handle error depends on app logic
})
}
}
filter
: Optional parameter for filter surveys. Possible options:placementId (String)
: an optional placement identifier. These can be setup in your Publisher Dashboardcategories: [InBrainSurveyCategory]
: an optional list of categories. Providing one or more categories will limit surveys to those categories.excludedCategories: [InBrainSurveyCategory]
: an optional list of EXCLUDED categories. Providing one or more excluded categories will only return surveys that do NOT belong to these categories.
Open A Native Survey
When a user within your app selects a survey, you will then need to call showNativeSurvey
along with the following survey data points. This will open the survey within a webview over your app.
func onSurveySelected(_ survey: InBrainNativeSurvey) {
InBrain.shared.showNativeSurveyWith(id: survey.id, searchId: survey.searchId,
offersEnabled: false)
}
surveyId
: id of the surveys to be shown;searchId
: survey'ssearchId
;offersEnabled
: Specifies whether to enable Offers feature at the Wall or not. Please, note: : Talk to the inBrain inBrain team to enable the offers for the integration.
Advanced Usage
Reward Hooks For Server2Server Apps
You can add your callbacks in the Dashboard and test the response!
Currency Sale
The SDK provides an option to get active currency sale. That may be done with method getCurrencySale(success:failed:)
:
InBrain.shared.getCurrencySale(success: { [weak self] sale in
// Show the info to the user
}, failed: { error in
// Handle the error
})
Custom tracking data
Value to track each user session. This value is provided via S2S Callbacks as SessionId
. See more here: S2S Docs
inBrain.setSessionId("test_session")
Please, note: All the configs should be done before showing the surveys, or it will have no effect.
Customize inBrain
InBrainSurveys provides to customize some UI elements of InBrainWebView. In order to do that - call these functions prior to showing InBrainWebView:
setNavigationBarTitle(_ title: String)
- Set title of InBrainWebView
setNavigationBarConfig(_ config: InBrainNavBarConfig)
- Customize UINavigationBar of InBrainWebView. Please, note: color values should be in sRGB (Device RGB) profile
let config = InBrainNavBarConfig(backgroundColor: UIColor(hex: "00a5ed"), buttonsColor: .white,
titleColor: .white, isTranslucent: false, hasShadow: false)
inBrain.setNavigationBarConfig(config)
setStatusBarConfig(_ config: InBrainStatusBarConfig)
- Customize Status Bar. Please, note: In order to customize status bar - needs to set View controller-based status bar appearance to YES
let statusBarConfig = InBrainStatusBarConfig(statusBarStyle: .lightContent, hideStatusBar: false)
inBrain.setStatusBarConfig(statusBarConfig)
Migration
InBrainSurveys 2.0 Migration Guide
InBrainSurveys 2.0.0 is the latest major release of InBrainSurveys, Survey library to monetize your mobile app, provided by inBrain.ai. As a major release, following Semantic Versioning conventions, 2.0 introduces several methods changes that one should be aware of.
SDK renaming
New name of the SDK is InBrainSurveys. As a result or renaming - build will be failed with errors. Possible errors using CocoaPods and manual installation:
- No such module 'InBrainSurveys_SDK_Swift' error
Solution - is to replaceimport InBrainSurveys_SDK_Swift
withimport InBrainSurveys
- InBrainSurveys_SDK_Swift/InBrainSurveys_SDK_Swift.h' file not found error
Solution - is to replace#import <InBrainSurveys_SDK_Swift/InBrainSurveys_SDK_Swift.h>
with#import <InBrainSurveys/InBrainSurveys.h>
.
Possible errors using Manual installation:
- There is no XCFramework found at '.../InBrainSurveys_SDK_Swift.xcframework' error
Solution - is to remove reference to InBrainSurveys_SDK_Swift.xcframework from your project and add InBrainSurveys.xcframework instead and to check that "Embed" option is "Embed & Sing".
Highly recommended to clean the build folde (cmd+shift+k) and Derived data after those updates.
New entities
- InBrainSurveyCategory - enum, represents all the supported categories;
- InBrainSurveyFilter - struct to specify survey fetching rules. It provides and option to get Native Surveys filtered by placement, categories and excluded categories. All the options may be used separated or simultaneously, the single limitation - is categories and excluded categories shouldn't intersect;
- InBrainWallOption - enum, specifies whether to enable Offers feature at the Wall.
Updated methods
InBrain
- getNativeSurveys(placementID: String?)
Changed to:getNativeSurveys(filter: InBrainSurveyFilter?)
- getNativeSurveys(placementID: String?, success: ([InBrainNativeSurvey]) -> (), failed: ErrorCallback)
Changed to:getNativeSurveys(filter: InBrainSurveyFilter?, success: ([InBrainNativeSurvey]) -> (), failed: ErrorCallback)
- showNativeSurveyWith(id: String, placementId: String?, from viewController: UIViewController?)
Changed to:showNativeSurveyWith(id: String, searchId: String, offersEnabled: Bool, from: UIViewController?)
NativeSurveyDelegate
- nativeSurveysLoadingStarted(placementId: String?)
Changed to:nativeSurveysLoadingStarted(filter: InBrainSurveyFilter?)
- nativeSurveysReceived(_ surveys: [InBrainNativeSurvey], placementId: String?)
Changed to:nativeSurveysReceived(_ surveys: [InBrainNativeSurvey], filter: InBrainSurveyFilter?)
- failedToReceiveNativeSurveys(error: Error, placementId: String?)
Changed to:failedToReceiveNativeSurveys(error: Error, filter: InBrainSurveyFilter?)
Other changes
NativeSurvey
'splacementId
property replaced withsearchId
;- added
categories
(categoryIds
for Obj-C) property toNativeSurvey
.
Available types and interfaces
Native Survey
Native Survey is an opbject which represents survey and has the following properties:
Property | Description |
---|---|
id | Id of the survey and the value that should be used when passing parameter to showNativeSurvey() |
rank | A normalized value of 1-N where 1 is highest ranked survey and N is the lowest ranked survey |
time | An estimation of how many minutes will be required for the user to complete the survey |
value | Reward the user will earn by completing the survey. This value is in the currency type (points, coins, cents) you specified within the publisher dashboard and already takes into consideration the revenue share you've allocated to share with the user for a survey completion. |
isProfilerSurvey | Boolean value indicating whether the survey represents an inBrain Profiler survey |
currencySale | Boolean value indicating if the value of the survey is adjusted based on an active currency sale |
multiplier | The currency sale multiplier value applied to the survey value |
conversionLevel | Value that indicates the approximate conversion rate of the survey. See possible values here |
categories | Array of values indicating what categories this survey belongs to. See possible values here |
searchId | This value should be used when opening a native survey. It includes important encoded information related to placement and category filters |
Survey Category
The survey may belong to one or a few categories, as well as may have no categories at all. The list of all possible categories may be found bellow:
- Automotive
- Beverages Alcoholic
- Beverages Non Alcoholic
- Business
- Children & Parenting
- Coalition Loyalty Programs
- Destinations & Tourism
- Education
- Electronics, Computer Software
- Entertainment And Leisure
- Finance, Banking, Investing & Insurance
- Food
- Gambling, Lottery
- Government & Politics
- HealthCare
- Home
- Media & Publishing
- Personal Care
- Restaurants
- Sensitive & Explicit Content
- Smoking & Tobacco
- Social Research
- Sports Recreation Fitness
- Telecommunications
- Transportation
- Travel - Airlines
- Travel - Hotels
- Travel - Services, Agency, Booking
- Credit Cards
- Video Games
- Fashion & Clothing - Other
- Fashion & Clothing - Department Store
Conversion Level
The Conversion Level buckets indicate how the survey has been performing platform-wide at inBrain, not necessarily how well the survey will perform for the user its shown to. Its recommended to use these tags only to portray a unique UI. Possible values are:
- New Survey;
- Very Poor Conversion
- Poor Conversion;
- Fair Conversion;
- Good Conversion;
- Very Good Conversion;
- Excellent Conversion.
Full list of SDK's function
InBrain Functions
setInBrain(apiClientID: String, apiSecret: String, isS2S: Bool)
setInBrain(apiClientID: String, apiSecret: String, isS2S: Bool, userID: String)
- Initial config of InBrain SDK
set(userID: String?)
- Provides and app userID to InBrain SDK;
- If no userID provided - UIDevice.current.identifierForVendor will be used instead.
setSessionID(_ sessionID: String?)
sessionID
: the session identifier
openWall()
openWall(with option: InBrainWallOption)
openWall(from viewController: UIViewController?)
openWall(with option: InBrainWallOption, from viewController: UIViewController)`
- Presents the inBrain Wall with configuration, provided before.
- Please, note: SDK should be configured before showing the surveys, or it will have no effect.
- Important: If you are using Native Surveys - please, take care about refreshing them after some survey(s) completed. Additional details may be found at Native Surveys section description.
showNativeSurveyWith(id: String, searchId: String, offersEnabled: Bool, from viewController: UIViewController?)
showNativeSurvey(_ survey: InBrainNativeSurvey, offersEnabled: Bool, from viewController: UIViewController?)
- Presents the Native Survey with configuration, provided before.
- Please, note: SDK should be configured before showing the survey, or it will have no effect.
- Important: If you are using Native Surveys - please, take care about refreshing them after some survey(s) completed. Additional details may be found at Native Surveys section description.
InBrainDelegate functions
surveysClosed(byWebView: Bool, completedSurvey: Bool, rewards: [InBrainSurveyReward]?)
- This delegate function calls back whenever the InBrainWebView is dismissed.
byWebView == true
- dismissed automatically by the WebView;byWebView == false
- dismissed by the user;completedSurvey == true
- some survey(s) completed (succeded or disqualified);rewards
- information about completed surveys and earned rewards. NOTE: At the moment only first Native Survey reward is delivered. That means if the user complete a Native Survey, proceed to the inBrain Wall and complete one more survey - only first reward will be delivered. In case of the inBrain Wall usage only - no rewards will be delivered.
NativeSurveysDelegate functions
func nativeSurveysLoadingStarted(filter: InBrainSurveyFilter?)
- Сalled just after loading of Native Surveys started.
nativeSurveysReceived(_ surveys: [InBrainNativeSurvey], filter: InBrainSurveyFilter?)
- Provides fresh portion of Native surveys.
failedToReceiveNativeSurveys(error: Error, filter: InBrainSurveyFilter?)
- Called if loading of Native Surveys failed
Side note - Things to double check:
- Be sure your configured InBrain SDK with proper values;
- Ensure that you are set InBrainDelegate and implemented didReceiveInBrainRewards() in case of Serverless app.
Troubleshooting
Library not loaded
In case of Objective-C projects building may be failed with error:
dyld: library not loaded: @rpath/libswiftCore.dylid
Library not loaded: @rpath/libswiftCore.dylib
Referenced from: .../Debug-iphonesimulator/InBrainSurveys.framework/InBrainSurveys
Reason: no suitable image found. Did find:
/usr/lib/swift/libswiftCore.dylib: mach-o, but not built for iOS simulator
To resolve this issue open Project -> Target -> Build Settings -> set Always Embed Swift Standard Libraries to YES.
M1/M2 Cocoapods Troubles
The SDK built with support of M1 architecture, so no troubles are expected. However if you will face some - we are proposing to try the next steps:
1) Open Terminal;
2) Install Homebrew;
3) Remove currently installed CocoaPods - sudo gem uninstall cocoapods
;
4) Install CocoaPods using Homebrew - brew install cocoapods
;
5) Go to project's folder at Terminal;
6) Remove pods from the project - pod deintegrate
;
7) Clean the project cmd+shift+k
at Xcode;
8) Clean Derived data;
9) Install the pods - pod install
at Terminal.
Now the problem should be solved.