PEAppTransaction-Logger 1.0.1

PEAppTransaction-Logger 1.0.1

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

Paul Evans维护。



 
依赖
FMDB~> 2.5
PEObjc-Commons~> 1.0.1
PEHateoas-Client~> 1.0.1
CocoaLumberjack~> 1.9
 

  • 作者
  • Paul Evans

PEAppTransaction Logging Framework的iOS静态库客户端。

PEAppTransaction Logging Framework

PEAppTransaction Logging Framework是一个用于捕捉应用内部重要事件的框架。它由3个主要组件组成:(1) 数据存储,(2) 网络服务层和(3)客户端库。

此存储库PEAppTransaction-Logger代表了框架的iOS客户端库。

动机

创建PEAppTransaction日志框架的动机很简单:系统地跟踪应用程序(最终用户应用程序或其他应用程序)中的重要事件。您可以使用此框架记录有关您的应用程序的信息,例如

  • 用户填写表单所需的时间。
  • 进行Web服务调用的往返时间。
  • 用户在没有完成call-to-action的情况下离开屏幕的频率。

对使用框架进行日志记录的使用案例集是开放的。您可以使用它进行基本的A/B测试、跟踪性能相关指标以及更多。

关于PEAppTransaction-Logger

PEAppTransaction-Logger是用于作为PEAppTransaction日志框架客户端的iOS静态库。PEAppTransaction-Logger可以创建和本地保存事务和事务日志实例;事务用于跟踪与应用程序中用例相关的事件;事务日志用于跟踪特定用例的特定时间戳事件。

这些事务和事务日志存储在本地SQLite数据库中,并打算持久化到远程数据存储供以后分析)。远程数据存储旨在通过网络服务层进行管理。

PEAppTransaction-DataStore存储库包含一个基于Datomic的数据存储架构。

PEAppTransaction-ServerResources 仓库存储了一个由 Clojure 编写的 Web 服务层实现,并利用了 Liberator 框架。

使用指南

PEAppTransaction日志框架通过其客户端库暴露了三种主要抽象:(1) 事务,(2) 事务日志和(3) 事务管理器。

事务是一个用于跟踪应用程序 用例 信息的内容容器。用例可以是任何事情;这取决于你。例如,一个用例可能是 登录 应用程序。或者 创建账户提交订单。当你的应用中启动了用例(通常是用户启动的),你首先需要创建一个合适的交易实例。但在创建交易实例之前,你首先需要创建一个交易管理器。对于你的应用程序,你应该只有1个交易管理器,因此建议你在应用设置代理的 application:didFinishLaunchingWithOptions: 函数中创建实例。

如上所述,PEAppTransaction-Logger是PEAppTransaction日志框架中的一个iOS静态库 客户端。该框架假设有一个面向后端数据存储的Web服务。使用TLTransactionManager的一个实例将本地上存储的事务/事务日志项通过Web服务刷新到远程存储。

PEAppTransaction-Logger利用 PEHateoas-Client 与Web服务交互。为了创建TLTransactionManager实例,我们首先需要创建一个HCRelationExecutor实例。

// Needed by TLTransactionManager instance for interacting with web service
HCRelationExecutor *relExec =
  [[HCRelationExecutor alloc] initWithDefaultAcceptCharset:[HCCharset UTF8]
                                     defaultAcceptLanguage:@"en-US"
                                 defaultContentTypeCharset:[HCCharset UTF8]
                                  allowInvalidCertificates:NO];

NSFileManager *fileMgr = [NSFileManager defaultManager];
// URL of local folder to contain SQLite data file
NSURL *sqliteDataFileFolderUrl = [fileMgr URLForDirectory:NSLibraryDirectory
                                                 inDomain:NSUserDomainMask
                                        appropriateForURL:nil
                                                   create:YES
                                                    error:nil];
// URL of SQLite data file
NSURL *sqliteDataFileUrl =
  [sqliteDataFileFolderUrl URLByAppendingPathComponent:@"peapptxns.data"];

// Finally we create the transaction manager instance
TLTransactionManager *txnMgr =
  [[TLTransactionManager alloc] initWithDataFilePath:[sqliteDataFileUrl absoluteString]
                                 userAgentDeviceMake:[PEUtils deviceMake] // from PEObjc-Commons
                                   userAgentDeviceOS:[[UIDevice currentDevice] systemName]
                            userAgentDeviceOSVersion:[[UIDevice currentDevice] systemVersion]
                                    relationExecutor:relExec
                                          authScheme:@"auth-scheme"
                                  authTokenParamName:@"auth-token"
                                  contentTypeCharset:[HCCharset UTF8]
                                  apptxnResMtVersion:@"1.0.0"
                                               error:nil]; // provide non-nil err handler in 'real' code

// Set the URI of the remote 'transactions' REST resource.  How you get this
// is dependent on your application.
NSURL *txnStoreResourceUri = ...;
[txnMgr setTxnStoreResourceUri:txnStoreResourceUri];

// Authentication token used when invoking web service layer (application
// dependent)
NSString *authToken = ...;
[txnMgr setAuthToken:authToken];

有了事务管理器实例,我们现在可以开始记录事项了。假设你有一个需要用户 登录 的应用程序,并且你考虑,为了事务日志记录的目的,登录是一个你想要用PEAppTransaction日志框架跟踪事件的 用例。假设你有一个登录屏幕的视图控制器。在视图控制器的 viewDidLoad 函数中创建一个 TLTransaction 实例来跟踪 登录 用例的事件。

但在我们这样做之前,简要侧边栏:在PEAppTransaction日志框架中建模的交易 用例 用简单的整数值表示。所以例如,我们的 登录 用例可能有数字 0 与之相关。我们的 注册账户 用例可能有数字 1 与之相关,等等。该框架还使用数字来表示可以记录在任何用例(交易)上的单个事件。为了保持你的代码井井有条,建议你创建一个 .h 文件来集中定义你的交易和交易事件用例编号。假设我们有一个这样的 .h 文件

// Define use case values
typedef NS_ENUM(NSInteger, PEAppTxnUsecase) {
  PEAppTxnLogin,
  PEAppTxnCreateAccount,
  ...
};

// Define use case event values
typedef NS_ENUM(NSInteger, PETxnLoginUsecaseEvent) {
  PETxnLoginEvtInitiated,
  PETxnLoginEvtCanceled,
  PETxnLoginEvtRemoteCommReqInitiated,
  PETxnLoginEvtRemoteProcStarted,        // recorded server-side
  PETxnLoginEvtRemoteProcDoneErrOccured, // recorded server-side
  PETxnLoginEvtRemoteProcDoneInvalid,    // recorded server-side
  PETxnLoginEvtRemoteProcDoneSuccess,    // recorded server-side
  PETxnLoginEvtRemoteCommRespReceived
};

...

现在在你的登录控制器的 viewDidLoad 函数中,创建一个交易实例,并创建一个表示用户已启动 登录 用例事件的记录。

// error handling block
TLDaoErrorBlk errorBlk = ^(NSError *err, int errCode, NSString *errDesc) {
  NSLog(@"Error attempting to persist txn log to local SQLite store: %@", err);
};

// Creating the transaction instance for our 'logging in' use case
TLTransaction *loggingInTxn = [_txnMgr transactionWithUsecase:@(PEAppTxnLogin)];

// Log the fact the user has initiated the act of logging in.
[loggingInTxn logWithUsecaseEvent:@(PETxnLoginEvtInitiated) error:errorBlk];

如果用户在某种程度上 取消 他们的登录尝试(点击'后退'按钮或'取消'按钮等),你也可以记录这个。

// Log the fact the user has canceled logging in
[loggingInTxn logWithUsecaseEvent:@(PETxnLoginEvtCanceled) error:errorBlk];

