This guide explains the requirements for Carthage installation, how to integrate it, and how to configure targets for Carthage.
Requirements
To configure Carthage, you need to:
1. Have an installed Mac with Xcode.
2. Have an iOS device (The Xcode simulator does not support push notifications. That's why you need to test on a real device.).
3. Have an Apple Push Services Certificate for iOS.
4. Install Carthage.
Installing Carthage
4.1. After installing Carthage, make sure that your Carthage directory is located in the /usr/bin/carthage directory. You can check it with the following command:
which carthageThe result for the command above needs to be /usr/bin/carthage. If the result is /opt/homebrew/bin/carthage, you need to move it to /usr/bin/carthage with the following command:
ln -s /opt/homebrew/bin/carthage /usr/local/bin/carthage4.2. Make sure you have the /usr/bin/carthage folder first.
5. Create a Cartfile.
Creating a Cartfile
5.1. Add a Cartfile to your project or update your existing one as follows:
binary "https://mobilesdk.useinsider.com/carthage/InsiderNotificationContent/2.0.0/InsiderNotificationContent.json" ~> 2.0.0
binary "https://mobilesdk.useinsider.com/carthage/InsiderNotificationService/2.0.0/InsiderNotificationService.json" ~> 2.0.0
binary "https://mobilesdk.useinsider.com/carthage/InsiderMobile/13.7.1/InsiderMobile.json" ~> 13.7.15.2. Make sure to replace <INSIDER_IOS_SDK_VERSION> with the appropriate version of the Insider iOS SDK in the “12.7.3” format.

Framework Integration
1. Before updating the Carthage repository, run the following command to clean the Carthage cache:
rm -rf ~/Library/Caches/org.carthage.CarthageKit2. Open the project directory in the terminal. Run the following command:
carthage update --use-xcframeworks --platform "iOS"After the command above, a Carthage folder will be created with the Build and Checkout folder. Downloaded frameworks located in the Carthage/Build folder are as follows:

3. To add Libraries to targets, select your main target > General tab. Add the following frameworks to the Frameworks, Libraries, and Embedded Content section from Carthage > Build.
InsiderMobile.xcframework
InsiderNotificationService.xcframework
InsiderNotificationContent.xcframework



Once you add the frameworks, they will be listed under Frameworks, Libraries, and Embedded Content.

4. Select the InsiderNotificationService target, select the General tab, and add the following frameworks to the Frameworks and Libraries section from Carthage > Build:
InsiderNotificationService.xcframework



Once you add the frameworks, they will be listed under Frameworks and Libraries.

5. Select InsiderNotificationContent target, select the General tab, and add the following frameworks to the Frameworks and Libraries section from Carthage > Build:
InsiderNotificationContent.xcframework



Once you add the frameworks, they will be listed under Frameworks and Libraries.

Configuring Targets
1. Navigate to Carthage in the project navigator and Carthage > Build > InsiderNotificationService.xcframework.
2. You will need to copy the code in NotificationService.m for Objective-C targets.
The following is the Notification Service:

3. Replace the entire code in Your Project > InsiderNotificationService > NotificationService.m with Carthage > Build > InsiderNotificationService.xcframework > NotificationService.m.
After you replace the entire code, it should look like as follows:
#import "NotificationService.h"
#import <InsiderNotificationService/InsiderPushService.h>
@interface NotificationService ()
@property (nonatomic, strong) void (^contentHandler)(UNNotificationContent *contentToDeliver);
@property (nonatomic, strong) UNMutableNotificationContent *bestAttemptContent;
@property (nonatomic, strong) UNNotificationRequest *receivedRequest;
@end
// FIXME: Please change with your app group.
static NSString *APP_GROUP = @"group.com.company.app";
@implementation NotificationService
-(void)didReceiveNotificationRequest:(UNNotificationRequest *)request withContentHandler:(void (^)(UNNotificationContent * _Nonnull))contentHandler {
self.contentHandler = contentHandler;
self.bestAttemptContent = [request.content mutableCopy];
self.receivedRequest = request;
// MARK: You can customize these.
NSString *nextButtonText = @">>";
NSString *goToAppText = @"Launch App";
[InsiderPushNotification showInsiderRichPush:self.bestAttemptContent appGroup:APP_GROUP nextButtonText:nextButtonText goToAppText:goToAppText success:^(UNNotificationAttachment *attachment) {
if (attachment) {
self.bestAttemptContent.attachments = [NSArray arrayWithObject:attachment];
}
self.contentHandler(self.bestAttemptContent);
}];
}
-(void)serviceExtensionTimeWillExpire {
[InsiderPushService serviceExtensionTimeWillExpire:[self receivedRequest] content:[self bestAttemptContent]];
self.contentHandler(self.bestAttemptContent);
}
@end4. For Swift, replace the entire code in Your Project > InsiderNotificationService > NotificationService.swift with the below code:
import UserNotifications
// FIXME: Please change with your app group.
let APP_GROUP = "group.com.company.app"
class NotificationService: UNNotificationServiceExtension {
var contentHandler: ((UNNotificationContent) -> Void)?
var bestAttemptContent: UNMutableNotificationContent?
var receivedRequest: UNNotificationRequest?
override func didReceive(_ request: UNNotificationRequest, withContentHandler contentHandler: @escaping (UNNotificationContent) -> Void) {
self.contentHandler = contentHandler
bestAttemptContent = (request.content.mutableCopy() as? UNMutableNotificationContent)
receivedRequest = request
if let bestAttemptContent = bestAttemptContent {
// Modify the notification content here...
let nextButtonText = ">>"
let goToAppText = "Launch App"
InsiderPushService.showInsiderRichPush(
bestAttemptContent,
appGroup: APP_GROUP as String,
nextButtonText: nextButtonText,
goToAppText: goToAppText,
success: { attachment in
if let attachment = attachment {
bestAttemptContent.attachments = bestAttemptContent.attachments + [attachment as UNNotificationAttachment]
print(bestAttemptContent.attachments)
}
print(bestAttemptContent.attachments)
contentHandler(bestAttemptContent)
print(bestAttemptContent.attachments)
})
print(bestAttemptContent.attachments)
}
}
override func 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.
if let contentHandler = contentHandler, let bestAttemptContent = bestAttemptContent {
InsiderPushService.serviceExtensionTimeWillExpire(receivedRequest, content: bestAttemptContent)
contentHandler(bestAttemptContent)
}
}
}The following is the Bridging Header for Notification Service in Swift:
#import <InsiderNotificationService/InsiderPushService.h>The following is the Notification Content:
.png)
5. Replace the entire code in Your Project > InsiderNotificationContent > NotificationService.m with Carthage > Build > InsiderNotificationContent.xcframework > NotificationViewController.m.
After you replace the entire code, it should look like as follows:
#import "NotificationViewController.h"
#import <UserNotificationsUI/UserNotificationsUI.h>
#import <InsiderNotificationContent/iCarousel.h>
#import <InsiderNotificationContent/InsiderPushContent.h>
@interface NotificationViewController () <UNNotificationContentExtension, iCarouselDelegate, iCarouselDataSource>
@property (nonatomic, weak) IBOutlet iCarousel *carousel;
@end
// FIXME: Please change with your app group.
static NSString *APP_GROUP = @"group.com.company.app";
@implementation NotificationViewController
@synthesize carousel;
-(void)viewDidLoad {
[super viewDidLoad];
}
-(void)viewWillDisappear:(BOOL)animated {
[InsiderPushContent setTimeAttribution];
}
-(void)didReceiveNotification:(UNNotification *)notification {
[InsiderPushContent interactivePushLoad:APP_GROUP superView:self.view notification:notification];
carousel.type = iCarouselTypeRotary;
[carousel reloadData];
[InsiderPushContent interactivePushDidReceiveNotification];
}
-(NSInteger)numberOfItemsInCarousel:(iCarousel *)carousel {
return [InsiderPushContent getNumberOfSlide];
}
-(UIView *)carousel:(iCarousel *)carousel viewForItemAtIndex:(NSInteger)index reusingView:(UIView *)view {
return [InsiderPushContent getSlide:index reusingView:view superView:self.view];
}
-(void)dealloc {
carousel.delegate = nil;
carousel.dataSource = nil;
}
-(CGFloat)carouselItemWidth:(iCarousel *)carousel {
return [InsiderPushContent getItemWidth];
}
-(void)didReceiveNotificationResponse:(UNNotificationResponse *)response
completionHandler:(void (^)(UNNotificationContentExtensionResponseOption option))completion {
if ([response.actionIdentifier isEqualToString:@"insider_int_push_next"]){
[carousel scrollToItemAtIndex:[InsiderPushContent didReceiveNotificationResponse:[carousel currentItemIndex]] animated:true];
completion(UNNotificationContentExtensionResponseOptionDoNotDismiss);
} else {
[InsiderPushContent logPlaceholderClick:response];
completion(UNNotificationContentExtensionResponseOptionDismissAndForwardAction);
}
}
@end6. For Swift, replace the entire code in Your Project > InsiderNotificationContent > NotificationViewController.swift with the below code:
import UIKit
import UserNotifications
import UserNotificationsUI
// FIXME: Please change with your app group.
let APP_GROUP = "group.com.company.app"
@objc(NotificationViewController)
class NotificationViewController: UIViewController, UNNotificationContentExtension, iCarouselDelegate, iCarouselDataSource {
@IBOutlet weak var carousel: iCarousel!
deinit {
carousel.delegate = nil
carousel.dataSource = nil
}
func numberOfItems(in carousel: iCarousel) -> Int {
return InsiderPushContent.getNumberOfSlide()
}
func carousel(_ carousel: iCarousel, viewForItemAt index: Int, reusing view: UIView?) -> UIView {
return InsiderPushContent.getSlide(index, reusing: view, superView: self.view)
}
func carouselItemWidth(_ carousel: iCarousel) -> CGFloat {
return InsiderPushContent.getItemWidth()
}
override func viewDidLoad() {
super.viewDidLoad()
}
override func viewWillDisappear(_ animated: Bool) {
InsiderPushContent.setTimeAttribution()
}
func didReceive(_ notification: UNNotification) {
InsiderPushContent.interactivePushLoad(APP_GROUP, superView:self.view, notification: notification)
carousel.type = .rotary
carousel.reloadData()
InsiderPushContent.interactivePushDidReceiveNotification()
}
func didReceive(_ response: UNNotificationResponse, completionHandler completion: @escaping (UNNotificationContentExtensionResponseOption) -> Void) {
if (response.actionIdentifier == "insider_int_push_next") {
carousel.scrollToItem(at: InsiderPushContent.didReceiveNotificationResponse(carousel.currentItemIndex), animated: true)
completion(.doNotDismiss)
} else {
InsiderPushContent.logPlaceholderClick(response)
completion(.dismissAndForwardAction)
}
}
}The following is the Bridging Header for Notification Content in Swift:
#import <InsiderNotificationContent/iCarousel.h>
#import <InsiderNotificationContent/InsiderPushContent.h>7. Copy Carthage > Build > InsiderNotificationContent.xcframework > InsiderInterface.storyboard into your NotificationContent folder




