Documentation for the Lune PFM iOS SDK
π¦ An SDK to embed Lune enrichment views into your iOS mobile apps
Installation
There are three options to install the LuneSDK
. Follow the instructions below for any of the options you prefer:
With that done, you should be able to import the SDK into any of your Swift files as shown below.
import LuneSDK
1. Swift Package Manager (SPM)
You can add the LuneSDK
to your project directly within xcode using Swift Package Manager. To do so:
- Open up your project in xcode, and in the menu bar, click on to
File
>Add Package Dependencies...
- Paste
https://github.com/Lune-Technologies/lune-pfm-sdk-ios.git
Β into the Search Bar at the top-right of the page. - Click on Add Package
- Select the target you want to add the SDK to, if necessary.
- Let Xcode download the package and set everything up.
2. CocoaPods
To install the LuneSDK
into your project using CocoaPods, add the following to your Podfile
file:
use_frameworks!
target 'MyApp' do
# Add the LuneSDK pod ππ½
pod 'LuneSDK'
# ...
end
Then run pod install
to install LuneSDK
in your workspace.
β οΈ Should you encounter an error about the bundle needing signing on Xcode 14, add the following post-install script in your podfile.
post_install do |installer|
installer.pods_project.targets.each do |target|
if target.respond_to?(:product_type) and target.product_type == "com.apple.product-type.bundle"
target.build_configurations.each do |config|
config.build_settings['CODE_SIGNING_ALLOWED'] = 'NO'
end
end
end
3. Manually - using raw XCFramework
You can also add the LuneSDK
to your project manually, using the raw xcframework
.To do so:
- Add the
.xcframework
provided to you into your Xcode project by simply dragging it into the Project navigator. - In the resulting pop-up, ensure that the "Copy items if needed" option is checked and click "Finish"
- Select your project in the Project Navigator, and allow the Targets settings to load.
- Under the General tab, scroll to reveal the Frameworks, Libraries and Embedded Content section.
- In that section, click the dropdown button next to
LuneSDK.xcframework
and select "Embed and Sign"
Initialization
To initialize the SDK, you simply have to create an instance of LuneSDKManager
(or LuneSDKObjcManager
for Objective-C) Β that would be used across your app.
Provided that you will need to initialize LuneSDK with credentials, you may want to do all the prep work within a view-model. That includes things like:
- Getting the credentials
- Setting up a refresh callback (optional, based on the TTL of your credentials)
- Setting up logging (also optional)
You can find specific implementation details for your project setup below:
1. SwiftUI
Follow the steps below to initialize LuneSDK in your SwiftUI
Project.
// MyViewModel.Swift
import Foundation
import LuneSDK // 1. Import LuneSDK
class MyViewModel: ObservableObject {
// 2. Add a property to hold the LuneSDKManager instance
@Published var luneSDKManager: LuneSDKManager? = nil
init() {
Task {
// 3. do everything you need to do to get your credentials
await getCredentials()
// 4. initialize the SDK with your credentials
let sdk = LuneSDKManager(
baseUrl: "<your.base.url>"
token: "<your.token>",
customerId: "<user.customer.id>"
)
// 5. optional: set up a refresh callback to handle token refresh
sdk.setupRefreshCallback(getRefreshToken)
// 6. optional: set up an event logger if you need to be informed about user actions in the SDK (for analytics)
sdk.initializeLogger { eventMap in
print("Logging event: \(eventMap)");
}
// 7. assign the SDK to the published property
DispatchQueue.main.async { [self] in
self.luneSDKManager = sdk
}
}
}
private func getCredentials() async {
// do everything you need to do to get your credentials (from server, or env, etc)
}
func getRefreshToken() async -> String? {
// do everything you need to do to get a refresh token
return "<refresh_token>"
}
}
Below are the steps within your view-model:
- Import
LuneSDK
- Instantiate a published property to hold the SDK instance. This would be referenced from your view. You can call it anything - in this case, we'd go with
luneSDKManager
- Get LuneSDK credentials (
baseUrl
andtoken
) ready. This could be by making requests to a server if your credentials are stored on your backend, or even jut reading them from some environment variables if that's what you use. - Initialize the SDK with the credentials and
customerId
. - Optional: Set up a refresh callback function. It should be an
async
function with return typeString?
. This function would be called whenever your token expires. - Optional: Set up a logging function for analytics events. This function should take in a map of
String
toAny
, and it will be used to report user actions to you. - Assign the initialized SDK to the published property,
luneSDKManager
.
π‘ SwiftUI Tip: Β
β
While you could create multiple instances of LuneSDKManager
, we recommend that you create just one instance per app. You could share that single instance with other views using Environment Objects.
// MyApp.Swift
import SwiftUI
import LuneSDK // 1. Import LuneSDK
@main
struct MyApp: App {
@ObservedObject private var viewModel = MyViewModel()
// 2. create getter
var luneSDKManager: LuneSDKManager? {
viewModel.luneSDKManager
}
var body: some Scene {
WindowGroup {
if(luneSDKManager != nil) {
ContentView()
.environmentObject(luneSDKManager!) // 3. optional: share instance with other views in the app's hierarchy
}
}
}
}
Below are the steps within your view:
- Import
LuneSDK
- Create a getter for the published property in your view-model,
luneSDKManager
- You can use
luneSDKManager
directly at this point, but you may want to pass it down your view hierarchy, so as to share the instance and not have to do the set up everywhere else.
You can then use the LuneSDKManager
instance in any view of your app as shown below.
// HomeView.Swift
import SwiftUI
import LuneSDK // 1.
struct HomeView: View {
// 2. Get instance with @EnvironmentObject
@EnvironmentObject var luneSDK: LuneSDKManager
var body: some View {
ScrollView{
// 3. Use instance to inject any view of your choice
luneSDK.TransactionListComponent()
}
}
}
2. Objective C
β οΈ Update Needed:
β
The Objective-C implementation needs to be updated in light of recent breaking changes.This documentation will be updated right after updates have been tested and pushed.
Follow the steps below to initialize LuneSDK in your Obj-C
Project.
// YourViewController.m
@import LuneSDK;
@interface YourViewController ()
// Declare luneSDK as a property of the class
@property (nonatomic, strong) LuneSDKObjcManager *luneSDK;
@end
@implementation YourViewController
- (void)viewDidLoad {
[super viewDidLoad];
// Initialize the SDK with your credentials.
_luneSDK = [
[LuneSDKObjcManager alloc]
initWithBaseUrl:@"<your.base.url>"
token:@"<your.token>",
customerId:@"<user.customer.id>"
];
}
You can then use the LuneSDKObjcManager
instance in any view of your app as shown below.
// YourViewController.m
// budget summary setup, after the above setup is complete
// Create a new view controller instance using the BudgetSummaryComponentWithConfig method of the LuneSDK.
UIViewController *hostingController = [self.luneSDK BudgetSummaryComponent];
// Add the new view controller as a child view controller of the current view controller.
[self addChildViewController:hostingController];
// Add the new view controller's view as a subview of the current view controller's view.
[self.view addSubview:hostingController.view];
// Disable the autoresizing mask translation for the new view controller's view to enable the use of Auto Layout constraints.
hostingController.view.translatesAutoresizingMaskIntoConstraints = NO;
// Activate Auto Layout constraints to pin the new view controller's view to the edges of the current view controller's view.
[NSLayoutConstraint activateConstraints:@[
[hostingController.view.topAnchor constraintEqualToAnchor:self.view.topAnchor],
[hostingController.view.leadingAnchor constraintEqualToAnchor:self.view.leadingAnchor],
[hostingController.view.trailingAnchor constraintEqualToAnchor:self.view.trailingAnchor],
[hostingController.view.bottomAnchor constraintEqualToAnchor:self.view.bottomAnchor],
]];
Customization
The SDK has lots of configurable parameters which can be overridden by setting up a JSON
file with a schema similar to the one attached below. You could just download the file and modify the values you wish to change.
The JSON
file should be saved as lune-config.json
and added to as a Data Set
, with the name LuneConfig
in your XCode project.
β οΈ The assets specified in the config file should be present within your XCAssets
file with the same name used in the config file.
π‘ Note:
Necessary variants of the fonts mentioned in the config file should be added to the project as well, within the <project-name>
directory.
e.g
β|- LuneBank
ππ½
|- - Info.plist
|- - Poppins_regular.ttf
β|- - Poppins_semibold.ttf
ππ½
β|- - Poppins_bold.ttf
ππ½
Also, don't forget to set up the fonts in Info.plist
e.g
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<!-- everything else -->
<key>UIAppFonts</key>
<array>
<string>Poppins_regular.ttf</string>
<string>Poppins_bold.ttf</string>
<string>Poppins_semibold.ttf</string>
</array>
</dict>
</plist>
1. Localization and Strings
If your app is already localized, the SDK would be localized as well - no configurations required. If your app is not localized, however, the SDK respects that and stays in English to preserve consistency and uniformity across your app.
String Overrides
You can override specific strings by assigning a different value to the same string keys used by the SDK.
The Strings used in the SDK can be found in the localization file attached below.
As you may have noticed, the keys are unique and should not conflict with any other strings in your project.
If your app has multiple string files, you might want to point the SDK to the specific file you want it to read overrides from.
You can do that by providing the file name as a value for the optional localizationTableName
parameter in the SDK initializer.
LuneSDKManager(
baseUrl: "<your.base.url>"
token: "<your.token>",
customerId: "<user.customer.id>",
localizationTableName: "<strings file name>"
)
π tableName
β
The name of the table containing the key-value pairs. Also, the suffix for the strings file (a file with the .strings
extension) to store the localized string. This defaults to the table in Localizable.strings
when tableName
is nil
or an empty string.
2. Images
You can override any of the images in LuneSDK
by simply giving any other images in your project the exact same name.
Each image is named using the format:
lune_sdk_asset_<image_name>
You can find a list of the images you can override here:
Components
The Lune SDK components are broadly divided into full-page views and smaller (mix and match) components.
Full page views
These components are typically large and were designed to be used as stand-alone components on a page. While you could still choose to do so, we strongly discourage adding other widgets as siblings to full page views.
Examples are:
Smaller (mix and match) Components
These components are usually small enough and could easily be arranged as siblings of other widgets on a page.
Examples are: