iOS Integration

Why use EMMA SDK in your APP?

Download and basic integration

Acquisition Integration

Behavior Integration

Push Notifications Integration

Messaging Integration

Add Rate Alert

Debugging your code

Deploying your App to Appstore

 

Why use EMMA SDK in your App?

EMMA SDK offers an unique functionality with the whole user tracking of your App. We have developed a robust, secure and light SDK with more than 2.000 Millions of installs until the day. And, of course, easy to be integrated.

EMMA can track the install origin (including Facebook, Twitter & Google), sessions, user events, location, ... with a powerful segmentation unit to evaluate the ROI and your user retention engaging them thanks to our communication tools, Push and In-app Messaging. 

EMMA iOS SDK is compatible with all devices (iPhone, iPod, iPad) with iOS 8 or over.

 

Download and basic integration 

 

Download EMMA iOS SDK 

See Changelog

Download through CocoaPods.

You can get the last EMMA version through CocoaPods. For that:

  1. Install CocoaPods using
    gem install cocoapods
  2. If it is the first time using you can optionally execute
    pod setup
    to download the repository with all “specs" and check them in a local environment. This will directly create a copy of the repository in GitHub.
     
  3. Create a file in your Xcode project called
    Podfile
    Just next add the line
    pod 'eMMa'
  4. Finally, run
    pod install
    in your Xcode project directory.

    One it is done, CocoaPods should download and install the EMMA library and create a new file .xcworkspace. Finally, open this workspace in Xcode.

Manually download

You can get latest EMMA version here. Once download you need add it to your Xcode project.

In Xcode, go to General >> Embedded Binaries >> Click + to add a new binary.

Click Add Other and add EMMA_iOS.framework to your project.

In Xcode, go to General >> Linked Frameworks and Libraries >> Click + to add a new library.

Click Add Other and add the EMMA_iOS.framework

Select Status of EMMA_iOS.framework as Optional.

 EMMA_1.png

 

 

Including SDK in your App (Mandatory)

  • SDK & Install (Minimum requirement to track) 

This guide allows you to track organic and non-organic installs of your App.

Add following files and parameters to your app:

  • Add the following frameworks to your project:
    • CoreLocation.framework
    • AdSupport.framework

If you are having problems executing this lib you should delete all weak-links from your libraries. Also in Other Linker Flags, set up these options -ObjC - all_load:

Note: EMMA SDK supports BITCODE. 

 

Running the SDK & Install Event (Minimum Requirement)

NOTE: This is the minimum requirement to start tracking your App installs.

Add EMMA to your Application Delegate.

#import <EMMA_iOS/EMMA.h>

In your Application Delegate add the following code to the theapplicationdidFinishLaunchingWithOptions:

[EMMA startSession:@"YOURSESSIONKEY"];

You can obtain your SessionKey by adding your app in My Account following these instructions.

Optional

In some cases, It is necessary to change the API EMMA URL (e.g proxies), this requires add the next method before starteMMaSession:

[EMMA setAPIeMMaURL:@"https://www.your_proxy_url.com/"];

 

Update to version 4

When upgrade to version 4, is mandatory do some minor changes.

NOW EMMA is a Framework

SDK changes to a Framework instead of a static library, you need to change how to include EMMA headers.

Replace all ocurrences of

#import <eMMa/eMMa.h>

by

#import <EMMA_iOS/EMMA.h>

 

Acquisition Integration

In the Acquisition section you can have the data of all the campaigns managed with EMMA.

Here is the specific documentation so you can manage your Facebook and Twitter campaigns and also the documentation about how to integrate the functionality of Powlink.

 

Tracking Facebook App Installs and Twitter App Promotion

EMMA is 100% integrated with Facebook and Twitter for tracking via AppsFlyer. You will be able to track all the App Installs sources in our Dashboard with no need to integrate Facebook or Twitter SDKs.

Add the following: (available here)

  • AppsFlyerTracker.h
  • libAppsFlyerLib.a

If your project includes CocoaPods you can integrate AppsFlyer in the following way:

pod ‘AppsFlyerFramework’ 

To initialize on the application please add the following code to yourdidFinishLaunchingWithOptions function:

[AppsFlyerTracker sharedTracker].appsFlyerDevKey = @"EMMASOCIALKEY";
[AppsFlyerTracker sharedTracker].appleAppID = @"Your_iTunes_APP_ID";

Add the following code to your AppDelegate.m file atapplicationDidBecomeActive function:

[[AppsFlyerTracker sharedTracker] trackAppLaunch];

The EMMA Social Key you have to introduce is the ID to follow the Facebook and Twitter campaigns.

To get the EMMA Social Key you have to follow these steps: 

1.  Login EMMA website and go to My Account > Configuration > Edit app.

EMMA_2.png

2.  Go to Media Source Settings and fill the App information:  

EMMA_3.png

 

To get the App Store ID you can copy the ID of the AppStore link, like this example:

EMMA_4.png

To get Google Play ID you can copy the ID of the GooglePlay link, like this example:

EMMA_5.png

To get the Facebook App ID visit this article to know how to do it.

4.  Select the Submit option to keep the changes. 

5.  Send us an email to support@emma.io and we will send youthe EMMA Social Key. You will receive an e-mail with your key. 

6.  If everything is set up correctly, you will find the Facebook and Twitter campaigns in the Acquisition > AppTracker. Once you start to run the campaigns, the data will automatically enter in EMMA.

