FsprgEmbeddedStoreMac 1.0.13

FsprgEmbeddedStoreMac 1.0.13

测试已测试
Lang语言 Obj-CObjective C
许可证 MIT
发布最后发布2015年1月

Lars Steiger维护。



  • FastSpring

简介

FastSpring 提供了一款创新的电子商务引擎,旨在克服困扰软件电子商务公司的易用性、客户服务和成本等问题。

FastSpring 的嵌入商店由一个控制器和一些集成点以及 WebKit 的 WebView 组成。它薄而灵活,使您可以根据应用程序的最佳方式集成 FastSpring。

要了解其工作原理,SDK 提供了两个示例和一个测试应用程序。所有源代码均在 MIT 许可下发布。它接受贡献,并且其使用不受限制。请参阅 RELEASE_NOTES.html 了解最新更改。

FsprgEmbeddedStore

FsprgEmbeddedStore 主要由 FsprgEmbeddedStoreController 和其代理协议 FsprgEmbeddedStoreDelegate 组成。

FsprgEmbeddedStoreController 控制连接的 WebView(WebKit)。它提供了加载商店、监控页面加载进度以及测试当前连接是否安全(https)的功能。

@interface FsprgEmbeddedStoreController : NSObject
    - (WebView *)webView;
    - (void)setWebView:(WebView *)aWebView;
    - (id <FsprgEmbeddedStoreDelegate>)delegate;
    - (void)setDelegate:(id <FsprgEmbeddedStoreDelegate>)aDelegate;

    - (void)loadWithParameters:(FsprgStoreParameters *)parameters;
    - (void)loadWithContentsOfFile:(NSString *)aPath;
    - (BOOL)isLoading;
    - (double)estimatedLoadingProgress;
    - (BOOL)isSecure;
    - (NSString *)storeHost;
@end

此外,它还定义了由 FsprgEmbeddedStoreDelegate 协议指定的某些集成点。它通知团队初始加载商店、随后的页面加载和订单完成。还可以定义一个视图向用户显示订单确认。

typedef enum {
    FsprgPageFS,
    FsprgPagePayPal,
    FsprgPageUnknown
} FsprgPageType;

@protocol FsprgEmbeddedStoreDelegate <NSObject>
    - (void)didLoadStore:(NSURL *)url;
    - (void)didLoadPage:(NSURL *)url ofType:(FsprgPageType)pageType;
    - (void)didReceiveOrder:(FsprgOrder *)order;
    - (NSView *)viewWithFrame:(NSRect)frame forOrder:(FsprgOrder *)order;
    - (void)webView:(WebView *)sender didFailProvisionalLoadWithError:(NSError *)error forFrame:(WebFrame *)frame;
    - (void)webView:(WebView *)sender didFailLoadWithError:(NSError *)error forFrame:(WebFrame *)frame;
@end

如何嵌入

使用我们的 CocoaPod 或执行以下步骤。

  1. 克隆或分支我们的仓库。
  2. 在 Xcode 中打开您的项目。
  3. 执行“文件”>“添加文件”>“您的应用程序”... 并选择目录 FsprgEmbeddedStoreMac/FsprgEmbeddedStore。我们建议取消选中 将项复制到目标组的文件夹中 的选项。
  4. 如果不需要 FsprgEmbeddedStore 单元测试,请从您的项目中删除对 FsprgEmbeddedStoreMac/FsprgEmbeddedStore/Tests 的引用。
  5. 将 WebKit.framework 和 Security.framework 添加到您的目标中。

如何使用

  1. 阅读我们的 集成指南 了解如何启用您的商店以进行 FsprgEmbeddedStore 请求。
  2. 创建一个 AppController 并使用 FsprgEmbeddedStoreController。Example1.app 和 Example2.app 展示了如何详细实现 AppController
  3. 打开 MainMenu.nib。
  4. 在 Interface Builder 中创建一个 AppController 实例。
  5. 将WebKit控件拖到屏幕上,并将其连接到AppController的storeView出口。

示例:AppController.h

@interface AppController : NSObject <FsprgEmbeddedStoreDelegate> {
    IBOutlet WebView* storeView;
    FsprgEmbeddedStoreController *storeController;
}

- (FsprgEmbeddedStoreController *)storeController;
- (void)setStoreController:(FsprgEmbeddedStoreController *)aStoreController;

