富士胶片 SPA iOS SDK 教程
介绍
该项目是一个示例应用程序,演示如何集成富士胶片 SPA iOS SDK。
本文档提供了一个教程,说明如何在您的 iOS 应用程序中使用富士胶片 SPA iOS SDK 库。
它是什么?
富士胶片智能发布 API SDK 是一个原生库,您可以将它包含到现有的 iOS 应用程序中,以通过富士胶片输出照片产品。这为您提供了新的收入渠道,同时为您的应用程序用户提供新的宝贵服务。
富士胶片 SPA SDK 提供了对 100 多种流行的照片礼物产品的访问权限,并允许您通过我们的网页门户控制每个产品的可用性和定价。
请访问富士胶片开发者网络门户进行注册并获取 API 密钥,设置产品定价并配置您的应用程序。该门户位于 http://www.fujifilmapi.com/。
需求
- 支持iOS版本8.0或更高版本
- 使用富士胶片SPA iOS SDK的开发者需要在富士胶片开发者网络(http://fujifilmapi.com)注册账户,创建应用程序,获取API密钥,并设置目录产品和定价。
集成说明
步骤1:获取API密钥
在富士胶片开发者网络(http://fujifilmapi.com)注册账户,创建应用程序,获取API密钥,并设置目录产品和定价。
步骤2:包含富士胶片SPA SDK
将富士胶片SPA SDK包含到您的Xcode项目中。要将富士胶片SPA SDK添加到您的Xcode项目,您可以通过CocoaPods安装,或者手动添加。
使用CocoaPods
有关CocoaPods的更多信息,包括如何将pod添加到Xcode项目的说明,请访问https://guides.cocoapods.org.cn/using/the-podfile.html。
本节假设您已经在您的系统中安装了CocoaPods。
在您的Podfile中,按照如下方式包含SPA SDK pod
pod 'Fujifilm-SPA-SDK', '~> 1.10.12'
通过导航到终端中的项目目录并运行$ pod install
来安装pod。如果您已经安装了SDK并希望更新到最后版本,请运行$ pod update
代替。
成功安装后,如果您的Xcode项目已经打开,请先关闭它,然后打开由Cocoapods生成的 workspace。
手动安装
如果您正在使用Cocoapods,请跳过本节!
- 下载文件
- 将文件添加到项目中
- 在Xcode中打开您的项目。选择“文件”>“添加文件到‘MyApp’”,选择您刚下载的文件。在“目标”部分下选择“所需时复制项目”,并在“已添加文件夹”下选择“创建分组”。确保已勾选“添加到目标”部分的“我的目标”。点击添加。
- 链接框架
- 将以下框架添加到您的项目中:
- Accelerate
- AddressBook
- AddressBookUI
- AVFoundation
- AudioToolBox
- CoreMedia
- MobileCoreServices
- SystemConfiguration
- AssetsLibrary
- ImageIO
- Photos
- 要添加框架,在Xcode文件浏览器中选择您的项目。在主窗口中,左上角有一个下拉菜单,列出了您所有的项目和目标。请确保已选择您的目标(而不是项目)并切换到“构建阶段”选项卡。展开“链接二进制与库”部分,并添加上述列出的框架。
- 在“TARGETS”构建设置中,将“-lc++”添加到“其他链接器标志”部分。
- 在“TARGETS”构建设置中,将“-ObjC”添加到“其他链接器标志”部分。
步骤 3: 更新 info.plist 文件
为了使用 SDK,您需要在项目的 info.plist 文件中添加密钥。
您可以使用 Xcode UI 手动输入所有密钥,或使用文本编辑器打开 info.plist 文件,并在 <plist> <dict> 标签内粘贴以下内容。
<key>NSLocationWhenInUseUsageDescription</key>
<string>Please enable this feature to search for stores near you when creating personalized prints and gifts.</string>
<key>NSContactsUsageDescription</key>
<string>Please enable this feature to access your contacts when creating personalized prints and gifts.</string>
<key>NSPhotoLibraryUsageDescription</key>
<string>Please enable this feature to be able to upload your photos and create personalized prints and gifts.</string>
<key>NSAppTransportSecurity</key>
<dict>
<key>NSAllowsArbitraryLoads</key>
<true/>
<key>NSExceptionDomains</key>
<dict>
<key>fujifilmesys.com</key>
<dict>
<key>NSExceptionAllowsInsecureHTTPLoads</key>
<true/>
<key>NSExceptionRequiresForwardSecrecy</key>
<false/>
<key>NSIncludesSubdomains</key>
<true/>
</dict>
<key>paypal.com</key>
<dict>
<key>NSExceptionRequiresForwardSecrecy</key>
<false/>
<key>NSIncludesSubdomains</key>
<true/>
</dict>
</dict>
</dict>
步骤 4: PayPal 付款选项
我们为用户提供2种支付方式:信用卡和PayPal。请按照以下步骤操作以启用PayPal,因为它通常会有更高的转化率。
在 info.plist 中使用 CFBundleURLTypes 键设置应用切换
要接受 PayPal 的支付,您必须注册一个 URL 类型并配置您的应用以从应用切换返回。
注册一个 URL 类型
- 在 Xcode 中,点击项目导航器中的您的项目,然后转到 App Target > Info > URL Types。
- 点击 [
+
] 添加一个新的 URL 类型。 - 在 Identifier 下,输入您的应用的 Bundle ID。
- 在 URL Schemes 下,输入您的应用切换返回 URL 方案。 此方案必须以您的应用 Bundle ID 开头,并专门用于富士影像 SDK 的应用切换返回。例如,如果应用的 Bundle ID 是 com.your-company.Your-App,则您的 URL 方案可以是 com.your-company.Your-App.FujifilmSDK.Payments。
- 如果您使用 iOS 9 作为其基本 SDK 构建应用,则必须在您的应用
info.plist
中的白名单中添加 URL。
<key>LSApplicationQueriesSchemes</key>
<array>
<string>com.paypal.ppclient.touch.v1</string>
<string>com.paypal.ppclient.touch.v2</string>
</array>
- 测试步骤 4 上设置的 URL 类型:打开移动 Safari 在您的 iOS 设备或模拟器中,并输入您在步骤 4 中设置的 URL(例如:com.your-company.Your-App.FujifilmSDK.Payments://test)。这应该启动您的应用。
重要:如果您有多个应用目标,请确保为所有目标添加 URL 类型。
第 5 步:与 SDK 集成 - Objective-C
如果您使用 Swift,可以参考这里找到的说明: Swift 集成。
在您的视图控制器头文件中导入 SDK。
#import "Fujifilm.SPA.SDK.h"
确保您的视图控制器头文件实现了 FujifilmSPASDKDelegate
协议。
@interface ViewController : UIViewController <FujifilmSPASDKDelegate>{}
在您的视图控制器中创建一个 Fujifilm_SPA_SDK_iOS
对象。使用 initWithApiKey:environment:images:userID:retainUserInfo:promoCode:launchPage:extraOptions
方法对其进行初始化。
Fujifilm_SPA_SDK_iOS *fujifilmSDKOrderController = [[Fujifilm_SPA_SDK_iOS alloc]
initWithApiKey: @"YOUR_API_KEY" //REPLACE with YOUR ApiKey
environment: @"Preview"
images: NS_ARRAY_OF_FFIMAGES
userID: @"" //optional
retainUserInfo: YES
promoCode: @"" //optional
launchPage: kHome
extraOptions: nil];
参数
名称 | 类型 | 描述 |
---|---|---|
apiKey |
NSString* |
当您在 http://fujifilmapi.com 创建应用程序时,您将收到富士胶片SPA apiKey。该apiKey对环境具有特定性 |
环境 |
NSString* |
设置要使用的环境。apiKey必须与在 http://fujifilmapi.com 上设置的与您的应用程序相同的环境相匹配。可能的值是“preview”或“production”。 |
图像 |
FFImage* |
一个包含FFImage的NSArray,可以使用PHAsset或NSURL初始化。图像必须是jpeg、png或heic格式,小于20MB。在给定的Checkout过程中最多可以发送100张图像。如果发送超过100张图像,则只会处理前100张。 |
userID |
NSString* |
可选参数。如果您不使用它,请发送空字符串@"" 。这可以用作将用户与订单关联。最大长度为50个字母数字字符。 |
retainUserInfo |
BOOL |
保存应用程序再次使用时用户信息(地址、电话号码、电子邮件)。 |
promoCode |
NSString* |
可选参数,可以添加促销代码到订单中。通过http://fujifilmapi.com与我们联系以获取使用和支持。 |
launchPage |
enum |
初始化SDK时应启动的页面。有效值是kHome 和kCart 。默认为kHome |
extraOptions |
NSDictionary |
一个包含键/值对的字典。所有键/值对都是可选的;如果不需要选项,则extraOptions 可以为空或nil 。有关更多信息,请参阅“额外初始化选项”部分。 |
接下来,将Fujifilm_SPA_SDK_iOS对象的委托设置到视图控制器
fujifilmSDKOrderController.delegate = self;
接下来,使用orderController作为根创建一个新的FujifilmSPASDKNavigation控制器
FujifilmSPASDKNavigationController *fujifilmSDKNavigationController = [[FujifilmSPASDKNavigationController alloc] initWithRootViewController:fujifilmSDKOrderController];
最后,显示Fujifilm_SPA_SDK_iOS对象
[self presentViewController:fujifilmSDKNavigationController animated:YES completion:nil];
额外初始化选项(可选)
键 | 值 | 描述 |
---|---|---|
kSiteDeepLink |
NSString* |
指定启动SDK时用户首次显示的页面。您可以将用户发送到购物车、类别、产品详情或产品构建器。要将用户发送到购物车,请将值设置为Cart 。要发送到类别,请使用以下模式:mailorder/CATEGORY_NAME 。请确保将CATEGORY_NAME 更改为类别的名称,例如,mailorder/WallArt 。要发送到产品详情屏幕,请使用以下模式:mailorder/CATEGORY_NAME/PRODUCT_NAME 。请确保将CATEGORY_NAME 更改为类别的名称,将PRODUCT_NAME 更改为产品的名称,例如,mailorder/canvas/11x14gallerywrappedcanvas 。要将用户发送到产品构建器屏幕,请使用以下模式:mailorder/CATEGORY_NAME/PRODUCT_NAME/builder 。请确保将CATEGORY_NAME 更改为类别的名称,将PRODUCT_NAME 更改为产品的名称,例如,mailorder/canvas/11x14gallerywrappedcanvas/builder 。 |
kEnableAddMorePhotos |
BOOL* |
默认情况下,此值设置为YES 。禁用“添加更多照片”功能,请将其设置为值No 。如果为YES (或省略),则用户将能够在其本地照片库的编译屏幕和打印屏幕上添加更多照片。 |
kPreRenderedOrder |
FFOrder* |
请参阅“提供预渲染产品”部分以获取更多信息。 |
提供预渲染产品(可选)
预渲染(自定义)产品可以用于创建您自己的自定义内容,我们将将其打印在4x8问候卡、5x7问候卡、5x7文具卡或8x8照片定制产品上。预渲染产品只能与预渲染(自定义)产品代码一起使用。您首先需要在门户的定价页面上启用自定义产品(配备),该页面位于左侧导航中的卡>自定义卡和照片书>自定义照片书类别下。启用自定义产品后,您可以使用以下4个产品代码之一。
4x8 Greeting Card: "PRGC;823"
5x7 Greeting Card: "PRGC;830"
5x7 Stationery Card: "PRGift;4121"
8x8 Photobook: "PRGift;5212"
为了将预渲染产品包含在您的订单中,您可以向extraOptions
参数传递一个FFOrder
类的实例。此类包含要添加到订单中的产品列表(FFLine
类实例)。每个FFLine
都包含一个产品代码字段,该字段对应于http://fujifilmapi.com上找到的产品代码,以及一个FFPage
对象列表。每个FFPage
对象包含一个FFAsset
对象列表,其中每个对象都包含要打印的Hi-Res图像的URL。以下是一个示例函数,说明如何创建一个包含预渲染文具卡的订单。
-(FFOrder *)createPrerenderedOrderWithStationeryCard {
//create a FFAsset for the front of the card
FFAsset *assetFront = [FFAsset assetWithHiResImageURL:@"http://test.com/prerenderedCardFront.jpg"];
//create a FFAsset for the back of the card
FFAsset *assetBack = [FFAsset assetWithHiResImageURL:@"http://test.com/prerenderedCardBack.jpg"];
//create a FFPage for the front of the card. Add the front asset
FFPage *pageFront = [FFPage page];
[pageFront addAsset:assetFront];
//create a FFPage for the back of the card. Add the back asset
FFPage *pageBack = [FFPage page];
[pageBack addAsset:assetBack];
//create a FFLine with product code which represents the desired product
FFLine *line = [FFLine lineWithProductCode:@"PRGift;4121"];
//add the front and back pages to the Line
[line addPage:pageFront];
[line addPage:pageBack];
//Create a new order containing the Line
FFOrder *order = [FFOrder order];
[order addLine:line];
//return the FFOrder to be added to extraOptions
return order;
}
结束SPA软件包开发工具
FujifilmSPASDKDelegate需要您的视图控制器实现命令fujifilmSPASDKFinishedWithStatus:(int) statusCode andMessage: (NSString*) message
。
当Fujifilm SPA SDK完成时,它将返回到父应用程序,调用命令fujifilmSPASDKFinishedWithStatus:andMessage
。您必须按照以下方式实施
#pragma mark -
#pragma mark Fujifilm SPA SDK delegate
-(void) fujifilmSPASDKFinishedWithStatus: (int) statusCode andMessage: (NSString*) message{
NSString *msg;
/**
Status codes that may be sent from Fujifilm SPA SDK. This may require updates if any new codes are added. See documentation for list of status codes.
*/
switch (statusCode){
case kFujifilmSDKStatusCodeFatal:
msg = @"Fatal Error";
break;
case kFujifilmSDKStatusCodeNoImagesUploaded:
msg = @"No Images Uploaded";
break;
case kFujifilmSDKStatusCodeNoInternet:
msg = @"No Internet";
break;
case kFujifilmSDKStatusCodeInvalidAPIKey:
msg = @"Invalid APIKey";
break;
case kFujifilmSDKStatusCodeUserCanceled:
msg = @"User Canceled";
break;
case kFujifilmSDKStatusCodeNoValidImages:
msg = @"No Valid Images";
break;
case kFujifilmSDKStatusCodeTimeout:
msg = @"Timeout Error";
break;
case kFujifilmSDKStatusCodeOrderComplete:
msg = message;
break;
case kFujifilmSDKStatusCodeUploadFailed:
msg = @"Upload Failed";
break;
case kFujifilmSDKStatusCodeInvalidUserIDFormat:
msg = @"Invalid User ID Format";
break;
case kFujifilmSDKStatusCodeInvalidPromoCodeFormat:
msg = @"Invalid Promo Code Format";
break;
case kFujifilmSDKStatusCodeRequiresPhotoPermission:
msg = @"Photo Permission Required";
break;
default:
msg = @"Unknown Error";
}
NSLog(@"fujifilmSPASDKFinishedWithStatus: statusCode: %u message: %@", statusCode, msg);
}
状态代码将是以下值之一
statusCode |
含义 |
---|---|
0 | 致命错误 |
1 | 未上传图片 |
2 | 没有互联网连接 |
3 | 无效的API密钥 |
4 | 用户已取消 |
5 | 没有有效图片 |
6 | 超时 |
7 | 订单完成 |
8 | 上传失败 |
9 | 用户ID格式无效 |
10 | 优惠码格式无效 |
11 | 需要照片权限 |
12 | 合作伙伴已关闭SDK |
您的视图控制器必须处理上述任何一种情况,并像上面那样在代码fujifilmSPASDKFinishedWithStatus:andMessage
中处理。状态代码和消息仅限内部使用,请不要将这些呈现在用户面前。
此外,FujifilmSPASDKDelegate
有可选方法promoCodeDidFailValidationWithError: (int) error
当传入的促销码在SDK中验证失败时,将调用此方法。错误参数是int类型的,对应于失败的原因。提供了可能的错误值作为枚举(FFPromotionError
)。尽管不是必需的,但建议实现此方法以记录问题或通知用户他们的促销无效。下面提供了一个示例实现。
-(void) promoCodeDidFailValidationWithError:(int)error {
NSString *errorReason;
switch(error) {
case 0:
errorReason = @"Promotion Expired";
break;
case 1:
errorReason = @"Promotion Not Activated";
break;
case 2:
errorReason = @"Invalid Discount";
break;
case 3:
errorReason = @"Promotion Disabled";
break;
case 4:
errorReason = @"Promotion Does Not Exist";
break;
case 5:
default:
errorReason = @"Fatal Error";
break;
}
NSLog(@"Promotion is invalid. Cause: %@",errorReason);
}
支付宝支付选项
除了在上述第4步中更新您的info.plist
之外,还必须更新您的应用程序代理。
更新您的数据中心代理
在您的AppDelegate的application:didFinishLaunchingWithOptions
实现中,使用setReturnURLScheme:
与在第4步中设置的值:支付宝支付选项。确保您传入的url与第4步中在您的info.plist
中设置的url匹配。
例如
#import "AppDelegate.h"
#import "Fujifilm_SPA_SDK_iOS_AppSwitch.h"
@implementation AppDelegate
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
[Fujifilm_SPA_SDK_iOS_AppSwitch setReturnURLScheme:@"com.your-company.Your-App.FujifilmSDK.Payments"];
return YES;
}
然后在您的应用程序代理中传递第4步中设置的支付宝支付选项中的支付URL。请确保将下面的“com.your-company.Your-App.FujifilmSDK.Payments”从示例更改为您在第4步中在您的info.plist
中设置的url。
#if __IPHONE_OS_VERSION_MAX_ALLOWED >= 90000
- (BOOL)application:(UIApplication *)application
openURL:(NSURL *)url
options:(NSDictionary<UIApplicationOpenURLOptionsKey,id> *)options {
if ([url.scheme localizedCaseInsensitiveCompare:@"com.your-company.Your-App.FujifilmSDK.Payments"] == NSOrderedSame) {
return [Fujifilm_SPA_SDK_iOS_AppSwitch handleOpenURL:url options:options];
}
return NO;
}
#endif
// If you support iOS 7 or 8, add the following method.
- (BOOL)application:(UIApplication *)application
openURL:(NSURL *)url
sourceApplication:(NSString *)sourceApplication
annotation:(id)annotation {
if ([url.scheme localizedCaseInsensitiveCompare:@"com.your-company.Your-App.FujifilmSDK.Payments"] == NSOrderedSame) {
return [Fujifilm_SPA_SDK_iOS_AppSwitch handleOpenURL:url sourceApplication:sourceApplication];
}
return NO;
}
接收统计事件(可选)
如果您想了解用户在我们的SDK中的行为,我们提供了一种方法,让您可以在用户采取某些操作时监听我们的事件。为了接收这些事件,实现receivedAnalyticsEvent:withAttributes:
代理方法。
这些属性是包含NSDictionary
的NSArray
。在每一个NSDictionary
中,键(如下定义)将对应一个字符串的NSString
值,或布尔和数字的NSNumber
值。以下是如何将数据传递到该方法的示例。
示例代码
-(void) receivedAnalyticsEvent:(NSString *)event withAttributes:(NSArray *)attributes{
if (!event) {
return;
}
if ([event isEqualToString:kAnalyticsEventItemPurchased]) {
[self processItemPurchasedEventWithAttributes:attributes];
}
// Handle any other desired events here
}
-(void) processItemPurchasedEventWithAttributes:(NSArray *)attributes {
NSString *productName = nil;
NSString *productCode = nil;
NSNumber *quantity = @0;
NSNumber *unitPrice = @0.0;
for (NSDictionary *attribute in attributes) {
NSObject *eventValue = [attribute valueForKey:valueKey];
if (eventValue == nil || [eventValue isKindOfClass:[NSNull class]]) {
continue;
}
NSString *attributeName = [attribute valueForKey:attributeKey];
if ([attributeName isEqualToString:kAnalyticsAttributePurchasedProduct]) {
productName = [attribute valueForKey:valueKey];
}
else if ([attributeName isEqualToString:kAnalyticsAttributeProductCodePurchased]) {
productCode = [attribute valueForKey:valueKey];
}
else if ([attributeName isEqualToString:kAnalyticsAttributePurchasedQuantity]) {
quantity = [attribute valueForKey:valueKey];
}
else if ([attributeName isEqualToString:kAnalyticsAttributePurchasedUnitPrice]) {
unitPrice = [attribute valueForKey:valueKey];
}
}
NSLog(@"Received purchased event for product %@ (%@) with quantity %@ and unit price %@", productName, productCode, quantity, unitPrice);
}
事件
事件名称 | 事件值 | 描述 |
---|---|---|
退出 | kAnalyticsEventExit |
当用户退出SDK时发送 |
打印编辑 | kAnalyticsEventPhotoEdited |
当用户编辑打印产品时发送 |
产品编辑 | kAnalyticsEventProductEdited |
当用户编辑任何非打印产品时发送 |
继续购物 | kAnalyticsEventContinueShopping |
当用户从购物车页面或感谢页面点击“继续购物”时发送 |
添加到购物车 | kAnalyticsEventItemAddedToCart |
从组合页面或打印页面将产品添加到购物车时发送 |
组合项 | kAnalyticsEventitemComposed |
当用户前往组合页面编辑产品时发送 |
查看项目详情 | kAnalyticsEventDetailsViewed |
当用户点击导航到产品详情页面时发送 |
购买商品 | kAnalyticsEventItemPurchased |
当用户成功结账时为每个商品发送 |
订单完成 | kAnalyticsEventOrderComplete |
当用户成功结账时发送 |
开始结账 | kAnalyticsEventCheckoutStarted |
当用户从购物车页面点击“继续结账”时发送 |
商店搜索 | kAnalyticsEventStoreSearched |
当用户在商店列表页面搜索商店时发送 |
从购物车中移除 | kAnalyticsEventRemovedFromCart |
当产品从购物车中移除,无论是由于错误还是用户自己删除产品时发送 |
收藏商店 | kAnalyticsEventStoreFavorited |
当用户在商店搜索页面或在结账的第一步收藏商店时发送 |
退出事件属性
事件属性 | 数据类型 | 描述 |
---|---|---|
kAnalyticsAttributeItemsPurchased |
NSNumber (整数) |
购买商品的数量 |
kAnalyticsAttributeExitPoint |
NSString |
用户离开的页面 |
kAnalyticsAttributePromoCode |
NSString |
应用促销代码的逗号分隔列表 |
kAnalyticsAttributeExitMethod |
NSString |
完成按钮/后退按钮/取消按钮 |
kAnalyticsAttributeDeliveryType |
NSString |
零售自提/邮寄订单 |
kAnalyticsAttributePickupLocation |
NSString |
如果是邮寄订单,则N/A。否则,它是用户选择的零售商的名称(沃尔玛、山姆俱乐部等) |
kAnalyticsAttributeAddressValidationErrors |
NSNumber (整数) |
在会话期间发生的地址验证错误数量 |
打印编辑事件属性
没有事件属性
产品编辑事件属性
非事件属性
继续购物事件属性
事件属性 | 数据类型 | 描述 |
---|---|---|
kAnalyticsAttributeScreen |
NSString |
用户点击继续购物页面 |
添加到购物车事件属性
事件属性 | 数据类型 | 描述 |
---|---|---|
kAnalyticsAttributeStatus |
NSNumber (BOOL) |
添加到购物车是否成功或失败 |
kAnalyticsAttributeDuration |
NSNumber (整数) |
添加到购物车所需时间 |
kAnalyticsAttributeItemAdded |
NSString |
添加到购物车的产品名称 |
kAnalyticsAttributeAddToCartDelivery |
NSString |
零售自提/邮寄订单 |
kAnalyticsAttributeAddToCartPickup |
NSString |
如果是邮寄订单,则N/A。否则,它是用户选择的零售商的名称(沃尔玛、山姆俱乐部等) |
kAnalyticsAttributeAddedProductCode |
NSString |
添加到购物车的产品代码 |
组合商品事件属性
事件属性 | 数据类型 | 描述 |
---|---|---|
kAnalyticsAttributeComposedProduct |
NSString |
组合产品的名称 |
kAnalyticsAttributeComposedSource |
NSString |
用户来源。一个是:购物车页面,订单打印页面,产品列表 |
kAnalyticsAttributeComposedDelivery |
NSString |
零售自提/邮寄订单 |
kAnalyticsAttributeComposedPickup |
NSString |
如果是邮寄订单,则N/A。否则,它是用户选择的零售商的名称(沃尔玛、山姆俱乐部等) |
查看商品详情事件属性
事件属性 | 数据类型 | 描述 |
---|---|---|
kAnalyticsAttributeDetailsProduct |
NSString |
用户查看的产品名称 |
kAnalyticsAttributeDetailsSource |
NSString |
用户查看产品的地方。当前仅限“产品列表” |
kAnalyticsAttributeDetailsDelivery |
NSString |
零售自提/邮寄订单 |
kAnalyticsAttributeDetailsPickup |
NSString |
如果是邮寄订单,则N/A。否则,它是用户选择的零售商的名称(沃尔玛、山姆俱乐部等) |
用户购买事件属性
事件属性 | 数据类型 | 描述 |
---|---|---|
kAnalyticsAttributePurchasedProduct |
NSString |
用户购买产品的名称 |
kAnalyticsAttributePurchasedQuantity |
NSNumber (整数) |
订单中行项目的数量 |
kAnalyticsAttributePurchasedDelivery |
NSString |
零售自提/邮寄订单 |
kAnalyticsAttributePurchasedPickup |
NSString |
这是一个邮寄订单,不适用/否则是用户选择的零售商名称(沃尔玛,山姆俱乐部等) |
kAnalyticsAttributeProductCodePurchased |
NSString |
购买商品的条形码 |
kAnalyticsAttributePurchasedUnitPrice |
NSNumber (浮点数) |
产品的单价 |
用户完成订单事件属性
事件属性 | 数据类型 | 描述 |
---|---|---|
kAnalyticsAttributeNumberOfItems |
NSNumber (整数) |
订单中行项目的数量 |
kAnalyticsAttributeNumberOfDistinctItems |
NSNumber (整数) |
订单中不同产品的数量 |
kAnalyticsAttributeOrderPaymentType |
NSString |
用户使用的支付方式名称 |
kAnalyticsAttributeOrderCurrencyType |
NSString |
使用货币类型的ISO 4217货币代码。目前仅限USD。 |
kAnalyticsAttributeOrderSubtotal |
NSNumber (浮点数) |
订单的子总额 |
kAnalyticsAttributeOrderTax |
NSNumber (浮点数) |
对用户进行征税的税额 |
kAnalyticsAttributeOrderShipping |
NSNumber (浮点数) |
用户需支付的总运费 |
kAnalyticsAttributeOrderDiscount |
NSNumber (浮点数) |
因折扣而从订单中扣除的金额 |
kAnalyticsAttributeOrderTotal |
NSNumber (浮点数) |
订单的总金额 |
kAnalyticsAttributeOrderRetailer |
NSString |
如果是邮寄订单,则不适用。否则,是用户选择的零售商名称(沃尔玛,山姆俱乐部等) |
kAnalyticsAttributeOrderServiceType |
NSString |
邮寄订单/零售提货 |
kAnalyticsAttributeOrderDeliveryMethod |
NSString |
用户选择的交货级别:标准/加急/快递。如果是店内取货订单,则为“店内付款”。 |
kAnalyticsAttributeStoreNumber |
NSString |
用户的订单是店内取货的情况下,用户选择的店铺编号 |
结算开始事件属性
事件属性 | 数据类型 | 描述 |
---|---|---|
kAnalyticsAttributeStoreNumber |
NSString |
用户的订单是店内取货的情况下,用户选择的店铺编号 |
kAnalyticsAttributeNumberOfItems |
NSNumber (整数) |
订单中行项目的数量 |
kAnalyticsAttributeNumberOfDistinctItems |
NSNumber (整数) |
订单中不同产品的数量 |
kAnalyticsAttributeOrderCurrencyType |
NSString |
使用货币类型的ISO 4217货币代码。目前仅限USD。 |
kAnalyticsAttributeOrderSubtotal |
NSNumber (浮点数) |
订单的子总额 |
kAnalyticsAttributeIsPreservedCart |
NSNumber (BOOL) |
如果是新订单或保留的购物车 |
kAnalyticsAttributeOrderRetailer |
NSString |
如果是邮寄订单,不适用/否则是用户选择的零售商名称(沃尔玛,山姆俱乐部等) |
kAnalyticsAttributeOrderServiceType |
NSString |
邮寄订单/零售提货 |
存储搜索事件属性
事件属性 | 数据类型 | 描述 |
---|---|---|
kAnalyticsAttributeSearchLatitude |
NSNumber (浮点数) |
用户在商店搜索页面点击“附近寻找”时所在的纬度 |
kAnalyticsAttributeSearchLongitude |
NSNumber (浮点数) |
用户在商店搜索页面点击“附近寻找”时所在的经度 |
kAnalyticsAttributeSearchZip |
NSString |
用户在商店搜索页面输入的邮编 |
kAnalyticsAttributeSearchRadius |
NSNumber (整数) |
用户选择的半径 |
kAnalyticsAttributeSearchResultsCount |
NSNumber (整数) |
根据用户搜索条件找到的店铺数量 |
从购物车删除项目事件属性
事件属性 | 数据类型 | 描述 |
---|---|---|
kAnalyticsAttributeProductRemoved |
NSString |
从用户的购物车中删除的产品名称 |
kAnalyticsAttributeProductCodeRemoved |
NSString |
从用户的购物车中删除的产品代码 |
收藏店铺事件属性
事件属性 | 数据类型 | 描述 |
---|---|---|
kAnalyticsAttributeFavoritedStoreNumber |
NSString |
用户收藏的店铺编号 |
重写图片选择器(可选)
如果您希望我们的SDK在用户尝试在会话中添加更多照片时使用您的图片选择器,您可以实现可选的 requestForAdditionalPhotos 函数。当用户尝试在我们的SDK内部添加更多照片时,我们的SDK将调用此函数。然后您可以调用 completionHandler 以发送用户选择的照片。
示例代码
/**
Optional function (requestForAdditionalPhotos) to implement if you would like to use your own image picker. Our SDK will call this function when a user attempts to add more photos from within our SDK. You can then call the completionHandler to send us the images the user selected.
@param selectedImages - An array of FFImage objects that represents the images the user has in session. This should be referenced in your image picker to display to the user which images are already in their session (show the image as selected). The FFImage object has a uniqueidentifier property that is set to the PHAsset's identifier or the NSURL's path and can be accessed by calling getUniqueIdentifier, [myFFimageObject getUniqueIdentifier]. You can then use this identifier to compare it to the identifiers for the images in your image picker and display to the user the images already in their session.
@param notDeselectable - An array of FFImage objects that represents the images the user is not allowed to deselect because they are being used in a cart or a product builder. This should be referenced to prevent the user from deselecting images in your image picker. The FFImage object has a uniqueidentifier property that is set to the PHAsset's identifier or the NSURL's path and can be accessed by calling getUniqueIdentifier, [myFFimageObject getUniqueIdentifier]. You can then use this identifier to compare it to the identifiers for the images in your image picker and prevent the user from deselecting the image.
@param completionHandler - Call this completion handler to send us the images the user selected.
*/
- (void)requestForAdditionalPhotos:(NSArray<FFImage *> *)selectedImages lockedImages:(NSArray<FFImage *> *)notDeselectable withCompletionHandler:(void (^)(NSArray<FFImage *> * _Nonnull))completionHandler{
//self.requestForAdditionalPhotosCompletionHandler = completionHandler;
//open your image picker and then call the completion handler.
}
完整示例代码
Podfile
pod 'Fujifilm-SPA-SDK', '~> 1.10.12'
ViewController.h
#import "Fujifilm.SPA.SDK.h"
@interface ViewController : UIViewController <FujifilmSPASDKDelegate>{}
/**
Enum of status codes that may be sent from Fujifilm SPA SDK. This may require updates if any new codes are added. See documentation for list of status codes.
*/
typedef enum FujifilmSDKStatusCode {
kFujifilmSDKStatusCodeFatal= 0,
kFujifilmSDKStatusCodeNoImagesUploaded= 1,
kFujifilmSDKStatusCodeNoInternet= 2,
kFujifilmSDKStatusCodeInvalidAPIKey= 3,
kFujifilmSDKStatusCodeUserCanceled= 4,
kFujifilmSDKStatusCodeNoValidImages= 5,
kFujifilmSDKStatusCodeTimeout= 6,
kFujifilmSDKStatusCodeOrderComplete= 7,
kFujifilmSDKStatusCodeUploadFailed= 8,
kFujifilmSDKStatusCodeInvalidUserIDFormat = 9,
kFujifilmSDKStatusCodeInvalidPromoCodeFormat = 10,
kFujifilmSDKStatusCodeRequiresPhotoPermission= 11
} FujifilmSDKStatusCode;
@end
ViewController.m
- (IBAction)launchFujifilmSDK:(id)sender {
FFImage *newFFImage1 = [[FFImage alloc] initWithNSURL:[NSURL URLWithString:@"https://webservices.fujifilmesys.com/venus/imagebank/fujifilmCamera.jpg"]];
FFImage *newFFImage2 = [[FFImage alloc] initWithNSURL:[NSURL URLWithString:@"https://webservices.fujifilmesys.com/venus/imagebank/mustang.jpg"]];
NSMutableArray<FFImage *> *ffimages = [[NSMutableArray alloc] initWithObjects:newFFImage1,newFFImage2, nil];
/*
-------------------------------------------------------------------------------
Create a Fujifilm_SPA_SDK_iOS instance and present the Fujifilm SDK controller.
-------------------------------------------------------------------------------
- Go to http://www.fujifilmapi.com to register for an apiKey.
- Ensure you have the right apiKey for the right environment.
//MAKE SURE TO CHANGE YOUR_API_KEY TO YOUR APIKEY!
*/
Fujifilm_SPA_SDK_iOS *fujifilmSDKOrderController = [[Fujifilm_SPA_SDK_iOS alloc]
initWithApiKey: @"5cb79d2191874aca879e2c9ed7d5747c"
environment: @"Preview"
images: ffimages
userID: @"" //optional
retainUserInfo: YES
promoCode: @"" //optional
launchPage: kHome
extraOptions: nil];
fujifilmSDKOrderController.delegate = self;
//Create a new FujifilmSPASDKNavigation Controller with the orderController as its root
FujifilmSPASDKNavigationController *fujifilmSDKNavigationController = [[FujifilmSPASDKNavigationController alloc] initWithRootViewController:fujifilmSDKOrderController];
/*
---------------------------------------------------------------------------------------
Present the Fujifilm SPA SDK Navigation Controller
---------------------------------------------------------------------------------------
*/
[self presentViewController:fujifilmSDKNavigationController animated:YES completion:nil];
}
-(void) fujifilmSPASDKFinishedWithStatus: (int) statusCode andMessage: (NSString*) message{
NSString *msg;
/**
Status codes that may be sent from Fujifilm SPA SDK. This may require updates if any new codes are added. See documentation for list of status codes.
*/
switch (statusCode){
case kFujifilmSDKStatusCodeFatal:
msg = @"Fatal Error";
break;
case kFujifilmSDKStatusCodeNoImagesUploaded:
msg = @"No Images Uploaded";
break;
case kFujifilmSDKStatusCodeNoInternet:
msg = @"No Internet";
break;
case kFujifilmSDKStatusCodeInvalidAPIKey:
msg = @"Invalid APIKey";
break;
case kFujifilmSDKStatusCodeUserCanceled:
msg = @"User Canceled";
break;
case kFujifilmSDKStatusCodeNoValidImages:
msg = @"No Valid Images";
break;
case kFujifilmSDKStatusCodeTimeout:
msg = @"Timeout Error";
break;
case kFujifilmSDKStatusCodeOrderComplete:
msg = message;
break;
case kFujifilmSDKStatusCodeUploadFailed:
msg = @"Upload Failed";
break;
case kFujifilmSDKStatusCodeInvalidUserIDFormat:
msg = @"Invalid User ID Format";
break;
case kFujifilmSDKStatusCodeInvalidPromoCodeFormat:
msg = @"Invalid Promo Code Format";
break;
case kFujifilmSDKStatusCodeRequiresPhotoPermission:
msg = @"Photo Permission Required";
break;
default:
msg = @"Unknown Error";
}
//NSLog(@"fujifilmSPASDKFinishedWithStatus: statusCode: %u message: %@", statusCode, msg);
}
AppDelegate.m
请确保将“com.your-company.Your-App.FujifilmSDK.Payments”更改为您在第4步:PayPal支付选项中设置的URL。确保将示例代码中的“com.your-company.Your-App.FujifilmSDK.Payments”更改为您在上述第4步info.plist中设置的URL。
#import "AppDelegate.h"
#import "Fujifilm_SPA_SDK_iOS_AppSwitch.h"
@implementation AppDelegate
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
[Fujifilm_SPA_SDK_iOS_AppSwitch setReturnURLScheme:@"com.your-company.Your-App.FujifilmSDK.Payments"];
return YES;
}
- (void)applicationWillResignActive:(UIApplication *)application {
}
- (void)applicationDidEnterBackground:(UIApplication *)application {
}
- (void)applicationWillEnterForeground:(UIApplication *)application {
}
- (void)applicationDidBecomeActive:(UIApplication *)application {
}
- (void)applicationWillTerminate:(UIApplication *)application {
}
#if __IPHONE_OS_VERSION_MAX_ALLOWED >= 90000
- (BOOL)application:(UIApplication *)application
openURL:(NSURL *)url
options:(NSDictionary<UIApplicationOpenURLOptionsKey,id> *)options {
if ([url.scheme localizedCaseInsensitiveCompare:@"com.your-company.Your-App.FujifilmSDK.Payments"] == NSOrderedSame) {
return [Fujifilm_SPA_SDK_iOS_AppSwitch handleOpenURL:url options:options];
}
return NO;
}
#endif
// If you support iOS 8, add the following method.
- (BOOL)application:(UIApplication *)application
openURL:(NSURL *)url
sourceApplication:(NSString *)sourceApplication
annotation:(id)annotation {
if ([url.scheme localizedCaseInsensitiveCompare:@"com.your-company.Your-App.FujifilmSDK.Payments"] == NSOrderedSame) {
return [Fujifilm_SPA_SDK_iOS_AppSwitch handleOpenURL:url sourceApplication:sourceApplication];
}
return NO;
}
@end
附加说明和调试帮助
以下是一些集成富士胶片SPA iOS SDK时的说明。
使用要求
- 手机必须能够访问互联网以启动SDK,并在整个结账过程中保持访问。
- 在给定的结账过程中,最多可以向SDK发送100张图片。
- 仅支持
jpeg
、png
和heic
文件。 - 单个文件的最大大小为20MB。
通用错误
- 请确保您已更新
info.plist
文件,包含了上述列出的所需数据(NSAppTransportSecurity
、NSLocationWhenInUseUsageDescription
、NSContactsUsageDescription
和NSPhotoLibraryUsageDescription
)。
阻止SDK启动的错误
- 没有有效图片
- 无网络访问
- 无效的APIKey。请确保您使用的APIKey与您传递的环境字符串相匹配(“stage”,“preview”,“production”)
- 缺少所需框架:AddressBook、AddressBookUI、MobileCoreServices、SystemConfiguration、AssetsLibrary、ImageIO和Photos
将取消SDK的错误
- 所有图片未上传完成前网络或互联网访问丢失
- 所有图片上传失败/没有剩余图片可结账
这些错误将使控制权返回到父应用程序,并带有代表错误原因的状态码和消息调用fujifilmSPASDKFinishedWithStatus:andMessage
。
将阻止特定图片上传或处理的错误
- 图像大小超过20MB
- 图像格式不受支持图像文件损坏或上传失败,使其损坏
这些错误不会取消SDK,因此它们不会直接向fujifilmSPASDKFinishedWithStatus:andMessage
返回错误代码。但是,如果删除足够多的图像使得没有剩余的图像,那么SDK将被终止。
反馈
我们非常关注您的反馈!如果您遇到任何问题,有任何建议,或者想告诉我们哪些东西工作得很好,请给我们发送电子邮件至 [email protected] 或者使用 https://www.fujifilmapi.com/contact-us 上的网页表单。
许可协议
重要 - 在使用以下计算机代码(“代码”)之前,请仔细阅读以下条款和条件。代码的使用风险自负。代码按“原样”提供,包含任何和所有故障、缺陷和错误,且不提供任何类型的保证。富士胶片对代码及其在操作中或任何特定应用或使用中的缺陷不承担责任,包括但不限于明示、默示或法律的保证,包括但不限于关于适销性、适用于特定目的和非侵权的默示保证。富士胶片不对代码不符合您的需求或期望、代码在任何硬件、操作系统或任何软件上运行、代码操作的中断、不受有害组件或错误的影响,或已知的或发现的错误将被纠正承担责任。富士胶片不对您或任何第三方因代码而产生的任何利润损失、数据丢失、计算机失败或损坏、业务中断或其他损害承担责任,包括但不限于象征性、惩戒性、特殊、法定、直接、间接、偶然、后果性、侵权或补偿性损害赔偿,包括但不限于在使用或无法使用代码时,即使富士胶片已被告知或意识到了此类损害的可能性。