EMMA_6.png

 

 

Powlink Integration

To support the Powlink in iOS, first of all, it is necessary to set up in the EMMA Dashboard the subdomain in powlink.io that your App will use, and you have to fill the Apple Store Bundle ID and the Apple Team ID. You can configure this in My Account, in the option of the Media Source Settings.

EMMA_7.png

Next, you have to create a Provisioning Profile to your App, in your Apple's Developer Center. You must activate the Associated Domains for your App, download the Provisioning Profile and install it in Xcode. 

Once you know your Powlinks subdomain, in the Xcode proyect of your App, you have to select the target and in the Capabilities section you have to activate the Associated Domains option.

EMMA_8.png

When you activate this option, Xcode will let you choose an Apple Team ID, and when you choose it, you will can add the domains that your app will run. You must add the powlink.io subdomain that you configure in the EMMA dashboard, preceded of "applinks:"

applinks:mysubdomain.powlink.io

EMMA_9.png

Now you only have to manage the Powlink inside your App, and to do that you have to implement the method application:continueUserActivity:restorationHandler: in your AppDelegate. If you process the paths of the received Powlinks, you can launch several sections of your App.  

-(BOOL)application:(UIApplication *)application continueUserActivity:(NSUserActivity *)userActivity restorationHandler:(void (^)(NSArray * restorableObjects))restorationHandler{
    
    if ([userActivity.activityType isEqualToString: NSUserActivityTypeBrowsingWeb]) {
        NSURL *url = userActivity.webpageURL;
        //Process url. Manage Powlink path
    }
    return YES;
}

 

Behavior Integration

With EMMA you can do a complete integration of the SDK that allows you to know the location of your users, how they register in your App, how many transactions they do and even their own characteristics. This is all the information of your users that you will get in the Behavior section.

The following articles specify the integration of the measurement of each of these aspects:

 

Tracking Events

In the EMMA platform you have the option to measure between two types of events. Those that the platform includes by default and the Custom events that you want to integrate according to the structure of your application.

Default events

The EMMA default events allow you to know the Leads (registered users outside the app, old registers and any tags that you want to link to a user in order to be able to create custom segments) and the Login (users that have logged in the App through an existing mail or through some social platform).

Follow these steps to do this integration:

Sign Up/Register/Leads

[EMMA registerUser:USER_ID forMail:MAIL]

RegisterUser measure a complete register of a device in the EMMA data base to an user_id (NSString) and an email (NSString)

Login

[EMMA loginUser:USER_ID forMail:MAIL]

LoginUser collects the user data in the EMMA database to an user_id (NSString) and an email (NSString). When the user logs in, you can use [eMMa loginDefault] to collect another user Sign In with the same data.

Custom events

With EMMA you can measure every user action like a custom event: 

[EMMA trackEvent:@"EVENT_TOKEN"];

Use trackEvent to count the number of times that certain events happen during an App session.

This information can be useful for measuring how often users perform different actions, for example. Your application is currently limited to counting occurrences for 30 different event ids.

You can obtain the EVENT_TOKENS in the EMMA platform. If an non-existing token is sent, EMMA will return an error. 

Tracking purchases

EMMA allows you to track every purchase of your App.

Start Order

[EMMA startOrder:YOUR_ORDER_ID customerId:CUSTOMER_ID totalPrice:TOTAL_PRICE coupon:COUPON extras:EXTRAS currencyCode:CURRENCY_CODE]

Starts an order for adding products. You can pass the following parameters:

YOUR_ORDER_ID

: NSString with your order id

CUSTOMER_ID

: NSString with your Customer ID. If not passed, EMMA will use the logged one (if exists).

TOTAL_PRICE

: Float with your total price.

COUPON

: NSString with your coupon if needed.

EXTRAS

: NSDictionary with until 20 extra parameters, category… Each extra parameter can be used later to filter in EMMA.

CURRENCY_CODE

: NSString of a valid Currency Code (EUR,USD,..) If the currency code is not valid EUR currency will be taken

 You can use abbreviated methods if you don’t need all parameters, you can find them at the end of the document or in eMMa.h.

 

Add Products to the order

[EMMA addProduct:PRODUCT_ID name:PRODUCT_NAME qty:QUANTITY price:PRICE extras:YOUR_EXTRAS]

Adds products to your current started order. Always startOrder should be called before. You can pass the following parameters: You can pass the following parameters:

PRODUCT_ID

: NSString with your product id.

NAME

: NSString with your product name.

QTY

: Float with your product qty.

PRICE

: Float with product price.

EXTRAS

: NSDictionary with until 20 extra parameters, like currendy, category, …

 

Track Order

[EMMA trackOrder]

Track the current order. It should be called after startOrder and after being all cart products added.

The sequence of tracking order in EMMA is always startOrder>addProduct(*distinct products)>trackOrder

 

Cancel Order

[EMMA cancelOrder:ORDER_ID]

Cancel the order referenced by an order id. If your e-commerce allows canceling orders this method updates the purchases data with the cancelled orders.

 

Tracking User Tags

[EMMA trackExtraUserInfo:YOUR_NSDICTIONARY]

This method updated or includes extra parameters in order to obtain a better segmentation to the Users with tag filter. It can be used in the register, in the login or in any app section where is the user information. 

If you want to use the EMMA RULE On his Birthday you have to send the birthday date with the tag method in this format:

Name: BIRTHDAY

Value: YYYY-MM-DD

 

Tracking location

If your app has the permission required you can track the location of each device using the next code:

[EMMA trackLocation];

 

Get User Info

Get User ID

[EMMA getUserID:^(id result) {
NSLog(@"ID:%@",result); // Your code
}];

This method gives back the EMMA ID like a NSString. This ID is unique for each user and it can be used to do the segmentation to send communications. 

Get User Info

[EMMA getUserInfo:^(id result) {
NSLog(@"Info:%@",result); // Your code
}];

This method returns all the user information in a JSON format. The JSON includes the following parameters, all of them in NSDictionary format with all the NSString values:

id The same unique ID that appears in the method (eMMa.getUserID)
udid Unique ID for app install (usually IDFA/AAID)
emma_build EMMA version"]">Identify the EMMA SDK version used
email User email if the register or the login are integrated. 
customerid ID assigned tho the user after he does the register or the login
created_at At which time the user has been created
updated_at Last time that the user update the information
registred_at At which time the user registered
fisrt_login At which time the user made his first login
last_login At which time the user made his last login
device Device of the user
app_version Version of the app
os_version Version of the operating system
rated If the user has punctuated the app
token Push identifier (token)
inactive If the user is inactive to receive the push notifications 
latitude  Latitude of the user in case the geolocation is allowed and measured. 
longitude  Longitude of the user in case the geolocation is allowed and measured. 
emma_city  City of the user in case the geolocation is allowed and measured. 
emma_country  Country of the user in case the geolocation is allowed and measured.
emma_state  State of the user in case the geolocation is allowed and measured.  
emma_device_id Unique ID of the device.
emma_referrer_id Campaign ID from which the user comes (if he come from an  EMMA AppTracker campaign)
loyal_user_at
At which time the user became in Loyal User 
loyal_buy_at At which time the user became in Loyal Buyer 
emma_num_sessions Number of sessions (app openings) of the user
last_session_at User last session (app openings)
tag_name Name and value of all the user tags

Also, if the user comes from a Facebook campaign, it will be included the following parameters:

eat_sub1 Name of the app
eat_sub2 "facebook" (Fixed value)
eat_sub3 "Facebook's Campaign" (Fixed value)
eat_sub4 "cpi" (Fixed value)
eat_sub5 Facebook name campaign
eat_sub6 Facebook campaign ID 
eat_sub7 Name of the Adgroup in Facebook
eat_sub8 Adgroup ID in Facebook
eat_sub9 Name of the Adset in Facebook
eat_sub10 Adset ID in Facebook

In case that the user comes from the AppTracker, the JSON could include the following custom parameters.

If you want to use this method, it is necessary to contract the Raw Export feature.

 

Push Notifications Integration

NOTE: To differentiate a notification from our push system to other systems, the payload sent by EMMA contains a flag called "eMMa".

EMMA allows you to add a very powerful Push system easy to integrate. The platform also allows you to send info through Push Notifications and do whatever you want inside your app with it.

In order the Push Notifications work correctly in your app, you must integrate the following steps: 

 

iOS Push Certificates

1.  First step is to request a certificate from a certificate authority. Open up Keychain from Applications > Utilities.

EMMA_10.png

2.  Then enter your email and add the name for the new certificate. Select “Saved to disk’.

EMMA_11.png

3.  This will generate a file called “CertificateSigningRequest.certSigningRequest”. You now need to upload this in your Apple Developer account.

    • Go to iOS Provisioning Portal
    • App IDs
    • Click ‘Configure’ beside your app.
    • Click ‘Enable for Apple Push Notification service’.
    • Click ‘Configure’ button next to Development.
    • Click ‘Continue’
    • Upload the ”CertificateSigningRequest.certSigningRequest” file.

4.  This will generate an aps_developer_identity.cer certificate. Double click on it to load it into your Keychain.

5.  Repeat for production: You will now need to regenerate a development Provisioning Profile for your app because the current one you won’t be aware that of the push notification capabilities.

    • Go to Provisioning in the sidebar and click Edit, then Modify next to your app. You need to change something for it to regenerate a new provisioning profile, for example, you can just deselect one of your development devices.
    • Then click Submit.
    • Refresh the page and your Provisioning Profile should be ready for download.
    • Now go into Organizer in Xcode and delete the old Provisioning Profile. Drag your new profile into Xcode to install it.
    • You will now need to change the coding signing entries in Build Settings to reflect your new Provisioning Profile. Make sure you change the code signing settings under “Targets” as well as Project.
    • Finally, you need to generate two p12 for each certificate. Go to Keychain and look up for your Apple Push Development Certificate.
    • Then, right-click, export. You should put a password, this password needs to be provided with your p12 for installing on EMMA server.
    • Click the right arrow and repeat the process for your private key. Now you will have two p12, one for the certificate and one for your key.
    • Repeat it for production using the same password 

6.  Login EMMA website and go to My Account > Configuration > Edit app.

EMMA_12.png

 

7.  Go to the configuration O.SiOS Push certificates section to upload your certificates. Select Upload certificates to load your Dev y Prod certificates (archivo .p12) with the passwords and select Submit to save the changes: 

EMMA_13.png

 

 

 

Using EMMA Push Notifications

 Once you upload your iOS Certificates, you can start to integrate the Push Notifications:

[EMMA startPushSystem:LAUNCH_OPTIONS]

Starts push system from

applicationDidFinishLaunching