- (IBAction)load:(id)sender;

@end

如何提供对Web商店的链接

有时用户更喜欢使用Web商店而不是嵌入式商店。使用FsprgStoreParameters构建Web商店的URL,并通过使用NSWorkspace在默认浏览器中打开它。

- (IBAction)openWebStoreInBrowser:(id)sender
{
    FsprgStoreParameters *parameters = [FsprgStoreParameters parameters];
    [parameters setOrderProcessType:kFsprgOrderProcessDetail];
    [parameters setStoreId:@"your_store" withProductId:@"your_product"];
    [parameters setMode:kFsprgModeTest];
    [[NSWorkspace sharedWorkspace] openURL:[parameters toURL]];
}

FsprgOrder API

FsprgOrder对象代表通过FsprgEmbeddedStoreDelegate协议返回的订单确认。为了避免您深入头文件,以下部分包含真实世界的示例和FsprgOrder及其相关类的简化API文档。

示例

以下是一个真实世界的示例,展示了从已完成的许可证中获取序列号的最常见情况。感谢来自SmileOnMyMac的Greg Scown分享。

- (void)didReceiveOrder:(FsprgOrder *)order
{
   NSEnumerator *e = [[order orderItems] objectEnumerator];
   FsprgOrderItem *item = nil;
   while (item = [e nextObject]) {
       if ([[item productName] hasPrefix:@"MyItemNamePrefix"]) {
           NSString *userName = [[item license] licenseName];
           NSString *serialNumber = [[item license] firstLicenseCode];
           if ([[[item productName] lowercaseString] rangeOfString:@"upgrade"].location != NSNotFound) {
               NSLog(@"Upgrade purchase:\nName: %@\nSerial #: %@", userName, serialNumber);
           } else {
               NSLog(@"Full purchase:\nName: %@\nSerial #: %@", userName, serialNumber);
           }
       }
   }
}

FsprgOrder.h

- (BOOL)orderIsTest;
- (NSString *)orderReference;
- (NSString *)orderLanguage;
- (NSString *)orderCurrency;
- (NSNumber *)orderTotal;
- (NSNumber *)orderTotalUSD;
- (NSString *)customerFirstName;
- (NSString *)customerLastName;
- (NSString *)customerCompany;
- (NSString *)customerEmail;
- (FsprgOrderItem *)firstOrderItem; // Shortcut for [[self orderItems] objectAtIndex:0].
- (NSArray *)orderItems;

FsprgOrderItem.h

- (NSString *)productName;
- (NSString *)productDisplay;
- (NSNumber *)quantity;
- (NSNumber *)itemTotal;
- (NSNumber *)itemTotalUSD;
- (NSString *)subscriptionReference; // See https://support.fastspring.com/entries/236487-api-subscriptions
- (NSURL *)subscriptionCustomerURL; // This URL can be presented to the customer to manage their subscription.
- (FsprgFulfillment *)fulfillment;
- (FsprgLicense *)license;           // Shortcut for [[self fulfillment] valueForKey:@"license"]
- (FsprgFileDownload *)download;     // Shortcut for [[self fulfillment] valueForKey:@"download"]

FsprgFulfillment.h

/*!
 * @param aKey type of fulfillment (e.g. license, download)
 * @result Specific fulfillment information (FsprgLicense, FsprgFileDownload).
 */
- (id)valueForKey:(NSString *)aKey;

FsprgLicense.h

- (NSString *)licenseName;
- (NSString *)licenseEmail;
- (NSString *)licenseCompany;
- (NSString *)firstLicenseCode;
- (NSArray *)licenseCodes;
- (NSDictionary *)licensePropertyList;
- (NSURL *)licenseURL;

FsprgFileDownload.h

- (NSURL *)fileURL;

Example1.app

Example1 app通过访问MacOS的AddressBook来设置默认的联系人字段。订单确认是通过Interface Builder内部构建的视图XIB。

Example1.app Screenshot

如何实现AppController

  • init中将self设置为委托
  • awakeFromNib中将webView设置为FsprgEmbeddedStoreController
  • load:委托给FsprgEmbeddedStoreControllerloadWithParameters:
  • 通过使用NSViewController(在此为OrderViewController)实现viewWithFrame:forOrder:,该NSViewController使用Interface Builder内部定义的视图XIB

从AppController.h提取内容

@implementation AppController

