Reader SDK For iOS(1.2.1.0)说明

  1. 简介

  2. 最新版下载地址:http://www.ycanpdf.cn/download/pages/readersdk/ios.html

    ReaderSDK.framwork是优看科技出品的ios平台下阅读器程序库。只需简单的接口调用,即可使你的app拥有阅读功能,适合快速开发阅读器的开发者。如需高级定制功能,可使用本公更底层的产品:PDF SDK for iOS 和 TXT SDK for ios。

    • 支持的文件格式:pdf、txt。

    • 支持语言:Objective-c。

    • 支持最低系统:ios 8.0。

    • 开发工具:xcode 8.2.1。

    • 接口分2类:ReaderViewController类接口和delegate回调接口。

  3. 在xcode中集成:

    1. 选择要集成的 targets,切换到 Build Phases 标签。

    2. Link Binary With Libaraies 中分别添加 PDFSDK.frameworkSecurity.frameworklibiconv.tbd和c++动态库libc++.tbd

    3. Copy Bundle Resources 中添加 SDKResource.bundle

  4. 具体接口调用流程(Objective-c代码为例)

  5. 调用sdk接口前,需要在app启动时注册sdk,否则sdk不可用。可以通过在线注册开发者账号,获取appKey和appSecret,详情请参考registerSDKWithAppKey函数的注意部分。注册示例代码:

    // AppDelegate 回调函数
    - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
        [YCANPDFViewController registerSDKWithAppKey:@"5E2FADFEAE365427FFFF041412FE8C5"
            appSecret:@"13C49F0807DF56809E492DEF0CDCD"
            completeHandler:^(NSDictionary *info, NSError *error)
        {
            NSLog(@"info=%@, error=%@", info, error);
        }];
        return YES;
    }


    下面的示例程序首先创建了ReaderViewController对象,然后切换到阅读界面。由于ReaderViewController是UIViewController子类,可以调用UIViewController的presentViewController:animated:completion:            方法显示阅读界面,(如需高级定制功能,可使用本公更底层的产品:PDF SDK for iOS 和 TXT SDK for ios)。            
    注意: 需要引入头文件<ReaderSDK/ReaderSDK.h>。

    NSString *path =  // pdf/txt file path;
    NSString* password = nil;
    RDErrorCode code;
    
    // 为pdf设置默认TrueType字体文件,不必每次打开时都调用,建议在app启动时调用。
    [ReaderViewController setDefaultTrueTypeFontWithFontPath:fontPath];
    
    ReaderViewController *rd = [ReaderViewController instanceWithPath:path password:password openFileType:rd_open_file_type_unknow delegate:nil error:code];
    if( rd )
        [self presentViewController:rd animated:YES completion:nil];
    } else {
       NSString *msg = nil;
            switch (code) {
                case rd_err_invalid_path:
                    msg = @"无效的文件路径";
                    break;
                case rd_err_file_is_not_exist:
                    msg = @"文件不存在";
                    break;
                case rd_err_can_not_open:
                    msg = @"无法打开";
                    break;
                case rd_err_password_is_error:
                    msg = @"密码错误";
                    break;
                case rd_err_file_damaged :
                    msg = @"文件损坏";
                    break;
                case rd_err_file_is_encrypted :
                    msg = @"文件已加密";
                    break;
                case rd_err_file_has_no_page:
                    msg = @"文件无页面";
                    break;
                case rd_err_file_is_invalid :
                    msg = @"文件无效";
                    break;
                case rd_err_verification_failed :
                    msg = @"验证失败";
                    break;
                case rd_err_reading_time_interval_is_over:
                    msg = @"时段用完";
                    break;
                case rd_err_reading_count_is_over:
                    msg = @"次数用完";
                    break;
                case rd_err_not_in_reading_time_interval:
                    msg = @"不在时段内";
                    break;
                case rd_err_reading_duration_is_over:
                    msg = @"时长用完";
                    break;
                case rd_err_can_not_open_two_files_in_same_time:
                    msg = @"无法同时打开两文件";
                    break;
                case rd_err_encoding_is_unkown:
                    msg = @"编码未知";
                    break;
                case rd_err_unkown:
                default:
                    msg = @"未知错误";
                    break;
            }
        }
    }

    在用户阅读过程中,可能需要知道他们的某些阅读行为,为此开发者可以指定ReaderViewController对象的delegate 并实现RDDelegate协议即可。细节请参考RDDelegate说明

  6. 接口说明

    1. ReaderViewController类接口

    2. ReaderViewController 定义如下:(摘自ReaderSDK.h)

      @interface ReaderViewController : UIViewController
      // register sdk api
      +(void)registerSDKWithAppKey:(NSString*)appKey
          appSecret:(NSString*)appSecret
          completeHandler:(void(^)(NSDictionary* info, NSError *error))completeHandler;
      +(void)setDefaultTrueTypeFontWithFontPath:(NSString*)path;
          
      +(instancetype)instanceWithPath:(NSString*)path
                              password:(NSString*)password
                          openFileType:(RDOpenFileType)fileType
                              delegate:(id<RDDelegate>)delegate
                              error:(RDErrorCode*)errCode;  
      +(void)removeBookCacheWithPath:(NSString *)path;
      +(NSString*)configFilePath;
      +(NSString*)version;       
      -(UIImage*)bookThumbnailAtPage:(NSUInteger)pageNum boundsSize:(CGSize)boundsSize useQuartz:(BOOL)useQuartz;
      -(NSArray<RDBookmarkItem*>*)bookmarkArray;
      -(NSArray<RDAnnotItem*>*)annotArray;
      -(void)close;
      @property(nonatomic, strong, readonly) NSString *path;
      @property (nonatomic, assign, readonly) RDOpenFileType fileType;
      
      // drm api 仅支持pdf
      +(long)isFileEncWithPath:(NSString*)path;
      +(long)makeDRMFileWithDestPath:(NSString*)destPath srcPath:(NSString*)srcPath ctrlInfo:(NSString*)info;
      @end

      接口详细说明:

      1. +(void)registerSDKWithAppKey:(NSString*)appKey appSecret:(NSString*)appSecret completeHandler:(void(^)(NSDictionary* info, NSError *error))completeHandler;

        • 功能:

        • 注册sdk。

        • 参数:

        • appKey 注册账号后得到的字符串(App Key)。

          appSecret 注册账号后得到的字符串(App Secret)。

          completeHandler 可以为nil,注册完成后调用。

        • 返回值:

        • 无。

        • 注意:

          • 开发者账号登陆/注册网址http://sdk.ycanpdf.com

          • 注册开发者账号时请注意:填写的 Bundle ID 必须要与 app 的 Bundle ID 一致。

          • app Bundle ID 获取方法:

            1. 选中app target

            2. 切换到 General标签。

            3. 展开IdentifyBundle Identifier 的值就是要填的 Bundle ID

          • 调用方式和时机,请参考:注册SDK代码示例

      2. + (void)setDefaultTrueTypeFontWithFontPath:(NSString*)path;

        • 功能:

        • 设置默认TrueType字体文件。

        • 参数:

        • path TrueType字体文件路径。

        • 返回值:

        • 无。

        • 注意:

        • 由于存在非内嵌字体的pdf文件,解析这类文件时,需要pdf文件外部提供默认字体文件,否则页面文字会显现不正常。调用此接口,可以为解析引擎提供默认字体。提供的字体文件必须是完整的 TrueType 类型的中文字体文件,建议提供 “黑体”字体文件(simhei.ttf)。



      3. + (instancetype)instanceWithPath:(NSString*)path
                                password:(NSString*)password
                            openFileType:(RDOpenFileType)fileType
                                delegate:(id<RDDelegate>)delegate
                                   error:(RDErrorCode*)errCode;
                           
        • 功能:

        • 打开文件。

        • 参数:

        • path 文件路径。

          password pdf文件密码,某些pdf文档受密码保护,需要密码才能打开。

          fileType 文件类型,请参考RDOpenFileType

          delegate 阅读器委托,遵循RDDelegate,可为nil。

          errCode 错误码,请参考RDErrorCode

        • 注意:

        • 如果确定文件类型,请指定明确的文件类型,sdk只会以给定的文件类型打开;若是未知的,sdk会猜测文件类型,但会有一定的失败几率。password只对需要密码的pdf文件有效,sdk内置了密码输入界面,因此无需关心PDF密码问题,但是若要自定义密码输入界面,请实现RDDelegate中的canShowDefaultPasswordUI回调接口,详情请参考  canShowDefaultPasswordUI。此接口是唯一获取ReaderViewController对象的接口,请不要使用其他UIVeiewController类获取对象的接口,否则得到的对象的所有行为是未定义的。获取封面时,需要调用此接口打开文件,使用完毕后,必须调用close接口,否则sdk将无法打开新的文件。


      4. +(void)removeBookCacheWithPath:(NSString *)path;                        

        • 功能:

        • 删除与本书相关的缓存文件,在删除path所在的文件时,请调用此接口 - 删除与本书相关的缓存文件,以便释放手机更多存储空间。否则在删除文件后,这些与path所在文件相关的无用缓存会一直随app存在。

        • 参数:

        • path 文件路径,必须与打开该文件时所传的路径一致。

        • 返回值:

        • 无。


      5.   +(NSString*)version;                        

        • 功能:

        • 返回阅读器版本号。

        • 参数:

        • 无。

        • 返回值:

        • 阅读器版本号, 如:1.0.0.0。


      6.   -(UIImage*)bookThumbnailAtPage:(NSUInteger)pageNum boundsSize:(CGSize)boundsSize useQuartz:(BOOL)useQuartz;                        

        • 功能:

        • 获取封面。

        • 参数:

        • pageNum 指定第几页为封面,起始页码以1开始,一般为1。

          boundsSize 封面大小。

          useQuartz 是否使用 quartz 获取封面, 由于阅读时,获取封面可能导致程序崩溃;而使用quartz,可避免这种情况。

        • 返回值:

        • 封面图片。

        • 注意:

        • 由于获取封面的前提是,需要打开文件;而阅后即焚文件可能对打开次数有限制,因此在获取封面前,应当先判断文件是否为阅后即焚文件,若为阅后即焚文件,不应当打开文件获取封面。判断方法请参考isFileEncWithPath:;若不是,即可打开,获取封面;然后必须调用


      7. -(NSArray<RDBookmarkItem*>*)bookmarkArray;                        

        • 功能:

        • 获取书签。

        • 参数:

        • 无。

        • 返回值:

        • 该书的所有书签,书签内容请参考:RDBookmarkItem


      8. -(NSArray<RDAnnotItem*>*)annotArray;                        

        • 功能:

        • 获取注释。

        • 参数:

        • 无。

        • 返回值:

        • 该书的所有注释,注释内容请参考:RDAnnotItem


      9. -(void)close;                        

        • 功能:

        • 通知sdk关闭文件,以及相关的后台计算。

        • 参数:

        • 无。

        • 返回值:

        • 无。


      10. @property (nonatomic, strong, readonly) NSString *path;                        

        • 功能:

        • 获取图书路径。

        • 注意:

        • 得到的路径将与打开文件时传入的路径相同。


      11. @property (nonatomic, assign, readonly) RDOpenFileType fileType;                        

        • 功能:

        • 获取打开图书的文件类型,请参考:RDOpenFileType


      12. + (long)isFileEncWithPath:(NSString*)path;                        

        • 功能:

        • 检查文件是否是阅后即焚文件。

        • 参数:

        • path 文件路径。

        • 返回值:

        • 0为普通文件,1为阅后即焚文件,-1为文件无法打开。


      13. +(long)makeDRMFileWithDestPath:(NSString*)destPath srcPath:(NSString*)srcPath ctrlInfo:(NSString*)info;                        

        • 功能:

        • 生产阅后即焚文件。

        • 参数:

        • destPath sdk存放制作的DRM文件路径。

          srcPath 将要被加密的文件路径。

          ctrlInfo 文件控制信息,使用标准的xml格式字符串传递,示例:

          <ReadCtrlWay>0</ReadCtrlWay> // 控制方式,0逻辑或,1逻辑与

          <ReadDuration>0 </ReadDuration> // 时长,秒数,若无控制则可不包含此项

          <ReadCount>10</ReadCount> // 次数控制,若无控制传-1

          <UseReadTime> // 若无控制则可不包含此项,时间格式须严格按下面的格式书写

              <RStart>0000-00-00 00:00:00</RStart>

              <REnd>2018-05-15 18:00:00</REnd>

          </UseReadTime>

        • 返回值:

        • -1表示目标文件出错;-2表示文件大小为0;-3 表示目标文件存在,不允许覆盖或覆盖失败;-4表示原始文件出错 0表示文件加密成功.

        • 注意:

        • 此接口只是针对pdf文件格式;若要打开生成的文件,需调用ReaderViewController的打开文件接口。

    3. RDDelegate

    4. RDDelegate 定义如下:(摘自readerSDK.h)。

      @class ReaderViewController;
      @protocol RDDelegate
      @optional
      //返回阅读器初始设置信息
      -(RDSettingsInfoItem*)readerSettingsForReaderViewController:(ReaderViewController*)rd;
      
      //返回当前成功打开的图书设置信息
      -(RDBookSettingsInfoItem*)bookSettingsForReaderViewController:(ReaderViewController*)rd;
      
      //返回注释数组
      -(NSArray<RDAnnotItem*>*)annotArrayForReaderViewController:(ReaderViewController*)rd;
      
      //返回书签数组
      -(NSArray<RDBookmarkItem*>*)bookmarkArrayForReaderViewController:(ReaderViewController*)rd;
      
      //通知保存阅读器设置信息
      -(void)readerViewController:(ReaderViewController*)rd saveReaderSettings:(RDSettingsInfoItem*)readrStttings;
      
      //通知保存书本设置信息
      -(void)readerViewController:(ReaderViewController*)rd saveBookSettings:(RDBookSettingsInfoItem*)bookSettings;
      
      //bookmark 编辑
      -(void)readerViewController:(ReaderViewController *)rd didRemoveBookmarkItem:(RDBookmarkItem*)bookmarkItem;
      -(void)readerViewController:(ReaderViewController *)rd didAddBookmarkItem:(RDBookmarkItem*)bookmarkItem;
      -(void)readerViewController:(ReaderViewController *)rd bookmarkItemDidChage:(RDBookmarkItem*)bookmarkItem;
      
      // annot 编辑
      -(void)readerViewController:(ReaderViewController *)rd didRemoveAnnotItem:(RDAnnotItem*)annotItem;
      -(void)readerViewController:(ReaderViewController *)rd didAddAnnotItem:(RDAnnotItem*)annotItem;
      -(void)readerViewController:(ReaderViewController *)rd annotItemDidChage:(RDAnnotItem*)annotItem;
      
      //是否可以显示默认的密码界面,默认返回YES
      //如果默认的密码界面无法满足的你的要求,可自定义密码界面,
      //当打开的文件需要密码时,会调用此接口询问,若返回NO,[instanceWithPath ...]函数将返回nil, errCode == rd_err_password_is_error,而不显示默认密码界面
      -(BOOL)canShowDefaultPasswordUI;
      
      //将drm文件加入到书架
      -(void)readerViewController:(ReaderViewController *)rd addDRMFileToShelf:(NSString*)drmFilePath;
      @end

      协议接口详细说明:

      1. -(RDSettingsInfoItem*)readerSettingsForReaderViewController:(ReaderViewController*)rd;                        

        • 说明:

        • 打开图书时,为阅读器提供初始设置参数,请参考RDSettingsInfoItem,如果不实现,阅读器将使用上次自动保存的配置参数。


      2. -(RDBookSettingsInfoItem*)bookSettingsForReaderViewController:(ReaderViewController*)rd;                        

        • 说明:

        • 打开图书时,为阅读器提供书本初始设置参数,请参考RDBookSettingsInfoItem,如果不实现,阅读器将使用上次自动保存的配置参数。


      3. -(void)readerViewController:(ReaderViewController*)rd saveReaderSettings:(RDSettingsInfoItem*)readrStttings;                        

        • 说明:

        • 通知保存阅读器设置,请参考RDSettingsInfoItem,如果不实现, 阅读器会自动保存到本地这些设置。


      4. -(void)readerViewController:(ReaderViewController*)rd saveBookSettings:(RDBookSettingsInfoItem*)bookSettings;                        

        • 说明:

        • 通知保存阅读器该本书的设置,请参考RDBookSettingsInfoItem, 阅读器会自动保存到本地这些设置。


      5. -(NSArray<RDAnnotItem*>*)annotArrayForReaderViewController:(ReaderViewController*)rd;                        

        • 说明:

        • 为阅读器提annot,请参考RDAnnotItem,如果不实现,阅读器将使用上次自动保存的数据。


      6. -(NSArray<RDBookmarkItem*>*)bookmarkArrayForReaderViewController:(ReaderViewController*)rd;                        

        • 说明:

        • 为阅读器提供bookmark,请参考RDBookmarkItem,如果不实现,阅读器将使用上次自动保存的数据。


      7. -(void)readerViewController:(ReaderViewController *)rd didRemoveBookmarkItem:(RDBookmarkItem*)bookmarkItem;                        

        • 说明:

        • 通知删除书签的操作,请参考RDBookmarkItem,如果不实现,阅读器会自动保存到本地。


      8. -(void)readerViewController:(ReaderViewController *)rd didAddBookmarkItem:(RDBookmarkItem*)bookmarkItem;                        

        • 说明:

        • 通知添加书签的操作,请参考RDBookmarkItem,如果不实现,阅读器会自动保存到本地。


      9. -(void)readerViewController:(ReaderViewController *)rd bookmarkItemDidChage:(RDBookmarkItem*)bookmarkItem;                        

        • 说明:

        • 可以不实现,通知修改书签内容的操作,请参考RDBookmarkItem,如果不实现,阅读器会自动保存到本地。


      10. -(void)readerViewController:(ReaderViewController *)rd didRemoveAnnotItem:(RDAnnotItem*)annotItem;                        

        • 说明:

        • 通知删除注释的操作,请参考RDAnnotItem,如果不实现,阅读器会自动保存到本地。


      11. -(void)readerViewController:(ReaderViewController *)rd didAddAnnotItem:(RDAnnotItem*)annotItem;                        

        • 说明:

        • 通知通知添加注释的操作,请参考RDAnnotItem,如果不实现,阅读器会自动保存到本地。


      12. -(void)readerViewController:(ReaderViewController *)rd annotItemDidChage:(RDAnnotItem*)annotItem;                        

        • 说明:

        • 通知修改注释的操作,请参考RDAnnotItem,如果不实现,阅读器会自动保存到本地。


      13. -(BOOL)canShowDefaultPasswordUI;                        

      14. -(void)readerViewController:(ReaderViewController *)rd addDRMFileToShelf:(NSString*)drmFilePath;                        

        • 说明:

        • 用户生成阅后即焚文件成功后,并选择“加入书架”选项后调用, drmFilePath 为阅后即焚文件路径;可以不实现;若不实现,SDK界面将不会有“加入书架”的选项。

  7. 结构定义

    1. RDErrorCode(摘自ReaderSDK.h)

    2. // error code
      typedef NS_ENUM(NSUInteger, RDErrorCode){
          rd_err_ok                   = 0, // 成功
          rd_err_invalid_path         = 1, // 无效的文件路径
          rd_err_file_is_not_exist    = 2, // 文件不存在
          rd_err_can_not_open         = 3, // 无法打开
          rd_err_password_is_error    = 4, // 密码错误
          rd_err_unkown               = 5, // 未知错误
          rd_err_file_damaged         = 6, // 文件损坏
          rd_err_file_is_encrypted    = 7, // 文件已加密
          rd_err_file_has_no_page     = 8, // 文件无页面
          rd_err_file_is_invalid      = 9, // 文件无效
          rd_err_verification_failed  = 10,// 验证失败
          rd_err_reading_time_interval_is_over        = 11, // 时段阅读时间用完
          rd_err_not_in_reading_time_interval         = 12, // 不在阅读时段内
          rd_err_reading_duration_is_over             = 13, // 时长阅读时间用完
          rd_err_reading_count_is_over                = 14, // 阅读次数用完
          rd_err_encoding_is_unkown                   = 15, // 编码未知
          rd_err_can_not_open_two_files_in_same_time  = 16, // 无法同时打开两文件
      };

    3. RDOpenFileType(摘自ReaderSDK.h)

    4. // 打开文件格式
      typedef NS_ENUM(NSUInteger, RDOpenFileType){
          rd_open_file_type_unknow    = 0,          // 未知文件类型
          rd_open_file_type_pdf       = 1,          // pdf格式
          rd_open_file_type_txt       = 2           // txt格式
      };
      • 注意:

      • 阅读器目前仅支持 pdf 和 txt 格式。

    5. RDAnnotType(摘自ReaderSDK.h)

    6. // 注释类型
      typedef NS_ENUM(NSUInteger, RDAnnotType){
          rd_annot_type_solid_underline   = 0,    // 实线下划线
          rd_annot_type_wave_underline    = 1,    // 波浪下划线
          rd_annot_type_dash_underline    = 2,    // 虚线下划线
          rd_annot_type_highlight         = 3     // 高亮
      };

    7. RDPageFlipMode(摘自ReaderSDK.h)

    8. // 翻页模式
      typedef NS_ENUM(NSUInteger,RDPageFlipMode){
          rd_page_flip_mode_slide         = 0,    // 滑动
          rd_page_flip_mode_simulation    = 1,    // 仿真
          rd_page_flip_mode_continues     = 2,    // 连续页,只有pdf支持
          rd_page_flip_mode_none          = 3     // 无
      };
      • 注意:

      • rd_page_flip_mode_continues 是为pdf预留的翻页模式,暂不支持。

    9. RDSettingsInfoItem(摘自ReaderSDK.h)

    10. @interface RDSettingsInfoItem : NSObject
      // textColor = nil,即无效,则 textColorIndex 有效
      @property (nonatomic, strong) UIColor *textColor;           // 自定义的 textColor
      @property (nonatomic, assign) NSUInteger textColorIndex;    // 阅读器内部预留的序号
      
      // textBkgndColor = nil,即无效,则 textBkgndColorIndex 有效
      @property (nonatomic, strong) UIColor *textBkgndColor;      // 自定义的 textBkgndColor
      @property (nonatomic, assign) NSUInteger textBkgndColorIndex;//阅读器内部预留的序号
      
      @property (nonatomic, assign) CGFloat textLineSpaceing;     // text 行间距
      @property (nonatomic, strong) NSString *textFontName;       // 字体名
      @property (nonatomic, assign) CGFloat textFontSize;         // 字体大小
      
      @property (nonatomic, assign) BOOL isNightMode;             // 是否为夜间模式
      @property (nonatomic, assign) RDPageFlipMode pageFileMode;  // 翻页模式
      @end

    11. RDBookSettingsInfoItem(摘自ReaderSDK.h)

    12. @interface RDBookSettingsInfoItem : NSObject
      @property (nonatomic, assign) NSUInteger pageNum;           // 阅读器初始化时所显示的页面
      @property (nonatomic, assign) BOOL cutPageEdgeManually;     // yes为手动裁边,no自动裁边
      @property (nonatomic, assign) BOOL enableOddEvenSimmetry;   // 手动裁边时,YES为奇偶对称裁边,NO为正常裁边
      @property (nonatomic, assign) UIEdgeInsets cutPageEdge;     // 手动裁边时的边距
      @end

    13. RDAnnotItem(摘自ReaderSDK.h)

    14. @interface RDAnnotItem : NSObject
      @property (nonatomic, assign) RDAnnotType type;     // 注释类型,支持高亮和下划线
      @property (nonatomic, assign) NSInteger ID;         // 注释唯一标示
      @property (nonatomic, strong) NSDate *addTime;      // 注释添加时间
      @property (nonatomic, strong) NSString *userNote;   // 用户笔记
      @property (nonatomic, strong) NSString *text;       // 注释包涵的文字
      @property (nonatomic, assign) NSInteger pageNum;    // 注释所在页,在txt下无效,值为RD_INVALID_INDEX
      @property (nonatomic, assign) NSInteger startIndex; // 起始文字索引
      @property (nonatomic, assign) NSInteger endIndex;   // 结束文字索引
      @property (nonatomic, assign) NSInteger argbAlpha;  // argb alpha(0-255)
      @property (nonatomic, assign) NSInteger argbRed;    // argb red(0-255)
      @property (nonatomic, assign) NSInteger argbGreen;  // argb green(0-255)
      @property (nonatomic, assign) NSInteger argbBlue;   // argb blue(0-255)
      // 以下属性在(type=下划线)下才有效
      @property (nonatomic, assign) NSInteger lineWidth;  // 线条宽
      @end

    15. RDBookmarkItem(摘自ReaderSDK.h)

    16. @interface RDBookmarkItem : NSObject
      @property (nonatomic, assign) NSUInteger pageNum;    // bookmark 所在页
      @property (nonatomic, strong) NSDate *addTime;       // 添加时间
      @property (nonatomic, strong) NSString *userNote;    // 用户笔记
      @property (nonatomic, strong) NSString *text;         // bookmark包含的的文字
      @end