You need to pass method’s launchOptions after starting EMMA session.

LAUNCH_OPTIONS

: NSDictionary received from DidFinishLaunching

You can set the Push options with the following methods:

[EMMA setPushSystemDelegate:YOUR_DELEGATE]

: NSObject that will obtain push info sent through EMMA dashboard. It's mandatory only if you want to do extra stuff in your app depending on the Push received.

[EMMA setPushSystemOptions:(eMMaPushSystemOptions)options]

: eMMaPushSystemDisableAlert -> Disables showing alert messages for new Push Notifications received.

To add notification methods (iOS 10 only) we have to implement the UserNotifications framework delegate:

Swift

import UserNotifications 

@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate,UNUserNotificationCenterDelegate {
...
}

Objective-C

#import <UserNotifications/UserNotifications.h>

@interface AppDelegate : UIResponder <UIApplicationDelegate,UNUserNotificationCenterDelegate>
@end

To add the delegate to the SDK:

Swift

 EMMA.setPushNotificationsDelegate(self)

Objective-C

 [EMMA setPushNotificationsDelegate:self];

It is also necessary to add this methods in your AppDelegate:

Swift

func application(_ application: UIApplication, didReceiveRemoteNotification userInfo: [AnyHashable : Any], fetchCompletionHandler completionHandler: @escaping (UIBackgroundFetchResult) -> Void) {
	EMMA.handlePush(userInfo)
}
	
func application(_ application: UIApplication, didRegister notificationSettings: UIUserNotificationSettings) {
	application.registerForRemoteNotifications()
}
	
func application(_ application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) {
	EMMA.registerToken(deviceToken)
}
	
func application(_ application: UIApplication, didFailToRegisterForRemoteNotificationsWithError error: Error) {
	NSLog("Error registering notifications " + error.localizedDescription);
}
	
@available(iOS 10.0, *)
func userNotificationCenter(_ center: UNUserNotificationCenter,  willPresent notification: UNNotification, withCompletionHandler   completionHandler: @escaping (_ options:   UNNotificationPresentationOptions) -> Void) {
    EMMA.handlePush(notification.request.content.userInfo)
completionHandler([.badge, .sound]) } @available(iOS 10.0, *) func userNotificationCenter(_ center: UNUserNotificationCenter, didReceive response: UNNotificationResponse, withCompletionHandler completionHandler: @escaping () -> Void) { EMMA.handlePush(response.notification.request.content.userInfo)
completionHandler() }

Objective-C

 -(void) application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken {
    [EMMA registerToken:deviceToken];
}

- (void)application:(UIApplication *)application didReceiveRemoteNotification:(nonnull NSDictionary *)userInfo fetchCompletionHandler:(nonnull void (^)(UIBackgroundFetchResult))completionHandler{
    [EMMA handlePush:userInfo];
}


- (void)application:(UIApplication *)application didRegisterUserNotificationSettings:(UIUserNotificationSettings *)notificationSettings
{
    //register to receive notifications
    [application registerForRemoteNotifications];
}

-(void)application:(UIApplication *)application didFailToRegisterForRemoteNotificationsWithError:(NSError *)error {
    NSLog(@"Error: %@", error);
}


#ifdef __IPHONE_10_0
-(void)userNotificationCenter:(UNUserNotificationCenter *)center willPresentNotification:(UNNotification *)notification withCompletionHandler:(void (^)(UNNotificationPresentationOptions options))completionHandler{
    [EMMA handlePush:notification.request.content.userInfo];
completionHandler(UNAuthorizationOptionSound | UNAuthorizationOptionBadge); } -(void)userNotificationCenter:(UNUserNotificationCenter *)center didReceiveNotificationResponse:(UNNotificationResponse *)response withCompletionHandler:(void(^)())completionHandler{ [EMMA handlePush:response.notification.request.content.userInfo];
completionHandler(); } #endif

iOS 10 changes

For registering token is necessary enable Push Notifications in Capabilities.

EMMA_14.png

Push Tag

[EMMA checkPushTag:(NSString *)pushTag withBlock:(EMMAPushTagBlock)block]

EMMAPushTagBlock definition

typedef void(^EMMAPushTagBlock)(NSString* pushTag, NSString* pushTagID);

Example

[EMMA checkPushTag:@"Account" withBlock:^(NSString *pushTag, NSString *pushTagID) {
//Redirects to Accounts tab
[self performSegueWithIdentifier:@"AccountSegue" sender:self];
}];

By the other hand, you now can keep track of all messages sent by Push and show them in a custom alert or more than once. In order to do so you need to add this method in your delegate specified on eMMaPush Message.

Push Message

-(void)pushMessage:(NSString*)pushMessage{
//Do whatever you want with pushMessage
}

You can use abbreviated methods if you don’t need all parameters, you can find them in EMMA.h.

Rich Push, custom sounds in push notifications

To use custom sounds in notifications you send with EMMA, you need to add your custom sounds in .caf format into the main bundle or into Library/Sounds/ of your app. Remember use the same name for sound files in iOS and Android.

Rich Push URL using DeepLinking

You can redirect your push notification openings to a section into your app. For that you can use a structure like this:

scheme://host/page1/page2/page3

In order to make your app available to receive a scheme deep link:

1) Go to Xcode > App Target > Info > URL Types and put your custom scheme.

EMMA_15.png

 2) Add this method to your AppDelegate.m file:

-(BOOL)application:(UIApplication *)application openURL:(NSURL *)url sourceApplication:(NSString *)sourceApplication annotation: (id)annotation{ 
[EMMA handleLink:url];
//Manage by url
return YES;
}

 

Add the handleLink method for internal EMMA managements. For example to run Re-Engagement campaigns.

iOS Rich Push Notification

iOS 10 has introduced Rich Push Notifications, which allow you to add image, video, audio or gif attachments to your push notifications.

Rich Push Notifications are enabled via a Notification Service Extension, a separate and distinct binary embedded in your app bundle. Prior to displaying a new push notification, the system will call your Notification Service Extension to allow you to modify the payload as well as add media attachments to be displayed.

Create Notification Service Extension

To create a Notification Service Extension in your project, in Xcode, select File -> New -> Target and choose the Notification Service Extension template.

EMMA_16.png

EMMA_17.png

You can name the extension as you wish: we will name it RichPushExtension for this tutorial. Make sure you embed your new extension in your app!

EMMA_18.png

 

When you press Finish you will be asked to activate the extension, click Activate to finish.

                        EMMA_19.png

 

At the end of this step, three new files will be created under the extension name directory (RichPushExtension in our case): NotificationService.h, NotificationService.m and Info.plist.

EMMA_20.png

Then make sure that the Push Notifications Capability is enabled for the Notification Service Extension created. Select your new extension (RichPushExtension), select Capabilities and turn on Push Notifications.

EMMA_21.png

 

Code Changes

Open NotificationService.m. Remove all code from the editor and copy-paste the code below:

#import "NotificationService.h"

@interface NotificationService ()

@property (nonatomic, strong) void (^contentHandler)(UNNotificationContent *contentToDeliver);
@property (nonatomic, strong) UNMutableNotificationContent *bestAttemptContent;

@end

@implementation NotificationService

- (void)didReceiveNotificationRequest:(UNNotificationRequest *)request withContentHandler:(void (^)(UNNotificationContent * _Nonnull))contentHandler {
    self.contentHandler = contentHandler;
    self.bestAttemptContent = [request.content mutableCopy];
    
    // Check for rich attachment
    NSDictionary *userInfo = [self.bestAttemptContent userInfo];
    if (userInfo == nil) {
        [self taskComplete];
        return;
    }
    
    NSString *urlImagePush = [userInfo objectForKey:@"media-attachment"];
    if (urlImagePush == nil) {
        [self taskComplete];
        return;
    }
    
    NSString *typeImage = [self fileExtensionForMediaUrl:urlImagePush];
    if (typeImage == nil) {
        [self taskComplete];
        return;
    }
    
    // load the attachment
    [self loadAttachmentForUrlString:urlImagePush
                            withType:typeImage
                   completionHandler:^(UNNotificationAttachment *attachment) {
                       if (attachment) {
                           self.bestAttemptContent.attachments = [NSArray arrayWithObject:attachment];
                       }
                       [self taskComplete];
                   }];
    
}

- (void)serviceExtensionTimeWillExpire {
    // Called just before the extension will be terminated by the system.
    // Use this as an opportunity to deliver your "best attempt" at modified content, otherwise the original push payload will be used.
    [self taskComplete];
}

- (void)taskComplete {
    self.contentHandler(self.bestAttemptContent);
}

- (void)loadAttachmentForUrlString:(NSString *)urlString withType:(NSString *)type
                 completionHandler:(void(^)(UNNotificationAttachment *))completionHandler  {

    __block UNNotificationAttachment *attachment = nil;
    NSURL *attachmentURL = [NSURL URLWithString:urlString];
    
    NSURLSession *session = [NSURLSession sessionWithConfiguration:[NSURLSessionConfiguration defaultSessionConfiguration]];
    [[session downloadTaskWithURL:attachmentURL
                completionHandler:^(NSURL *temporaryFileLocation, NSURLResponse *response, NSError *error) {
                    if (error != nil) {
                        NSLog(@"NSE ERROR. %@", error.localizedDescription);
                    } else {
                        NSFileManager *fileManager = [NSFileManager defaultManager];
                        NSURL *localURL = [NSURL fileURLWithPath:[temporaryFileLocation.path stringByAppendingString:type]];
                        [fileManager moveItemAtURL:temporaryFileLocation toURL:localURL error:&error];
                        
                        NSError *attachmentError = nil;
                        attachment = [UNNotificationAttachment attachmentWithIdentifier:@"" URL:localURL options:nil error:&attachmentError];
                        if (attachmentError) {
                            NSLog(@"NSE ERROR. %@", attachmentError.localizedDescription);
                        }
                    }
                    completionHandler(attachment);
                }] resume];
}

- (NSString *)fileExtensionForMediaUrl:(NSString *)url {
    NSString *ext = nil;
    //EMMA always send pngs without extension in filename
    if ([url rangeOfString:@"emma.io"].location != NSNotFound) {
        ext = @"png";
    } else if ([url rangeOfString:@"jpg"].location != NSNotFound) {
        ext = @"jpg";
    } else if ([url rangeOfString:@"jpeg"].location != NSNotFound) {
        ext = @"jpg";
    } else if ([url rangeOfString:@"png"].location != NSNotFound) {
        ext = @"png";
    } else if ([url rangeOfString:@"gif"].location != NSNotFound) {
        ext = @"gif";
    }
    
    if (ext != nil) {
        ext = [@"." stringByAppendingString:ext];
    }
    return ext;
}