- (id) init
{
    self = [super init];
    if (self != nil) {
        [self setStoreController:[[[FsprgEmbeddedStoreController alloc] init] autorelease]];
        [[self storeController] setDelegate:self];
    }
    return self;
}

- (void)awakeFromNib
{
    [[self storeController] setWebView:storeView];
    [self load:nil];
}

- (IBAction)load:(id)sender
{
    FsprgStoreParameters *parameters = [FsprgStoreParameters parameters];
    ...
    [[self storeController] loadWithParameters:parameters];
}

- (NSView *)viewWithFrame:(NSRect)frame forOrder:(FsprgOrder *)order
{
    OrderViewController *orderViewController = [[OrderViewController alloc] initWithNibName:@"OrderView" bundle:nil];
    [orderViewController setRepresentedObject:order];

    [[orderViewController view] setFrame:frame];
    return [orderViewController view];
}

@end

如何创建视图XIB

  • 通过扩展NSViewController创建类OrderViewController
  • 创建视图XIB
  • 将文件的所有者类设置为OrderViewController
  • 将文件所有者的视图出口分配给主“自定义视图”
  • 绑定控件(例如标签)到表示对象(=FSOrder),向用户展示订单确认数据

Example2.app

Example2使用HTML、CSS和JavaScript展示订单确认。它使用Matt Gemmell的MGTemplateEngine来渲染HTML。

Example2.app Screenshot

如何创建订单HTML视图

AppController看起来与Example1相同。唯一的区别是viewWithFrame:forOrder:的实现。它使用WebFrameloadHTMLString:baseURL:方法来加载HTML并将其展示给用户。

从 AppController.h 中提取

@implementation AppController

- (NSView *)viewWithFrame:(NSRect)frame forOrder:(FsprgOrder *)order
{
    MGTemplateEngine *engine = [MGTemplateEngine templateEngine];
    [engine setMatcher:[ICUTemplateMatcher matcherWithTemplateEngine:engine]];

    NSString *templatePath = [[NSBundle mainBundle] pathForResource:@"OrderView" ofType:@"html"];
    NSDictionary *variables = [NSDictionary dictionaryWithObject:order forKey:@"order"];
    NSString *htmlString = [engine processTemplateInFileAtPath:templatePath withVariables:variables];

    NSString *templateDirectory = [templatePath substringToIndex:[templatePath length]-[[templatePath lastPathComponent] length]];
    NSURL *baseURL = [NSURL URLWithString:[NSString stringWithFormat:@"file://%@", templateDirectory]];

    WebFrame *webFrame = [[[WebView alloc] initWithFrame:frame] mainFrame];
    [webFrame loadHTMLString:htmlString baseURL:baseURL];

    return [webFrame frameView];
}

@end

由于我们将 FsprgOrder 设置为一个变量,现在我们可以在模板内部方便地访问订单信息。baseURL 指向资源目录。因此,我们可以访问 CSS 文件来美化视图,以及 JavaScript 来添加一些行为和良好效果。

OrderView.html

<html>
    <head>
        <meta http-equiv='Content-Type' content='text/html; charset=UTF-8' />
        <title>Your Order</title>
        <link rel="stylesheet" type="text/css" href="OrderView.css">
        <script src="jquery-1.4.2.js"></script>
        <script language="javascript">
            $(function() {
                $(".orderItemsTitle").fadeIn(2000);
                $(".orderItem").fadeIn(2000);
            });
        </script>
    </head>
    <body>
        <div class="thankYouNote">Thanks for your order {{ order.customerFirstName }}!</div>
        <div class="orderItemsTitle">Ordered items</div>
        {% for orderItem in order.orderItems %}
        <div class="orderItem">
            <div class="productName">
            {{ orderItem.productName }}
            {% if orderItem.quantity > 1 %} ({{ orderItem.quantity }}) {% /if %}
            </div>
            <div class="licenseKey">Your license key: {{ orderItem.license.firstLicenseCode }}</div>
        </div>
        {% /for %}
    </body>
</html>

Test.app

Test 应用程序允许您探索 FastSpring 的参数,并显示原始订单确认结果(XML plist 格式)。

Test.app 设置截图  Test.app 结果截图

您还可以将确认结果存储为 plist 文件,并使用 FsprgEmbeddedStoreControllerloadWithContentsOfFile: 方法来加载它。这简化了订单确认视图的开发和测试。