These are the integration instructions for the iOS Open Measurement SDK. If you are porting an existing integration to the newest version of OM SDK, please refer to the migration guide.
OM SDK supports iOS 9.0 and above versions, and tvOS 9.0 and above versions.
Please implement the following setup steps before moving on to the specific ad format instructions.
The first step is, of course, to add the OM SDK to your app or ads SDK.
Drag the dynamic xcfamework into your Project and make sure that it has been added in the “Link Binary With Libraries” phase of your target.
You should implement these steps as early as possible in your app or SDK lifecycle. It’s recommended that the SDK is activated on [AppDelegate application:didFinishLaunchWithOptions:].
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
[[OMIDSDK sharedInstance] activate]
}
Note that OM SDK may only be used on the main UI thread. Make sure you are on the main thread when you initialize the SDK, create its objects, and invoke its methods.
The first step is to initialize the OM SDK:
NSError *error;
BOOL sdkStarted = [[OMIDSDK sharedInstance] activate];
If the SDK fails to initialize, all subsequent steps will fail as well if the SDK does not initialize properly.
On tvOS, the app should signal to the SDK when a user interacts with app, via manual input. This can be done like so:
[[OMIDSDK sharedInstance] updateLastActivity]
Note that the SDK will consider app activation (specifically the UIApplicationDidBecomeActiveNotification
notification triggered on app foregrounding) as activity events. Only the latest activity timestamp
will be sent to measurement scripts, so that they can validate that a user is likely present.
Note that careful thought should be given to implementing calling this API, to ensure that it’s only called on user input. For example, calling this API on the start of media playback would be incorrect, since a future update may trigger via media playback via autoplay.
As the next step, you must fetch the OMID JS service library and save the response.
NSURL *url = [NSURL URLWithString:@"https://my.server.com/omsdk.js"];
__weak typeof(self) weakSelf = self;
NSURLSessionDataTask *dataTask = [defaultSession dataTaskWithURL:url
completionHandler:^(NSData *data, NSURLResponse
*response, NSError *error) {
if (error || weakSelf == nil) {
return;
}
weakSelf.omidJS = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
}];
[dataTask resume];
We recommend that this step is performed right after you’ve initialized the SDK because you will need the JS library to be available before you create any tracking session.
Note that this step is only necessary if you are injecting the OMID JS library client-side, which may not necessarily be true if you use only WebView ad formats. This is because WebView ad formats (not native, however) permit the injection server-side. If you are indeed injecting the JS library server-side (i.e., within the ad response itself), you can skip this step.
Note also that when integrating the native OM SDK, you must use the same or later version of the OM SDK JavaScript — ideally deploying the latest JavaScript patch version downloaded from the IAB Tech Lab tools portal.
Create a Partner
object to identify your integration. The IAB Tech Lab will assign a unique
partner name to you at the time of integration, so this is the value you should use here.
The version string should represent the integration version in semantic versioning format. For an ads SDK, this should be the same as your SDK’s semantic version. For an app publisher, this should be the same as your app version.
OMIDPartner *partner = [[OMIDPartner alloc] initWithName:PARTNER_NAME
versionString:PARTNER_SDK_OR_APP_VERSION];
You do not need to use the object at this time, but it will be required each time you track a new ad.
The following sections describe how to implement measurement for various ad formats. They assume you’ve already imported the library and implemented the initialization code.
The steps below describe how to create a tracking session for a WebView (HTML) ad.
Retrieve the ad response as you normally would. For the purposes of the subsequent steps, the ad response should be an HTML string.
NSString *adResponseHtmlString = @"<html>...</html>";
After you’ve retrieved the ad response, inject the JS service into the ad response and load inside the ad WebView:
NSError *error;
String *htmlString = [OMIDScriptInjector injectScriptContent:self.omidJS
intoHTML:adResponseHtmlString error:&error];
[adWebView loadHTMLString:htmlString baseURL:[[NSBundle mainBundle] bundleURL]];
Note, as mentioned in Step 2 of Initialization, if you have injected the JS service library server-side, this step is not necessary.
Create the session in the following sequence of steps.
Please note that each class’s initializer has its own input error checking, so it is important to pass through an error object and validate that each instance initialized successfully.
Note: in order to prevent issues with starting the session later, you must wait until the
WebView finishes loading OM SDK JavaScript before creating the OMIDAdSession
. Creating the session
sooner than that may result in an inability to signal events (impression, etc.) to verification
scripts inside the WebView. The easiest way to avoid this issue is to create the OMIDAdSession
in the webview delegate callback, -[WKNavigationDelegate webView:didFinishNavigation:]
(As of
OM SDK 1.3.4, UIWebView
support has been removed). Alternatively, if an implementation can receive an
HTML5 DOMContentLoaded event from the WebView, it can create the OMIDAdSession
in a message
handler for that event.
// In an implementation of WKNavigationDelegate:
- (void)webView:(WKWebView *)webView didFinishNavigation:(WKNavigation *)navigation {
if (self.omidSession != nil) return;
/*
* Create the session.
* Eliding the steps for brevity. Please reference for full steps below.
* /
self.omidSession = [[OMIDAdSession alloc] initWithConfiguration:config
adSessionContext:context error:nil];
// Set the view on which to track viewability
self.omidSession.mainAdView = webView;
// Start session
[self.omidSession start];
}
First, create a context with a reference to the partner object you created in the setup step and the ad’s WebView.
NSError *ctxError;
// the custom reference ID may not be relevant to your integration in which case you may pass an
// empty string.
NSString *customRefId = ...;
// contentUrl is the iOS universal link to the screen displaying the ad, nor nil if not applicable.
NSString *contentUrl = ...;
OMIDAdSessionContext *context = [[OMIDAdSessionContext alloc] initWithPartner:partner
webView:adWebView contentUrl:contentUrl customReferenceIdentifier:customRefId error:&ctxError];
Then designate which layer is responsible for signaling the impression event. For WebView display ads this is generally the native layer. We’ll get to the actual signaling of the event in a subsequent step.
NSError *cfgError;
// Set impression type as appropriate for this integration (begin-to-render, one pixel, etc.).
OMIDImpressionType impressionType = ...;
OMIDAdSessionConfiguration *config = [[OMIDAdSessionConfiguration alloc]
initWithCreativeType:OMIDCreativeTypeHtmlDisplay impressionType:impressionType impressionOwner:OMIDNativeOwner mediaEventsOwner:OMIDNoneOwner isolateVerificationScripts:NO error:&cfgError];
Finally, create the session itself.
NSError *sessError;
self.omidSession = [[OMIDAdSession alloc] initWithConfiguration:config
adSessionContext:context error:&sessError];
You will want to store a strong reference to the session either as a property or in a mapping dictionary (if you expect multiple concurrent ad sessions, in which case you would map from an ad instance to its associated session).
The subsequent steps assume you were able to initialize the session successfully. Of course, if the session failed to initialize with an error, it will return a nil reference and you should not use it subsequently.
Set the view on which to track viewability. For a WebView ad, this will be the WebView itself. For a native ad, this will be the native view that contains all the relevant elements of the ad.
self.omidSession.mainAdView = adView;
If there are any native elements which you would consider to be part of the ad, such as a close button, some logo text, or another decoration, you should register them as friendly obstructions to prevent them from counting towards coverage of the ad. This applies to any ancestor or peer views in the view hierarchy (all sub-views of the adView will be automatically treated as part of the ad):
[self.omidSession addFriendlyObstruction:view];
If the view changes at a subsequent time due to a fullscreen expansion or for a similar reason, you
should always update the mainAdView
reference to whatever is appropriate at that time.
Starting the session does not trigger an impression yet – it only prepares the session for tracking. It is important to start the session before dispatching any events.
[self.omidSession start];
Dispatch the loaded event to signal that the ad has loaded and is ready to display.
NSError *adEvtsError;
OMIDAdEvents *adEvents = [[OMIDAdEvents alloc] initWithAdSession:omidSession error:&adEvtsError];
NSError *loadedError;
[self.adEvents loadedWithError:&loadedError];
As described in the previous step, this should occur after the WebView has loaded.
The definition of an impression is generally accepted to be on ad render so this is likely when you will want to dispatch the event. The event should be dispatched only once and attempting to trigger it multiple times is an error.
NSError *impError;
[adEvents impressionOccurredWithError:&impError];
Stop the session when the impression has completed and the ad will be destroyed. Note, that after you’ve stopped the session it is an error to attempt to start it again or trigger an impression on the finished session.
Note that ending an OMID ad session sends a message to the verification scripts running inside the webview supplied by the integration. So that the verification scripts have enough time to handle the sessionFinish
event, the integration must maintain a strong reference to the webview for at least 1.0 seconds after ending the session.
[self.omidSession finish];
self.omidSession = nil;
The implementation instructions for WebView Video are similar in many respects to WebView Display on the native side. The primary point of difference is that WebView Video will generally require some additional implementation within the JavaScript layer inside the WebView. This additional JavaScript configuration will likely be performed to a large degree in your ad server so that the necessary components are embedded within the ad response by the time your app or SDK receives it.
The following implementation instructions assume that the JavaScript layer is responsible for these actions:
Impression events and playback progress can be handled from the native layer as well. You can
indicate which layer is responsible for event handling at the time that you create the
OMIDAdSessionConfiguration
instance by passing through the appropriate owner (Native or JavaScript)
for the respective events. As mentioned previously, this guide assumes you will be implementing the
responsibilities cited above in the JavaScript layer. If you would like instructions on how to do
the same in the native layer, please reference the Native Video implementation instructions.
Within the HTML ad response, please create a SessionClient. You will interact with classes from the SessionClient to signal events and pass metadata.
var sessionClient;
try {
sessionClient = OmidSessionClient[SESSION_CLIENT_VERSION];
} catch (e) {}
if (!sessionClient) {
return;
}
const AdSession = sessionClient.AdSession;
const Partner = sessionClient.Partner;
const Context = sessionClient.Context;
const VerificationScriptResource = sessionClient.VerificationScriptResource;
const AdEvents = sessionClient.AdEvents;
const MediaEvents = sessionClient.MediaEvents;
See this step of WebView Display. This guide assumes that the ad response will contain HTML (which will render the video player) as well as a VAST component.
See this step of WebView Display.
See this step of WebView Display.
Note that you will want to designate which layer is responsible for signaling events differently than for WebView Display. Generally for WebView video the JavaScript layer will be signaling both the impression and video events. If this is not done correctly, the OMID service will not pass events to any verification scripts.
As with WebView display, you should ensure the session set up and creation should happen only after receiving the WebView loaded event. Please reference this step of the WebView Display instructions for further detail.
Furthermore, you should decide on the appropriate value for the isolateVerificationScripts
parameter. The effect of a YES
value is that measurement resources will be placed in a sandboxed
iframe where they cannot access the video ad element. If you specify NO
, they will be placed into
a same-origin iframe. The FAQ has further detail on this setting.
NSError *cfgError;
// The creative and impression types will be defined by the JS layer.
OMIDAdSessionConfiguration *config = [[OMIDAdSessionConfiguration alloc] initWithCreativeType:OMIDCreativeTypeDefinedByJavaScript
impressionType:OMIDImpressionTypeDefinedByJavaScript
impressionOwner:OMIDJavaScriptOwner
mediaEventsOwner:OMIDJavaScriptOwner
isolateVerificationScripts:YES|NO
error:&cfgError];
See this step of WebView Display.
The following instructions assume the ad response uses the VAST 4.1 Verification node, either per the 4.1 spec exactly or in the Extensions node. The exact details are outside the scope of this document and are addressed by other Tech Lab guidance and documentation.
If you are not able to use VAST or the 4.1 node, you must find an alternative way to embed this information within the ad response and will likely need to work with each measurement vendor individually to determine the correct mechanism for loading their tags.
Using this 4.1 Verification node as an example:
<Verification vendor="vendorKey">
<JavaScriptResource apiFramework="omid">
<![CDATA[https://measurement.domain.com/tag.js]]>
</JavaScriptResource>
<VerificationParameters>
<![CDATA[{...}]]>
</VerificationParameters>
</Verification>
First create an array to hold one or more measurement resources that you will parse in the next step:
var resources = [];
Then, for each Verification node in the ad response, create a VerificationScriptResource
instance
as follows:
var vendorKey = ...; // parsed from "vendor" attribute
var params = ...; // parsed from VerificationParameters as a string
var url = ...; // parsed from JavaScriptResource
var resource = new VerificationScriptResource(url, vendorKey, params);
resources.add(resource);
Note that the vendorKey must match the vendor
attribute from the Verification node in order
for OM SDK to pass any impression specific metadata in the VerificationParameters to the correct
verification script.
Next, create the JS ad session and pass through the measurement resources you parsed from the ad response in the previous step. You will need to use this session instance in order to subscribe to the native session start event as well as to load the resources.
var partner = new Partner(PARTNER_NAME, PARTNER_SDK_OR_APP_VERSION);
var context = new Context(partner, resources);
var adSession = new AdSession(context);
Note that the parameters for Partner
here should match those you’ve passed in the native layer.
In order to ensure the ad is measured correctly, you should provide a reference to the video element when it is available. The right steps will depend on whether the video element is in the top window or inside a cross-domain iframe.
Simply provide the video element reference using the Context
object you created previously:
const videoElement = document.getElementById(...);
context.setVideoElement(videoElement);
There are two possible scenarios when the video element is in a cross-domain iframe:
Session
and the element are inside the cross-domain iframe.Session
in the top window as well as inside the cross-domain iframe
with the ad element.In the first scenario, you should mark up the iframe with a predefined class name: omid-element
.
This will ensure the OMID JS service running in the top level is able to locate the iframe. The next
step is to indicate the position of the element within the iframe. This can be done by passing the
element’s offset to the Session
instance you created inside the iframe:
// elementBounds is a rect {x, y, width, height} that indicates the position of the video element
// inside the iframe.
adSession.setElementBounds(elementBounds)
In the second scenario, you should pass the reference to the iframe to the Session
and Context
instance in the top level:
const iframeElement = document.getElementById(...);
context.setSlotElement(iframeElement);
And within the iframe, provide the element’s offset to the Session
instance inside the iframe:
adSession.setElementBounds(elementBounds)
In addition, you should also at this time create the event notification objects which you will use to signal the impression and playback events.
const adEvents = new AdEvents(adSession);
const mediaEvents = new MediaEvents(adSession);
Start the session in the native layer before signaling any events in the JS layer.
[self.omidSession start];
When the media has loaded, signal the load event and pass through the following metadata:
adSession.registerSessionObserver((event) => {
if (event.type === "sessionStart") {
// Set the impression/creative type here.
if (event.data.creativeType === 'definedByJavaScript') {
adSession.setCreativeType('video');
}
if (event.data.impressionType === 'definedByJavaScript') {
adSession.setImpressionType('beginToRender');
}
// load event
adEvents.loaded({ isSkippable: skippable, isAutoPlay: autoplay, position: position });
// other event code
...
} else if (event.type === "sessionError") {
// handle error
} else if (event.type === "sessionFinish") {
// clean up
}
});
Note that we are dispatching the event within the session observer callback. This is to ensure that we do not dispatch any events until we’ve received session start. All events in the JS layer must be dispatched only after the session start event. You should also check the event type to ensure you handle each event type appropriately.
When you are ready, signal the impression event using the events object you created in the previous step. For video, an impression is generally accepted to occur when the first frame of the video successfully plays. It should only be dispatched once, and attempting to trigger it multiple times is an error. As noted in the previous step, you must also ensure that you don’t dispatch the impression event until after you’ve received the session start event.
// this should be within the same callback as the load event from the previous step
adSession.registerSessionObserver((event) => {
if (event.type === "sessionStart") {
...
adEvents.impressionOccurred();
...
} else if (event.type === "sessionError") {
// handle error
} else if (event.type === "sessionFinish") {
// clean up
}
})
Note that we are signaling this event from the JavaScript rather than native layer since we designated the JavaScript layer as the impression event owner.
As playback progresses, dispatch notifications for the playback progress events. You should at a minimum signal the following events, as appropriate:
Monitor video playback to signal the progress events at appropriate times (reference bullet list above). Generally the timing of the events corresponds to the industry defined standards VPAID and VAST.
Note that the start event is distinct from others because it requires the duration of the ad as well as the creative volume. Please ensure that video player duration is available at the time you dispatch this event.
if (!isNaN(player.duration)) {
mediaEvents.start(player.duration, player.volume);
} else {
// wait until duration is available to start
}
Note that the mediaPlayerVolume
parameter should only be the volume of the player element. The
device volume is detected by the SDK automatically. The player volume should be normalized between
0 and 1. If the creative volume only supports muted or unmuted, it is sufficient to use the
following for the mediaPlayerVolume parameter:
mediaEvents.start(player.duration, player.muted ? 0 : 1);
With respect to volume changes, you are responsible for notifying only about creative volume
changes. See the note about mediaPlayerVolume
in the section above.
mediaEvents.volumeChange(player.volume);
Finally, you are also responsible for signaling any player state changes. If the player can expand to fullscreen as well as exit fullscreen, you will want to signal these state changes as follows:
// entering fullscreen
mediaEvents.playerStateChange("fullscreen");
// exiting fullscreen
mediaEvents.playerStateChange("normal");
For clarity, when we refer to Native Display, we refer to non-WebView display ad formats where the components of the ad are native (non-HTML) UI elements.
Retrieve the ad response as you normally would. For a native ad the ad response may generally be in the form of a JSON which includes some metadata and URLs to the ad assets.
The steps here are conceptually similar to the same step of Native Video. Unlike video, there is no standard ad response format for display, so you must find an alternative way to determine which measurement resources should be tracking a given ad impression, but, in any case, you will most likely return this information as part of the ad response one way or another.
Create the session in 3 steps.
Please note that each class’s initializer has its own input error checking, so it is important to pass through an error object and validate that each instance initialized successfully.
First, create a context with a reference to the partner object you created in the setup step, the OMID JS, and the measurement resources.
NSError *ctxError;
// contentUrl is the iOS universal link to the screen displaying the ad, nor nil if not applicable.
NSString *contentUrl = ...;
OMIDAdSessionContext *context = [[OMIDAdSessionContext alloc] initWithPartner:partner
script:self.omidJS resources:scripts contentUrl:contentUrl customReferenceIdentifier:nil error:&ctxError];
Then designate which layer is responsible for signaling the impression event. For Native display this will generally be the native layer.
NSError *cfgError;
// Set impression type as appropriate for this integration (begin-to-render, one pixel, etc.).
OMIDImpressionType impressionType = ...;
OMIDAdSessionConfiguration *config = [[OMIDAdSessionConfiguration alloc]
initWithCreativeType:OMIDCreativeTypeNativeDisplay impressionType:impressionType impressionOwner:OMIDNativeOwner mediaEventsOwner:OMIDNoneOwner
isolateVerificationScripts:NO error:&cfgError];
Finally, create the session itself.
NSError *sessError;
self.omidSession = [[OMIDAdSession alloc] initWithConfiguration:config
adSessionContext:context error:&sessError];
See this section of WebView display.
Starting the session does not trigger an impression yet – it only prepares the session for tracking. It is important to start the session before dispatching any events.
Generally you should start the session as soon as you’ve completed the previous steps.
[self.omidSession start];
Dispatch the loaded event to signal that the ad has loaded and is ready to display.
NSError *adEvtsError;
OMIDAdEvents *adEvents = [[OMIDAdEvents alloc] initWithAdSession:omidSession error:&adEvtsError];
NSError *loadedError;
[self.adEvents loadedWithError:&loadedError];
The definition of an impression is generally accepted to be on ad render so this is likely when you will want to dispatch the event. The event should be dispatched only once and attempting to trigger it multiple times is an error.
NSError *impError;
[adEvents impressionOccurredWithError:&impError];
Stop the session when the impression has completed and the ad will be destroyed. Note, that after you’ve stopped the session it is an error to attempt to start it again or trigger an impression on the finished session.
[self.omidSession finish];
self.omidSession = nil;
Please follow the instructions below for how to correctly track a native video ad.
Retrieve the ad response as you would normally. Generally this will be a VAST document.
In this step, you will determine which measurement resources should be tracking the ad. Overall the instructions are similar to this step of the WebView Video instructions. As before, we will assume that the ad response contains one or more Verification nodes as specified in VAST 4.1.
First we create an array to hold the scripts:
NSMutableArray *scripts = [NSMutableArray new];
Then parse each Verification node and add the associated OMIDVerificationScriptResource
to the
array of resources:
NSURL *url = [NSURL URLWithString:stringUrl];
NSString *vendorKey = ...;
NSString *params = ...;
[scripts addObject:[[OMIDVerificationScriptResource alloc] initWithURL:url vendorKey: vendorKey
parameters:params]];
See this step of the Native Display implementation instructions.
Note that you will want to specify a video event owner that is different from the example provided with native display.
NSError *cfgError;
// Set impression type as appropriate for this integration (begin-to-render, one pixel, etc.).
OMIDImpressionType impressionType = ...;
OMIDAdSessionConfiguration *config = [[OMIDAdSessionConfiguration alloc]
initWithCreativeType:OMIDCreativeTypeVideo impressionType:impressionType impressionOwner:OMIDNativeOwner mediaEventsOwner:OMIDNativeOwner
isolateVerificationScripts:NO error:&cfgError];
See this step of WebView Display.
You will use these instances to signal impression and playback events, so you will want to hold on to them after you’ve created them.
// to signal impression event
NSError *aErr;
self.omidAdEvents = [[OMIDAdEvents alloc] initWithAdSession:self.omidSession error:&aErr];
// to signal media events
NSError *vErr;
self.omidMediaEvents = [[OMIDMediaEvents alloc] initWithAdSession:self.omidSession error:&vErr];
Be sure to check the errors and ensure the event instances were created properly before using them subsequently. If there was an error, they will be nil.
As noted previously, signaling the start of the session does not yet trigger the impression. This only prepares the session for tracking. You will want to do this as close to completing the previous steps as possible.
[self.omidSession start];
Dispatch the loaded event to signal that the ad has loaded and is ready to play. Please reference
the OMIDVASTProperties
header for the appropriate values.
OMIDVASTProperties vastProperties = ...;
[self.omidAdEvents loadedWithVastProperties:vastProperties];
Signal the start of the impression. Generally this should occur when the first frame of the video successfully plays.
NSError *impError;
[self.omidAdEvents impressionOccurredWithError:&impError];
As playback progresses, dispatch notifications for the playback progress events. You should at a minimum signal the following events, as appropriate:
Monitor video playback to signal the progress events at appropriate times (reference bullet list above). Generally the timing of the events corresponds to the industry defined standards VPAID and VAST.
Note that the start event is distinct from others because it requires the duration of the ad as well as the creative volume:
[self.omidMediaEvents startWithDuration:MEDIA_DURATION mediaPlayerVolume:PLAYER_VOLUME_0_TO_1];
With respect to volume changes, you are responsible for notifying only about creative volume changes. Device volume is detected by the SDK automatically.
[self.omidMediaEvents volumeChangeTo:PLAYER_VOLUME_0_TO_1]
Finally, you are also responsible for signaling any player state changes. If the player can expand to fullscreen as well as exit fullscreen, you will want to signal these state changes as follows:
// enter fullscreen
[self.omidMediaEvents playerStateChangeTo:OMIDPlayerStateFullscreen];
// exit fullscreen
[self.omidMediaEvents playerStateChangeTo:OMIDPlayerStateNormal];
Special note for MPMoviePlayerController: if your playback happens via a fullscreen
MPMoviePlayerController
instance, you must ensure that you dispatch the fullscreen event to ensure
that viewability is tracked correctly.
Stop the session on completion or termination of ad playback.
[self.omidSession finish];
self.omidSession = nil
The setup for an audio ad is similar to the corresponding video ad, with minor exceptions…
Validating your steps is an important part of the integration process. Follow the instructions here.
This section is directed at ads SDKs that will want to distribute their SDK after integrating the OM SDK in order to provide measurement across their network of publishers. While the ads SDK may very well choose to distribute the OM SDK as a separate component, this will generally provide a poorer usability experience compared to embedding the OM SDK within. The following instructions detail how to embed the OM SDK when possible. Note that the OM SDK does use namespacing so that it can be independently included within multiple ads SDKs in a single app without issues.
The SDK can be linked statically to your iOS project. You can choose to integrate either a static library or a static “framework”.
OM SDK is available as two different XCFramework bundles. 1) A dynamic XCFramework, and 2) A static XCFramework. The XCFramework integration options include both device and simulator (including arm64 simulator) architecture slices and is the most optimal solution for this integration option. For most Ad SDK build and distribution processes, the static XCFramework option may be the best choice. Integrating the Static XCFramework into your Ad SDK does require a few additional considerations noted below
In order to integrate the Static XCFramework into your Ad SDK, you will need to perform the following:
1) Drag and drop the XCFramework into the Frameworks and Libraries
section of your project and ensure Do Not Embed
is selected.
2) Ensure your Library Search Paths
includes a path to the OMSDK XCFramework
3) In order to use the OMSDK APIs in Objective C files you will need to #import "OMIDImports.h"
where appropriate
If you need to use the OMSDK APIs in any Swift files in your Ad SDK and you plan to integrate OMSDK via the static XCFramework option, you will also need to perform the following:
4) In order for the the Objective C headers to be exposed to Swift, you will need to place the OMSDK headers in the public Headers build phase. The headers can be found inside the XCFramework and since the headers for each slice are the same, you may choose to link the simulator or device headers. When linking the headers, ensure Copy items if needed
is not selected.
5) Now that these headers are available, you may #import "OMIDImports.h"
in your framework’s header file (typically <MyFramework.h>
)
6) When performing step 5, the OMSDK headers will be exposed to the down stream host app integrating your Ad SDK. In order to avoid this, Ad SDKs should include a preprocessor macro that will only be enabled within the AdSDK. As an example, if the Ad SDK has defined a preprocessor macro named MYSDK_INTERNAL
, your framework header file would look like this:
#ifdef MYSDK_INTERNAL
#import "OMIDImports.h"
#endif
FAQ available here
Kill switch guidance available here