@end

 

Messaging Integration

Messaging includes seven different communicative formats that you can integrate to impact your users:

In many of these communicative formats you can delete the redirection url's that you want to introduce. With the EMMA Whitelist functionality you can define what content you want to be displayed in the scheduled webviews.  

Review Campaign 

[EMMA inAppMessage: (InAppType) type andRequest:(EMMAInAppRequest *) request];

Use inAppMessage to confirm whether the Campaign created on the EMMA platform corresponding to the specified Type is displayed.

The following attributes can be defined in EMMAInAppRequest:

EMMAInAppRequest* request = [EMMAInAppRequest new];
request.nateiveAdTemplateId = @"nativeAdTemplateId";
request.label = @"label";
request.inAppMessageId = @"inAppMessageId";

*The following steps will specify the attributes to be used for each type of campaign

Campaign with tag

EMMAInAppRequest* request = [EMMAInAppRequest new];
request.label = @"label";
[EMMA inAppMessage: AdBall andRequest: request];

If you wish you can pass a custom String that will tag the Campaign in case you use more than one Campaign of the same type in your app and you need to distinguish them.

Add interface

[EMMA addInAppDelegate:(id<EMMAInAppMessageDeletage>) delegate];
EMMAInAppRequest* request = [EMMAInAppRequest new];
request.label = @"label";
[EMMA inAppMessage: AdBall andRequest: request];

If you wish you can add an interface (or several) to receive the different events related to the Campaigns of your app.

 

Using EMMA Banner

EMMA Banner lets you show a banner on your app with promotional info. The banner will be shown and hidden depending on your dashboard configuration. It is a communication that allows the user to display an external webview with HTML content or redirect to another application tab (via deeplink)

EMMA_22.png

To display the Banners in your app you need at least to integrate the first method described below:

IMPORTANT: It is recommended to be called inside.

viewDidLayoutSubviews

Check Banner

[EMMA inAppMessage: Banner andRequest: nil];

Use checkForBanner in order to check if show Banners added on EMMA dashboard. YOUR_VIEWCONTROLLER is your top view controller where you decide how you want to show your ViewController.

Banner auto Creation

[EMMA setBannerAutoCreation:(BOOL) autoCreation];

Sets the parameter to autocreate the Banner when coming from background, if YES, it will create the Banner when coming from background automatically.

Banner with label

EMMAInAppRequest* request = [EMMAInAppRequest new];
request.label = @"label";
[EMMA inAppMessage: Banner andRequest: request];

Use checkForBanner in order to check if the shown Banner was added on EMMA dashboard. YOUR_VIEWCONTROLLER is your top view controller where do you want to show your ViewController. If you want you can pass a custom NSString that labels the Banner in case you use more than one Banner on your app and you need to distinguish between them. The block is invoked when the banner is displayed or when no banners available.

NOTE: You cannot use autocreation parameter using label because labeled Banner are attached to a specific part of the app, not at the startup.

 

Using EMMA Startview

EMMA StartView lets you show HTML info on your app startup via a webview.

EMMA_23.png

In order to allow them in your app you need at least to implement the first method.

StartView will be presented in a:

UIViewController

By default, EMMA will use:

[[[UIApplication sharedApplication] keyWindow] rootViewController]

but you can set your own EMMA RootViewController using:

[EMMA seteMMaRootViewController:YOUR_VIEW_CONTROLLER]

If both are nil, StartView won’t be shown.

Now StartView is implemented by default when starting EMMA Session, but it can be configured with the following methods:

StartView Options

[EMMAsetStartViewOptions:(EMMAStartViewOptions)options];

List of options:

eMMaStartViewManualCall

Sets the startView in manual mode. Useful for using StartViews with labels. Also disables check for StartView returning from background

eMMaStartViewOpenLinksInSafari

Sets the Startview redirection in a browser independently. 

Use this structure in case you want to use the ManualCall and the OpenLinksInSafari at the same time:

[eMMa setStartViewOptions:eMMaStartViewOpenLinksInSafari|eMMaStartViewManualCall]; 

 

 

Using EMMA Adball

EMMA AdBall lets you show an AdBall Icon on your app that you can move freely around the app view and also hide it. If you press the AdBall a popup with HTML content will be shown.

EMMA_24.png

In order to allow them in your app you need at least implement the first method. It can be configured with the following methods.

Check AdBall

[EMMA inAppMessage: AdBall andRequest: nil];

Use checkForAdBall in order to check if show AdBalls added on EMMA dashboard.

Check if Adball is showing

[EMMA isAdBallShowing];

Use for check if AdBall is showing on device screen. Return BOOL true if is on screen.

 

Using EMMA Dynamic Tab

EMMA tabBar View (DynamicTab) allows you to show HTML information in a new section of your app (only in case that you have a TabBar in the app). The new TabBar Item can be created locally or in the EMMA platform.

EMMA_25.png

If it is done in both ways, the dynamic TabBar Item created directly in EMMA will prevail.

To enable this feature in your app you will need to implement at least the first method. It can be configured following this indications:

[EMMA inAppMessage: PromoTab andRequest: nil];

DynamicTab TabController

[EMMA setPromoTabBarController:(UITabBarController*)tabBarController];

Set the UITabBarController where you will find the DynamicTab. If you don't define any UITabBarController, the DynamicTab will not be executed. 

Dynamic Tab Index

[EMMA setPromoTabBarIndex:(NSInteger) index];