当用户点击登录按钮时,在视图控制器对认证服务的(假设的)Web服务调用之前,你可以写入日志

// Log the fact that your app initiated the web service call to log in the user
[loggingInTxn logWithUsecaseEvent:@(PETxnLoginEvtRemoteCommReqInitiated) error:errorBlk];

并且在Web服务调用完成处理程序或回调中,你可以记录你已获得响应

// Log the fact that the 'log in' web service response was received.
[loggingInTxn logWithUsecaseEvent:@(PETxnLoginEvtRemoteCommRespReceived) error:errorBlk];

每个写入的日志都会标上时间戳,每个日志实例都与对应的交易实例相关联(在上面的代码中,我们的loggingInTxn实例)。每个交易实例都由一个GUID字符串标识。

相关信息,请再次查看我们上面定义的包含用例和用例事件整数值的 .h 文件。请注意,一些用例事件值被注释为 "// recorded server-side"。在当前框架中,假设服务器端代码可以为特定的交易实例提供日志数据。为了实现这一点,在上述示例中,用于用户身份验证的Web服务调用来包含一个包含交易实例GUID的自定义HTTP头。通过这种方式,实现用户身份验证检查的服务器端代码可以记录它已经接收到的入站Web服务请求,并可以记录其他用例事件;它可以这样做,因为它拥有包含交易实例的GUID。

顺便说一句,如果您也在您的应用程序中使用 PEHateoas-Client 来与您的Web服务集成,各种 doXXX 函数中包含一个 otherHeaders:(NSDictionary *)otherHeaders 部分,这是挂载此类自定义请求头的好地方。

将本地存储的交易数据刷新到远程数据存储

当用户使用您的应用时,交易实例和交易日志实例会积累在您应用的SQLite数据库中。为了使交易日志数据具有价值,它需要发送到您的服务器以便以后(可操作)分析。TLTransactionManager提供了2个函数来完成这项工作

  • synchronousFlushTxnsToRemoteStoreWithRemoteStoreBusyBlock
  • asynchronousFlushTxnsToRemoteStore

asynchronousFlushTxnsToRemoteStore: 是推荐使用的函数,因为它在后台线程上执行远程刷新。它接受一个 NSTimer * 实例,以便可以由计时器调用。如果远程存储前端的Web服务响应2XX,则从本地SQLite数据库中删除交易日志数据。

PEAppTransaction日志框架规定,客户端只需将交易日志数据集以(HTTP)POST方式发送到远程存储前端Web服务。如果您选择在此实现自己的前端Web服务(而不是利用 PEAppTransaction-ServerResources),以下是一些您需要了解的信息

HTTP POST刷新调用中JSON请求体的格式

以下是一个包含单个交易实例和2个子交易日志实例的消息示例。

{"apptxns" : [
    {"apptxn/usecase" : 17,
     "apptxn/user-agent-device-os-version" : "8.1.2",
     "apptxn/id" : "TXN17-586AB00B-F16E-4AE6-8A91-0210264925C7",
     "apptxn/user-agent-device-make" : "iPhone7,2",
     "apptxn/user-agent-device-os" : "iPhone OS",
     "apptxn/logs" : [
         {"apptxnlog/usecase-event" : 0,
          "apptxnlog/in-ctx-err-code" : null,
          "apptxnlog/timestamp" : "Fri, 06 Feb 2015 00:59:27 EST"},
         {"apptxnlog/usecase-event" : 1,
          "apptxnlog/in-ctx-err-code" : null,
          "apptxnlog/timestamp" : "Fri, 06 Feb 2015 01:23:05 EST"}
      ]
    }
  ]
}

POST请求的Content-Type头将类似:application/vnd.peapptxnlog.apptxnset-v0.0.1+json;charset=UTF-8

版本部分(0.0.1位)基于您提供的TLTransactionManager初始化器中的apptxnResMtVersion:部分。字符集部分(UTF-8)基于您提供的TLTransactionManager初始化器中的contentTypeCharset:部分。