If you forget to copy the InsiderInterface to your InsiderNotificationContent project folder, or just copy it through the finder, the carousel, slider, and discovery pushes will not work as expected. For this reason, you have to drag and drop Xcode InsiderNotificationContent into your project folder, as mentioned above.
Also note that after copying the InsiderInterface, you need to test it with a different push, as the same notification can sometimes be cached and may not seem to work.
Make sure the Main Interface is InsiderInterface.

Navigate to InsiderNotificationContent > Info.plist and open as source code. Edit it as follows. The following is the Info.plist:
<dict>
<key>NSExtensionAttributes</key>
<dict>
<key>UNNotificationExtensionCategory</key>
<string>insider_int_push</string>
<key>UNNotificationExtensionDefaultContentHidden</key>
<string>YES</string>
<key>UNNotificationExtensionInitialContentSizeRatio</key>
<real>0.5</real>
</dict>
<key>NSExtensionMainStoryboard</key>
<string>InsiderInterface</string>
<key>NSExtensionPointIdentifier</key>
<string>com.apple.usernotifications.content-extension</string>
</dict>Your Info.plist should look like as follows:
.png)

Issues with Carthage folder permission
When building the application, if “XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX.bcsymbolmap” couldn’t be copied because you don’t have permission to access “Debug-iphoneos” error occurred, you need to change the current permissions for the Carthage folder.
- In your Project root, choose Carthage folder > right-click and select Get info.
- Click Sharing & Permissions, then click the lock icon to unlock it.
- Enter the administrator name and password.
- Choose the user in the Name column and then choose the Privilege setting from the pop-up menu.