Set the índex where the DynamicTab will be displayed if it is not defined in EMMA platform. 

Dynamic Tab TabBarltem

[EMMA setPromoTabBarItem:(UITabBarItem*) tabBarItem];

Set the UITabBarItem to display it if it is not defined in EMMA platform. 

Dynamic Tab AutoCreation

[EMMA setPromoTabBarAutoCreation:(BOOL) autoCreation];

Set the auto-creation parameter of the TabBar when the app is opened from the background. If so, it will automatically create a DynamicTab when the user comes from the background. 

New and important

The TabBar ítem index and the item itself can be specified on the EMMA platform. As we indicated before, the configuration in EMMA will always prevail over the local configuration. 

 

Using EMMA Strip

EMMA Strip lets you show a Strip above the status bar with a message for your customers. It can be placed on any screen of the app.

EMMA_26.png

Check Strip

[EMMA inAppMessage: Strip andRequest: nil];

Use checkForStrip in order to check if the shown Strip were added on the EMMA dashboard.

Strip with AutoCreation

[EMMA setStripAutoCreation:(BOOL) autoCreation];

If you want to check Strip automatically in every startup or coming for background you need to pass a TRUE Boolean. By default it is set to no, so you need to decide where and when show Strip.

Strip with label

EMMAInAppRequest* request = [EMMAInAppRequest new];
request.label = @"label";
[EMMA inAppMessage: Strip andRequest: request];

If you want you can pass a custom NSString that labels the Strip in case you use more than one Strip on your app and you need to distinguish between them. NOTE: You cannot use autocreation parameter using label because labeled Strip are attached to a specific part of the app, not at the startup.

Extra

You can use a mixture of this methods in order to pass more parameters. See appendix with all EMMA header options.

 

Using EMMA Coupons

EMMA Coupons allows you to obtain, verify, redeem coupons that are defined and configured in EMMA platform. 

EMMA_27.png

Get Coupons

[EMMA addCouponDelegate:(id<EMMACouponDelegate>) delegate]
[EMMA inAppMessage: Coupons andRequest: nil];

With this call, we will get all the information of the coupons available to the user, depending on the conditions that have been set on the EMMA platform.

In the response block, we will get a dictionary with information about each coupon available to the users. The following information is available for each coupon: id (EMMA internal identifier), code, maximum number of redemptions, number of times traded, title, description, picture …

[EMMA sendImpression: EMMACampaignType.kCampaignCoupon withId: id];
[EMMA sendClick:EMMACampaignType.kCampaignCoupon withId: id];

Details of a Coupon

EMMAInAppRequest* request = [EMMAInAppRequest new];
request.inAppMessageId = @"couponId";
[EMMA inAppMessage: Coupons andRequest: request];

With this call, we will get information of a particular coupon.

The couponId parameter must be the internal coupon identifier of EMMA, ID that can be obtained from a call to checkForCoupons made ​​earlier.

In the response block, we will get a dictionary with the information about the consulted coupon: id (EMMA internal identifier), code, maximum number of redemptions, number of times traded, title, description, picture ...

Check the Coupon validity

EMMAInAppRequest* request = [EMMAInAppRequest new];
request.inAppMessageId = @"couponId";
[EMMA inAppMessage: CouponValidRedeems andRequest: request];

With this call we can check if the user can redeem the coupon indicated.

The couponId parameter must be the EMMA internal identifier of a coupon, ID that can be obtained from a call to checkForCoupons made ​​earlier.

In the response block, we will indicate the number of times that the user can still redeem the coupon.

Redeem a coupon

EMMAInAppRequest* request = [EMMAInAppRequest new];
request.inAppMessageId = @"couponId";
[EMMA inAppMessage: RedeemCoupon andRequest: request];

With this call, the user redeems the coupon indicated.

The couponId parameter must be the EMMA internal identifier of a coupon, ID that can be obtained from a call to Coupons made ​​earlier .

To send the impression and the click on the coupon the following methods must be added in the app, where both actions are performed 

Cancel a coupon

EMMAInAppRequest* request = [EMMAInAppRequest new];
request.inAppMessageId = @"couponId";
[EMMA inAppMessage: CancelCoupon andRequest: request];

This call can cancel the redemption of a coupon done before.

The couponId parameter must be the EMMA internal identifier of an identifier coupon that can be obtained from a call to checkForCoupons made ​​earlier.

Optionally, you can specify a count parameter if you want to cancel more than redemption done before. It it's not indicated, the coupon will be canceled. 

 

Using EMMA NativeAd

EMMA NativeAd allows you to obtain the information of a NativeAd corresponding to a template that has been defined and configured on the EMMA platform.

Formatos-integracion-iOS.png

Get NativeAd 

[EMMA addInAppDelegate:(id<EMMAInAppMessageDelegate>) delegate]
EMMAInAppRequest* request = [EMMAInAppRequest new];
request.nativeAdTemplateId = @"templateId";
[EMMA inAppMessage: NativeAd andRequest: request];

With this call, we will get all the NativeAd information available to the user regarding the templateId, depending on the conditions that have been configured in the EMMA platform.

onReceived:EMMANativeAd* is called if there is a nativeAd that corresponds to the template identifier "templateId".

EMMANativeAd contains all fields configured in EMMA for this NativeAd template, to obtain them the following method will be used:

 

NSString* title = [nativeAd getField:@"Title"];

Once you have obtained all the required fields, you can already create the view to paint this NativeAd on the screen depending on the design that you want to apply. Once the NativeAd is displayed it is necessary to call this method:

[EMMA sendImpression: NativeAd withId: @"templateId"];

Open a NativeAd

[EMMA openNativeAd: @"templateId"];

With this call, the content of the link configured in the NativeAd from the EMMA platform will be displayed.

 

EMMA Whitelist

Minim SDK version: 3.1.7 or higher

With this functionality we can limit the urls that will open the EMMA SDK. So, only the content that starts with any of the urls we have indicated in the whitelist will be displayed in the In-App communications webview.  

If we don't indicate any url in the whitelist, any url is allowed. 

This functionality would affect the Push (Rich URL), Banners, StartViews, AdBalls and DynamicTabs.

Communications (Banners, StartViews, AdBalls y DynamicTabs) can load external content to the app through a Webview and for Banners, AdBalls and DynamicTabs could load external images that would also be controlled by the whitelist. 

For a Push with Rich URL, if the url is not in the whitelist, the webview would not open, but the app will equally receive the push. If you use a deeplink instead of a url, the deeplink scheme must be added to the whitelist in order to open it.  

How to use it

Call this method after the starteMMaSession and before you call any method relating to In-App communications. 

[EMMA setWhitelist:(NSArray*)urls];

Examples

If my whitelist is http://mydomain.com.

[EMMA setWhitelist:@[@"http://mydomain.com"]; 

Example 1:

We upload to the EMMA dashboard a Banner with Target URL https://mydomain.com

The Banner will not be displayed, we must add to the wihitelist https://mydomain.com

Example 2:

We set up in the EMMA dashboard a StartView with StartView URL http://www.mydomain.com

The StartView will not be displayed, we must add to the whitelist http://www.mydomain.com

Example 3:

We set up in the EMMA dashboard a Banner with Target URL http://mydomain.com/my/url and SmartPhone Banner URL http://subdomain.mydomain.com/my/image

The Banner will not be displayed, the image url is not in the whitelist, so we must add to the whitelist http://subdomain.mydomain.com

Example 4:

We configure in the EMMA dashboard a Banner with Target URL http://mydomain.com/my/url/

The Banner will be displayed because the url that we configure in the  Target URL section starts with the same protocol and domain as the url of the whitelist. 

Ejemplo 5:

We configure in the EMMA dashboard a StartView with StartView URL http://mydomain.com/mypage.html&param=value

The StartView will be displayed because the url that we configure in the StartView URL section starts with the same protocol and domain as the url of the whitelist. 

 

Add Rate Alert

EMMA makes easier to add a Rate alert in order to achieve more positive reviews in an app.

Create Rate Alert

[EMMA addRateAlertForAppStoreURL:APP_STORE_URL]

You can set the following options using the following methods:

[EMMA setRateAlertFreq:TIME_FREQUENCE]

: Int specifying hours between alert shows. By default 72 hours.

[EMMA setRateAlertTitle:TITLE]

: NSString that specifies rate alert title. By default “Rate this app”.

[EMMA setRateAlertMessage:MESSAGE]

: NSString that specifies rate alert message. By default: “If you like our app, please rate it on App Store!”

[EMMA setRateAlertCancelButton:CANCEL]

: NSString that specifies rate cancel button title. If pressed the alert will never show again. By default: “No, thanks”

[EMMA setRateAlertLaterButton:LATER]

: NSString that specifies rate later button title. Each time user press Later alert will delay its shown multiplying time frequency per alert seen times. By default: “Later”

[EMMA setRateAlertRateItButton:RATE_IT]

: NSString that specifies rate button. If pressed the alert will never show again. By default: “Rate it now!”

[EMMA setRateAlertShowAfterUpdate:APP_UPDATE]

: Bool that allows Rate alert to show again in case of app update if the user previously has rated the app. (Multiple rates for the same user)

You can use abbreviated methods if you don’t need all parameters, you can find them in EMMA.h.

 

Debugging your code

This step is optional. If you need to see the EMMA log, enable it (before starteMMaSession) by calling:

[EMMA setDebuggerOutput:TRUE]

 

Deploying your App to AppStore

Apple has changed its tracking policies on 2014. The new policy affects directly the use of the IDFA tracking (Identifier for advertisers). Apple has stated that IDFA tracking is allowed for the following purposes: frequency capping, conversion events, estimating the number of unique users, security and fraud detection, and debugging.

EMMA gets this identifier in order to know conversion events and unique users estimation, so our IDFA collection is aligned with Apple policy.

In order to follow all Apple rules you need to tick the following boxes on iTunes Connect once uploading your app:

EMMA_28.png

Having checked the previous boxes EMMA will be fully working and allowing you to use POWLINK without breaking any Apple policy.

If you desire to disable the use of IDFA tracking you should check the same boxes in order to prevent Apple complaints. In that case you need to call the following method disabling it the use of the IDFA.

IMPORTANT
IDFA tracking is enabled by default on EMMA . If you don’t want to track with IDFA please use method [eMMa setUseIDFA:BOOL]; in order to disable. Anyway you need to check the speciefied box on iTunnes Connect question regarding IDFA tracking.

[EMMA setUseIDFA:BOOL];


BOOL tells to EMMA when to use IDFA tracking. If NO VendorID will be used. It can be enabled/disabled for future app releases.

Have more questions? Submit a request

0 Comments

Please sign in to leave a comment.