lipengwei
2020-01-13 ea8e18fe8cc8ef08da463c82dec74e3fb918ab58
v1.4.0
88 files added
3518 ■■■■■ changed files
WAAiHelpImpl_CN.podspec 27 ●●●●● patch | view | raw | blame | history
WAAiHelpImpl_CN/1.4.0/WAAiHelpImpl_CN.podspec 27 ●●●●● patch | view | raw | blame | history
config/wa_sdk_impl_config_aihelp.xml 9 ●●●●● patch | view | raw | blame | history
frameworks/ElvaChatServiceSDK.framework/ElvaChatServiceSDK patch | view | raw | blame | history
frameworks/ElvaChatServiceSDK.framework/Headers/ECServiceSdk.h 81 ●●●●● patch | view | raw | blame | history
frameworks/ElvaChatServiceSDK.framework/Headers/ElvaChatServiceSDK.h 19 ●●●●● patch | view | raw | blame | history
frameworks/ElvaChatServiceSDK.framework/Info.plist patch | view | raw | blame | history
frameworks/ElvaChatServiceSDK.framework/Modules/module.modulemap 6 ●●●●● patch | view | raw | blame | history
frameworks/MQTTFramework.framework/Headers/MQTTCFSocketDecoder.h 39 ●●●●● patch | view | raw | blame | history
frameworks/MQTTFramework.framework/Headers/MQTTCFSocketEncoder.h 38 ●●●●● patch | view | raw | blame | history
frameworks/MQTTFramework.framework/Headers/MQTTCFSocketTransport.h 65 ●●●●● patch | view | raw | blame | history
frameworks/MQTTFramework.framework/Headers/MQTTClient-Prefix.pch 9 ●●●●● patch | view | raw | blame | history
frameworks/MQTTFramework.framework/Headers/MQTTCoreDataPersistence.h 21 ●●●●● patch | view | raw | blame | history
frameworks/MQTTFramework.framework/Headers/MQTTDecoder.h 65 ●●●●● patch | view | raw | blame | history
frameworks/MQTTFramework.framework/Headers/MQTTFramework.h 30 ●●●●● patch | view | raw | blame | history
frameworks/MQTTFramework.framework/Headers/MQTTInMemoryPersistence.h 16 ●●●●● patch | view | raw | blame | history
frameworks/MQTTFramework.framework/Headers/MQTTMessage.h 131 ●●●●● patch | view | raw | blame | history
frameworks/MQTTFramework.framework/Headers/MQTTPersistence.h 124 ●●●●● patch | view | raw | blame | history
frameworks/MQTTFramework.framework/Headers/MQTTSSLSecurityPolicy.h 158 ●●●●● patch | view | raw | blame | history
frameworks/MQTTFramework.framework/Headers/MQTTSSLSecurityPolicyDecoder.h 18 ●●●●● patch | view | raw | blame | history
frameworks/MQTTFramework.framework/Headers/MQTTSSLSecurityPolicyEncoder.h 17 ●●●●● patch | view | raw | blame | history
frameworks/MQTTFramework.framework/Headers/MQTTSSLSecurityPolicyTransport.h 30 ●●●●● patch | view | raw | blame | history
frameworks/MQTTFramework.framework/Headers/MQTTSession.h 778 ●●●●● patch | view | raw | blame | history
frameworks/MQTTFramework.framework/Headers/MQTTSessionLegacy.h 456 ●●●●● patch | view | raw | blame | history
frameworks/MQTTFramework.framework/Headers/MQTTSessionManager.h 275 ●●●●● patch | view | raw | blame | history
frameworks/MQTTFramework.framework/Headers/MQTTSessionSynchron.h 389 ●●●●● patch | view | raw | blame | history
frameworks/MQTTFramework.framework/Headers/MQTTTransport.h 102 ●●●●● patch | view | raw | blame | history
frameworks/MQTTFramework.framework/Headers/MQTTWebsocketTransport.h 49 ●●●●● patch | view | raw | blame | history
frameworks/MQTTFramework.framework/Info.plist patch | view | raw | blame | history
frameworks/MQTTFramework.framework/MQTTFramework patch | view | raw | blame | history
frameworks/MQTTFramework.framework/Modules/module.modulemap 6 ●●●●● patch | view | raw | blame | history
frameworks/WAAIhelpImpl.framework/Headers/WAAIhelpImpl.h 19 ●●●●● patch | view | raw | blame | history
frameworks/WAAIhelpImpl.framework/Info.plist patch | view | raw | blame | history
frameworks/WAAIhelpImpl.framework/Modules/module.modulemap 6 ●●●●● patch | view | raw | blame | history
frameworks/WAAIhelpImpl.framework/WAAIhelpImpl patch | view | raw | blame | history
res/ElvaChatServiceSDK.bundle/ab_op_list_ltem_bg.9.png patch | view | raw | blame | history
res/ElvaChatServiceSDK.bundle/ab_reward.png patch | view | raw | blame | history
res/ElvaChatServiceSDK.bundle/ar.lproj/Localizable.strings 22 ●●●●● patch | view | raw | blame | history
res/ElvaChatServiceSDK.bundle/b27_icon_star_gray@2x.png patch | view | raw | blame | history
res/ElvaChatServiceSDK.bundle/b27_icon_star_yellow@2x.png patch | view | raw | blame | history
res/ElvaChatServiceSDK.bundle/back_2.png patch | view | raw | blame | history
res/ElvaChatServiceSDK.bundle/btn_close.png patch | view | raw | blame | history
res/ElvaChatServiceSDK.bundle/btn_search.png patch | view | raw | blame | history
res/ElvaChatServiceSDK.bundle/cai_has_clicked_ios.png patch | view | raw | blame | history
res/ElvaChatServiceSDK.bundle/chat5.png patch | view | raw | blame | history
res/ElvaChatServiceSDK.bundle/chat_send_message.png patch | view | raw | blame | history
res/ElvaChatServiceSDK.bundle/darkMode/ab_op_list_ltem_bg.9.png patch | view | raw | blame | history
res/ElvaChatServiceSDK.bundle/darkMode/back_2.png patch | view | raw | blame | history
res/ElvaChatServiceSDK.bundle/darkMode/btn_close.png patch | view | raw | blame | history
res/ElvaChatServiceSDK.bundle/darkMode/chat_send_message.png patch | view | raw | blame | history
res/ElvaChatServiceSDK.bundle/darkMode/message_receiver_background_normal.png patch | view | raw | blame | history
res/ElvaChatServiceSDK.bundle/darkMode/message_receiver_background_normal@2x.png patch | view | raw | blame | history
res/ElvaChatServiceSDK.bundle/darkMode/message_receiver_background_normal@3x.png patch | view | raw | blame | history
res/ElvaChatServiceSDK.bundle/darkMode/show_faq_list.png patch | view | raw | blame | history
res/ElvaChatServiceSDK.bundle/darkMode/uploadPic.png patch | view | raw | blame | history
res/ElvaChatServiceSDK.bundle/de.lproj/Localizable.strings 24 ●●●●● patch | view | raw | blame | history
res/ElvaChatServiceSDK.bundle/default_guide_elva.png patch | view | raw | blame | history
res/ElvaChatServiceSDK.bundle/default_guide_elva_robot.png patch | view | raw | blame | history
res/ElvaChatServiceSDK.bundle/default_player_elva.png patch | view | raw | blame | history
res/ElvaChatServiceSDK.bundle/ding_has_clicked_ios.png patch | view | raw | blame | history
res/ElvaChatServiceSDK.bundle/el-GR.lproj/Localizable.strings 33 ●●●●● patch | view | raw | blame | history
res/ElvaChatServiceSDK.bundle/en.lproj/Localizable.strings 23 ●●●●● patch | view | raw | blame | history
res/ElvaChatServiceSDK.bundle/es.lproj/Localizable.strings 23 ●●●●● patch | view | raw | blame | history
res/ElvaChatServiceSDK.bundle/evaluate_submit.png patch | view | raw | blame | history
res/ElvaChatServiceSDK.bundle/fa.lproj/Localizable.strings 33 ●●●●● patch | view | raw | blame | history
res/ElvaChatServiceSDK.bundle/fr-FR.lproj/Localizable.strings 24 ●●●●● patch | view | raw | blame | history
res/ElvaChatServiceSDK.bundle/id-ID.lproj/Localizable.strings 22 ●●●●● patch | view | raw | blame | history
res/ElvaChatServiceSDK.bundle/it-IT.lproj/Localizable.strings 33 ●●●●● patch | view | raw | blame | history
res/ElvaChatServiceSDK.bundle/ja.lproj/Localizable.strings 25 ●●●●● patch | view | raw | blame | history
res/ElvaChatServiceSDK.bundle/ko.lproj/Localizable.strings 23 ●●●●● patch | view | raw | blame | history
res/ElvaChatServiceSDK.bundle/loading.png patch | view | raw | blame | history
res/ElvaChatServiceSDK.bundle/message_receiver_background_normal.png patch | view | raw | blame | history
res/ElvaChatServiceSDK.bundle/message_receiver_background_normal@2x.png patch | view | raw | blame | history
res/ElvaChatServiceSDK.bundle/message_receiver_background_normal@3x.png patch | view | raw | blame | history
res/ElvaChatServiceSDK.bundle/message_sender_background_normal.png patch | view | raw | blame | history
res/ElvaChatServiceSDK.bundle/message_sender_background_normal@2x.png patch | view | raw | blame | history
res/ElvaChatServiceSDK.bundle/message_sender_background_normal@3x.png patch | view | raw | blame | history
res/ElvaChatServiceSDK.bundle/pl-PL.lproj/Localizable.strings 33 ●●●●● patch | view | raw | blame | history
res/ElvaChatServiceSDK.bundle/pt-PT.lproj/Localizable.strings 25 ●●●●● patch | view | raw | blame | history
res/ElvaChatServiceSDK.bundle/ru.lproj/Localizable.strings 23 ●●●●● patch | view | raw | blame | history
res/ElvaChatServiceSDK.bundle/show_faq_list.png patch | view | raw | blame | history
res/ElvaChatServiceSDK.bundle/sv-SE.lproj/Localizable.strings 25 ●●●●● patch | view | raw | blame | history
res/ElvaChatServiceSDK.bundle/th.lproj/Localizable.strings 22 ●●●●● patch | view | raw | blame | history
res/ElvaChatServiceSDK.bundle/tr.lproj/Localizable.strings 22 ●●●●● patch | view | raw | blame | history
res/ElvaChatServiceSDK.bundle/uploadPic.png patch | view | raw | blame | history
res/ElvaChatServiceSDK.bundle/vi-VN.lproj/Localizable.strings 25 ●●●●● patch | view | raw | blame | history
res/ElvaChatServiceSDK.bundle/zh-Hans.lproj/Localizable.strings 24 ●●●●● patch | view | raw | blame | history
res/ElvaChatServiceSDK.bundle/zh-Hant.lproj/Localizable.strings 24 ●●●●● patch | view | raw | blame | history
WAAiHelpImpl_CN.podspec
New file
@@ -0,0 +1,27 @@
#
#  Be sure to run `pod spec lint WAAiHelpImpl.podspec' to ensure this is a
#  valid spec and to remove all comments including this before submitting the spec.
#
#  To learn more about Podspec attributes see http://docs.cocoapods.org/specification.html
#  To see working Podspecs in the CocoaPods repo see https://github.com/CocoaPods/Specs/
#
Pod::Spec.new do |s|
s.name = 'WAAiHelpImpl_CN'
s.version = '1.4.0'
s.summary = 'WAAfImpl framework in testing environment.'
s.license = 'MIT'
s.author = { "lpw" => "lipengwei@gamehollywood.com" }
s.homepage = 'http://repo.wingsdk.cn:8082/summary/WAAiHelpImpl_CN.git'
s.source = { :git => "http://admin@repo.wingsdk.cn:8082/r/WAAiHelpImpl_CN.git" , :tag => s.version}
s.platform = :ios
s.ios.deployment_target = "7.0"
s.frameworks = "WebKit"
s.vendored_frameworks = 'frameworks/*.framework'
s.libraries = 'sqlite3'
s.resources = ['config/*.xml','res/ElvaChatServiceSDK.bundle','res/ElvaChatServiceSDK.bundle','res/Localization/*/*.strings']
s.requires_arc = true
s.dependency 'WASdkIntf_CN', '~> 1.4.0'   #此处添加私有库依赖
s.dependency 'WASdkImpl_CN', '~> 1.4.0'
end
WAAiHelpImpl_CN/1.4.0/WAAiHelpImpl_CN.podspec
New file
@@ -0,0 +1,27 @@
#
#  Be sure to run `pod spec lint WAAiHelpImpl.podspec' to ensure this is a
#  valid spec and to remove all comments including this before submitting the spec.
#
#  To learn more about Podspec attributes see http://docs.cocoapods.org/specification.html
#  To see working Podspecs in the CocoaPods repo see https://github.com/CocoaPods/Specs/
#
Pod::Spec.new do |s|
s.name = 'WAAiHelpImpl_CN'
s.version = '1.4.0'
s.summary = 'WAAfImpl framework in testing environment.'
s.license = 'MIT'
s.author = { "lpw" => "lipengwei@gamehollywood.com" }
s.homepage = 'http://repo.wingsdk.cn:8082/summary/WAAiHelpImpl_CN.git'
s.source = { :git => "http://admin@repo.wingsdk.cn:8082/r/WAAiHelpImpl_CN.git" , :tag => s.version}
s.platform = :ios
s.ios.deployment_target = "7.0"
s.frameworks = "WebKit"
s.vendored_frameworks = 'frameworks/*.framework'
s.libraries = 'sqlite3'
s.resources = ['config/*.xml','res/ElvaChatServiceSDK.bundle','res/ElvaChatServiceSDK.bundle','res/Localization/*/*.strings']
s.requires_arc = true
s.dependency 'WASdkIntf_CN', '~> 1.4.0'   #此处添加私有库依赖
s.dependency 'WASdkImpl_CN', '~> 1.4.0'
end
config/wa_sdk_impl_config_aihelp.xml
New file
@@ -0,0 +1,9 @@
<?xml version="1.0" encoding="UTF-8"?>
<config>
    <version val="AIHELP1.4.0"/>
    <comps>
        <!-- 公共模块 -->
        <comp module="CORE" plaf="AIHELP" mandatory="YES" value="WAAIhelpCore" desc="公共模块"/>
        <comp module="CSC" plaf="AIHELP" mandatory="YES" value="WAAIhelpCsc" desc="客服系统模块"/>
    </comps>
</config>
frameworks/ElvaChatServiceSDK.framework/ElvaChatServiceSDK
Binary files differ
frameworks/ElvaChatServiceSDK.framework/Headers/ECServiceSdk.h
New file
@@ -0,0 +1,81 @@
//
//  ECServiceCocos2dx.h
//  ElvaChatService Cocos2dx SDK
//
#import <Foundation/Foundation.h>
/*
 * notify the application when some state changes in Elva.
 * eventCode:
 *    2: Elva UI Visible Changed
 *          state (0) : will show elva ui
 *          state (1) : all elva ui are closed
 */
typedef void (*ElvaEventCallBack)(const int eventCode, const int state);
@class UIViewController;
@interface ECServiceSdk:NSObject
#pragma mark - ------init------
+ (void) init:(NSString*) appSecret Domain:(NSString*) domain AppId:(NSString*) appId;
#pragma mark - ------showElva------
+ (void) showElva:(NSString*) playerName PlayerUid:(NSString*) playerUid ServerId:(NSString*) serverId PlayerParseId:(NSString*) playerParseId PlayershowConversationFlag:(NSString*) playershowConversationFlag;
+ (void) showElva:(NSString*) playerName PlayerUid:(NSString*) playerUid ServerId:(NSString*) serverId PlayerParseId:(NSString*) playerParseId PlayershowConversationFlag:(NSString*) playershowConversationFlag Config:(NSMutableDictionary*) config;
#pragma mark - ------showConversation------
+ (void) showConversation:(NSString*) playerUid ServerId:(NSString*) serverId;//请优先实现setUserName接口
+ (void) showConversation:(NSString*) playerUid ServerId:(NSString*) serverId Config:(NSMutableDictionary*) config;
#pragma mark - ------showElvaOP------
+ (void) showElvaOP:(NSString*) playerName PlayerUid:(NSString*) playerUid ServerId:(NSString*) serverId PlayerParseId:(NSString*) playerParseId PlayershowConversationFlag:(NSString*) playershowConversationFlag Config:(NSMutableDictionary *)config;
+ (void) showElvaOP:(NSString*) playerName PlayerUid:(NSString*) playerUid ServerId:(NSString*) serverId PlayerParseId:(NSString*) playerParseId PlayershowConversationFlag:(NSString*) playershowConversationFlag Config:(NSMutableDictionary *)config defaultTabIndex:(int)defaultTabIndex;
#pragma mark - ------showFAQ------
+ (void) showFAQs;
+ (void) showFAQs:(NSDictionary*)config;
+ (void) showFAQs:(NSString*)playerName playerUid:(NSString*)playerUid;
+ (void) showFAQs:(NSString*)playerName playerUid:(NSString*)playerUid config:(NSDictionary*)config;
+ (void) showFAQSection:(NSString*) sectionPublishId;
+ (void) showFAQSection:(NSString*) sectionPublishId Config:(NSMutableDictionary*) config;
+ (void) showSingleFAQ:(NSString*) faqId;
+ (void) showSingleFAQ:(NSString*) faqId Config:(NSMutableDictionary*) config;
#pragma mark - ------other------
+ (void) showVIPChat:(NSString*) appidWeb VIPTags:(NSString *) vipTags;
+ (void) showQACommunity:(NSString *)playerUid PlayName:(NSString *)playerName;
+ (void) showURL:(NSString *) url;
+ (void) showStoreReview;
+ (void) setRootViewController:(UIViewController*)rootViewController;
+ (void) setUserId:(NSString*) playerUid;//自助服务,在showFAQ之前调用
+ (void) setUserName:(NSString*) playerName;//在需要的接口之前调用,建议游戏刚进入就默认调用
+ (void) setName:(NSString*) game_name;
+ (void) setOpenLog:(BOOL)isOpen;
+ (void) setServerId:(NSString*) serverId;//自助服务,在showFAQ之前调用
+ (void) setAccelerateDomain:(NSString *)domain;
+ (void) setSDKLanguage:(NSString*) sdkLanguage;
+ (void) setUseDevice;
+ (void) setSendCloseNotification:(BOOL) isSend;//关闭某一项是否发送通知
+ (void) setEvaluateStar:(int) star;//设置默认评价星星个数
+ (void) setChangeDirection;
+ (void) setSDKInterfaceOrientationMask:(NSUInteger)interfaceOrientationMask;//参数参考UIInterfaceOrientationMask
+ (void) setNoMenu;
+ (void) setVIP:(NSString *)userName userId:(NSString *)userId config:(NSDictionary*)config;
+ (void) registerUnityOnInitializedCallback:(NSString *) gameObject;
+ (void) registerUnityOnMessageArrivedCallback:(NSString *) gameObject;
+ (void) registerDeviceToken:(NSString*) deviceToken isVIP:(Boolean) isVip;
+ (void) handlePushNotification:(NSDictionary *) table DataFromInApp:(BOOL) dataFromInApp;
+ (int) getNotificationMessageCount;
+ (void) setUnreadMessageFetchUid:(NSString*) playerUid;
+ (NSString*)sdkVersionInfo;
+ (BOOL) isInSDKPageView;
+ (void) setSDKEdgeInsetsWithTop:(float)top bottom:(float)bottom enable:(BOOL)enable;
+ (void) setSDKEdgeColorWithRed:(float)red green:(float)green blue:(float)blue alpha:(float)alpha;//0~1
+ (void) setEventListener:(ElvaEventCallBack)callback;
@end
frameworks/ElvaChatServiceSDK.framework/Headers/ElvaChatServiceSDK.h
New file
@@ -0,0 +1,19 @@
//
//  ElvaChatServiceSDK.h
//  ElvaChatServiceSDK
//
//  Created by wwj on 16/7/21.
//  Copyright © 2016年 wwj. All rights reserved.
//
#import <UIKit/UIKit.h>
#import "ECServiceSdk.h"
//! Project version number for ElvaChatServiceSDK.
FOUNDATION_EXPORT double ElvaChatServiceSDKVersionNumber;
//! Project version string for ElvaChatServiceSDK.
FOUNDATION_EXPORT const unsigned char ElvaChatServiceSDKVersionString[];
// In this header, you should import all the public headers of your framework using statements like #import <ElvaChatServiceSDK/PublicHeader.h>
frameworks/ElvaChatServiceSDK.framework/Info.plist
Binary files differ
frameworks/ElvaChatServiceSDK.framework/Modules/module.modulemap
New file
@@ -0,0 +1,6 @@
framework module ElvaChatServiceSDK {
  umbrella header "ElvaChatServiceSDK.h"
  export *
  module * { export * }
}
frameworks/MQTTFramework.framework/Headers/MQTTCFSocketDecoder.h
New file
@@ -0,0 +1,39 @@
//
// MQTTCFSocketDecoder.h
// MQTTClient.framework
//
// Copyright © 2013-2016, Christoph Krey
//
#import <Foundation/Foundation.h>
typedef NS_ENUM(NSInteger, MQTTCFSocketDecoderState) {
    MQTTCFSocketDecoderStateInitializing,
    MQTTCFSocketDecoderStateReady,
    MQTTCFSocketDecoderStateError
};
@class MQTTCFSocketDecoder;
@protocol MQTTCFSocketDecoderDelegate <NSObject>
- (void)decoder:(MQTTCFSocketDecoder *)sender didReceiveMessage:(NSData *)data;
- (void)decoderDidOpen:(MQTTCFSocketDecoder *)sender;
- (void)decoder:(MQTTCFSocketDecoder *)sender didFailWithError:(NSError *)error;
- (void)decoderdidClose:(MQTTCFSocketDecoder *)sender;
@end
@interface MQTTCFSocketDecoder : NSObject <NSStreamDelegate>
@property (nonatomic) MQTTCFSocketDecoderState state;
@property (strong, nonatomic) NSError *error;
@property (strong, nonatomic) NSInputStream *stream;
@property (strong, nonatomic) NSRunLoop *runLoop;
@property (strong, nonatomic) NSString *runLoopMode;
@property (weak, nonatomic ) id<MQTTCFSocketDecoderDelegate> delegate;
- (void)open;
- (void)close;
@end
frameworks/MQTTFramework.framework/Headers/MQTTCFSocketEncoder.h
New file
@@ -0,0 +1,38 @@
//
// MQTTCFSocketEncoder.h
// MQTTClient.framework
//
// Copyright © 2013-2016, Christoph Krey
//
#import <Foundation/Foundation.h>
typedef NS_ENUM(NSInteger, MQTTCFSocketEncoderState) {
    MQTTCFSocketEncoderStateInitializing,
    MQTTCFSocketEncoderStateReady,
    MQTTCFSocketEncoderStateError
};
@class MQTTCFSocketEncoder;
@protocol MQTTCFSocketEncoderDelegate <NSObject>
- (void)encoderDidOpen:(MQTTCFSocketEncoder *)sender;
- (void)encoder:(MQTTCFSocketEncoder *)sender didFailWithError:(NSError *)error;
- (void)encoderdidClose:(MQTTCFSocketEncoder *)sender;
@end
@interface MQTTCFSocketEncoder : NSObject <NSStreamDelegate>
@property (nonatomic) MQTTCFSocketEncoderState state;
@property (strong, nonatomic) NSError *error;
@property (strong, nonatomic) NSOutputStream *stream;
@property (strong, nonatomic) NSRunLoop *runLoop;
@property (strong, nonatomic) NSString *runLoopMode;
@property (weak, nonatomic ) id<MQTTCFSocketEncoderDelegate> delegate;
- (void)open;
- (void)close;
- (BOOL)send:(NSData *)data;
@end
frameworks/MQTTFramework.framework/Headers/MQTTCFSocketTransport.h
New file
@@ -0,0 +1,65 @@
//
//  MQTTCFSocketTransport.h
//  MQTTClient
//
//  Created by Christoph Krey on 06.12.15.
//  Copyright © 2015-2016 Christoph Krey. All rights reserved.
//
#import "MQTTTransport.h"
#import "MQTTCFSocketDecoder.h"
#import "MQTTCFSocketEncoder.h"
/** MQTTCFSocketTransport
 * implements an MQTTTransport on top of CFNetwork
 */
@interface MQTTCFSocketTransport : MQTTTransport <MQTTTransport, MQTTCFSocketDecoderDelegate, MQTTCFSocketEncoderDelegate>
/** host an NSString containing the hostName or IP address of the host to connect to
 * defaults to @"localhost"
 */
@property (strong, nonatomic) NSString *host;
/** port an unsigned 16 bit integer containing the IP port number to connect to
 * defaults to 1883
 */
@property (nonatomic) UInt16 port;
/** tls a boolean indicating whether the transport should be using security
 * defaults to NO
 */
@property (nonatomic) BOOL tls;
/** certificates An identity certificate used to reply to a server requiring client certificates according
 * to the description given for SSLSetCertificate(). You may build the certificates array yourself or use the
 * sundry method clientCertFromP12.
 */
@property (strong, nonatomic) NSArray *certificates;
/** reads the content of a PKCS12 file and converts it to an certificates array for initWith...
 @param path the path to a PKCS12 file
 @param passphrase the passphrase to unlock the PKCS12 file
 @returns a certificates array or nil if an error occured
 @code
 NSString *path = [[NSBundle bundleForClass:[MQTTClientTests class]] pathForResource:@"filename"
 ofType:@"p12"];
 NSArray *myCerts = [MQTTCFSocketTransport clientCertsFromP12:path passphrase:@"passphrase"];
 if (myCerts) {
 self.session = [[MQTTSession alloc] init];
 ...
 self.session.certificates = myCerts;
 [self.session connect];
 ...
 }
 @endcode
 */
+ (NSArray *)clientCertsFromP12:(NSString *)path passphrase:(NSString *)passphrase;
@end
frameworks/MQTTFramework.framework/Headers/MQTTClient-Prefix.pch
New file
@@ -0,0 +1,9 @@
//
//  Prefix header
//
//  The contents of this file are implicitly included at the beginning of every source file.
//
#ifdef __OBJC__
    #import <Foundation/Foundation.h>
#endif
frameworks/MQTTFramework.framework/Headers/MQTTCoreDataPersistence.h
New file
@@ -0,0 +1,21 @@
//
//  MQTTCoreDataPersistence.h
//  MQTTClient
//
//  Created by Christoph Krey on 22.03.15.
//  Copyright © 2015-2016 Christoph Krey. All rights reserved.
//
#import <Foundation/Foundation.h>
#import <CoreData/CoreData.h>
#import "MQTTPersistence.h"
@interface MQTTCoreDataPersistence : NSObject <MQTTPersistence>
@end
@interface MQTTFlow : NSManagedObject <MQTTFlow>
@end
@interface MQTTCoreDataFlow : NSObject <MQTTFlow>
@end
frameworks/MQTTFramework.framework/Headers/MQTTDecoder.h
New file
@@ -0,0 +1,65 @@
//
// MQTTDecoder.h
// MQTTClient.framework
//
// Copyright © 2013-2016, Christoph Krey
//
// based on
//
// Copyright (c) 2011, 2013, 2lemetry LLC
//
// All rights reserved. This program and the accompanying materials
// are made available under the terms of the Eclipse Public License v1.0
// which accompanies this distribution, and is available at
// http://www.eclipse.org/legal/epl-v10.html
//
// Contributors:
//    Kyle Roche - initial API and implementation and/or initial documentation
//
#import <Foundation/Foundation.h>
#import "MQTTMessage.h"
typedef enum {
    MQTTDecoderEventProtocolError,
    MQTTDecoderEventConnectionClosed,
    MQTTDecoderEventConnectionError
} MQTTDecoderEvent;
typedef enum {
    MQTTDecoderStateInitializing,
    MQTTDecoderStateDecodingHeader,
    MQTTDecoderStateDecodingLength,
    MQTTDecoderStateDecodingData,
    MQTTDecoderStateConnectionClosed,
    MQTTDecoderStateConnectionError,
    MQTTDecoderStateProtocolError
} MQTTDecoderState;
@class MQTTDecoder;
@protocol MQTTDecoderDelegate <NSObject>
- (void)decoder:(MQTTDecoder *)sender didReceiveMessage:(NSData *)data;
- (void)decoder:(MQTTDecoder *)sender handleEvent:(MQTTDecoderEvent)eventCode error:(NSError *)error;
@end
@interface MQTTDecoder : NSObject <NSStreamDelegate>
@property (nonatomic)    MQTTDecoderState       state;
@property (strong, nonatomic)    NSRunLoop*      runLoop;
@property (strong, nonatomic)    NSString*       runLoopMode;
@property (nonatomic)    UInt32          length;
@property (nonatomic)    UInt32          lengthMultiplier;
@property (nonatomic)    int          offset;
@property (strong, nonatomic)    NSMutableData*  dataBuffer;
@property (weak, nonatomic ) id<MQTTDecoderDelegate> delegate;
- (void)open;
- (void)close;
- (void)decodeMessage:(NSData *)data;
@end
frameworks/MQTTFramework.framework/Headers/MQTTFramework.h
New file
@@ -0,0 +1,30 @@
//
//  MQTTFramework.h
//  MQTT-Client-Framework
//
//  Created by Terry Latanville on 2015-11-25.
//  Copyright © 2015-2016 Christoph Krey. All rights reserved.
//
#import <UIKit/UIKit.h>
#import "MQTTSession.h"
#import "MQTTDecoder.h"
#import "MQTTSessionLegacy.h"
#import "MQTTSessionSynchron.h"
#import "MQTTMessage.h"
#import "MQTTTransport.h"
#import "MQTTCFSocketTransport.h"
#import "MQTTCoreDataPersistence.h"
#import "MQTTSSLSecurityPolicyTransport.h"
//! Project version number for MQTTFramework.
FOUNDATION_EXPORT double MQTTFrameworkVersionNumber;
//! Project version string for MQTTFramework&lt;.
FOUNDATION_EXPORT const unsigned char MQTTFrameworkVersionString[];
// In this header, you should import all the public headers of your framework using statements like #import <MQTTFramework/PublicHeader.h>
frameworks/MQTTFramework.framework/Headers/MQTTInMemoryPersistence.h
New file
@@ -0,0 +1,16 @@
//
//  MQTTInMemoryPersistence.h
//  MQTTClient
//
//  Created by Christoph Krey on 22.03.15.
//  Copyright © 2015-2016 Christoph Krey. All rights reserved.
//
#import <Foundation/Foundation.h>
#import "MQTTPersistence.h"
@interface MQTTInMemoryPersistence : NSObject <MQTTPersistence>
@end
@interface MQTTInMemoryFlow : NSObject <MQTTFlow>
@end
frameworks/MQTTFramework.framework/Headers/MQTTMessage.h
New file
@@ -0,0 +1,131 @@
//
// MQTTMessage.h
// MQTTClient.framework
//
// Copyright © 2013-2016, Christoph Krey
//
// based on
//
// Copyright (c) 2011, 2013, 2lemetry LLC
//
// All rights reserved. This program and the accompanying materials
// are made available under the terms of the Eclipse Public License v1.0
// which accompanies this distribution, and is available at
// http://www.eclipse.org/legal/epl-v10.html
//
// Contributors:
//    Kyle Roche - initial API and implementation and/or initial documentation
//
#import <Foundation/Foundation.h>
/**
 Enumeration of MQTT Quality of Service levels
 */
typedef NS_ENUM(UInt8, MQTTQosLevel) {
    MQTTQosLevelAtMostOnce = 0,
    MQTTQosLevelAtLeastOnce = 1,
    MQTTQosLevelExactlyOnce = 2
};
/**
 Enumeration of MQTT protocol version
 */
typedef NS_ENUM(UInt8, MQTTProtocolVersion) {
    MQTTProtocolVersion31 = 3,
    MQTTProtocolVersion311 = 4
};
typedef NS_ENUM(UInt8, MQTTCommandType) {
    MQTT_None = 0,
    MQTTConnect = 1,
    MQTTConnack = 2,
    MQTTPublish = 3,
    MQTTPuback = 4,
    MQTTPubrec = 5,
    MQTTPubrel = 6,
    MQTTPubcomp = 7,
    MQTTSubscribe = 8,
    MQTTSuback = 9,
    MQTTUnsubscribe = 10,
    MQTTUnsuback = 11,
    MQTTPingreq = 12,
    MQTTPingresp = 13,
    MQTTDisconnect = 14
};
@interface MQTTMessage : NSObject
@property (nonatomic) MQTTCommandType type;
@property (nonatomic) MQTTQosLevel qos;
@property (nonatomic) BOOL retainFlag;
@property (nonatomic) BOOL dupFlag;
@property (nonatomic) UInt16 mid;
@property (strong, nonatomic) NSData * data;
/**
 Enumeration of MQTT Connect return codes
 */
typedef NS_ENUM(NSUInteger, MQTTConnectReturnCode) {
    MQTTConnectAccepted = 0,
    MQTTConnectRefusedUnacceptableProtocolVersion,
    MQTTConnectRefusedIdentiferRejected,
    MQTTConnectRefusedServerUnavailable,
    MQTTConnectRefusedBadUserNameOrPassword,
    MQTTConnectRefusedNotAuthorized
};
// factory methods
+ (MQTTMessage *)connectMessageWithClientId:(NSString*)clientId
                                   userName:(NSString*)userName
                                   password:(NSString*)password
                                  keepAlive:(NSInteger)keeplive
                               cleanSession:(BOOL)cleanSessionFlag
                                       will:(BOOL)will
                                  willTopic:(NSString*)willTopic
                                    willMsg:(NSData*)willData
                                    willQoS:(MQTTQosLevel)willQoS
                                 willRetain:(BOOL)willRetainFlag
                              protocolLevel:(UInt8)protocolLevel;
+ (MQTTMessage *)pingreqMessage;
+ (MQTTMessage *)disconnectMessage;
+ (MQTTMessage *)subscribeMessageWithMessageId:(UInt16)msgId
                                        topics:(NSDictionary *)topics;
+ (MQTTMessage *)unsubscribeMessageWithMessageId:(UInt16)msgId
                                          topics:(NSArray *)topics;
+ (MQTTMessage *)publishMessageWithData:(NSData*)payload
                                onTopic:(NSString*)topic
                                    qos:(MQTTQosLevel)qosLevel
                                  msgId:(UInt16)msgId
                             retainFlag:(BOOL)retain
                                dupFlag:(BOOL)dup;
+ (MQTTMessage *)pubackMessageWithMessageId:(UInt16)msgId;
+ (MQTTMessage *)pubrecMessageWithMessageId:(UInt16)msgId;
+ (MQTTMessage *)pubrelMessageWithMessageId:(UInt16)msgId;
+ (MQTTMessage *)pubcompMessageWithMessageId:(UInt16)msgId;
+ (MQTTMessage *)messageFromData:(NSData *)data;
// instance methods
- (instancetype)initWithType:(MQTTCommandType)type;
- (instancetype)initWithType:(MQTTCommandType)type
                        data:(NSData *)data;
- (instancetype)initWithType:(MQTTCommandType)type
                         qos:(MQTTQosLevel)qos
                        data:(NSData *)data;
- (instancetype)initWithType:(MQTTCommandType)type
                         qos:(MQTTQosLevel)qos
                  retainFlag:(BOOL)retainFlag
                     dupFlag:(BOOL)dupFlag
                        data:(NSData *)data;
- (NSData *)wireFormat;
@end
@interface NSMutableData (MQTT)
- (void)appendByte:(UInt8)byte;
- (void)appendUInt16BigEndian:(UInt16)val;
- (void)appendMQTTString:(NSString*)s;
@end
frameworks/MQTTFramework.framework/Headers/MQTTPersistence.h
New file
@@ -0,0 +1,124 @@
//
//  MQTTPersistence.h
//  MQTTClient
//
//  Created by Christoph Krey on 22.03.15.
//  Copyright © 2015-2016 Christoph Krey. All rights reserved.
//
#import <Foundation/Foundation.h>
#import "MQTTMessage.h"
static BOOL const MQTT_PERSISTENT = NO;
static NSInteger const MQTT_MAX_SIZE = 64 * 1024 * 1024;
static NSInteger const MQTT_MAX_WINDOW_SIZE = 16;
static NSInteger const MQTT_MAX_MESSAGES = 1024;
/** MQTTFlow is an abstraction of the entity to be stored for persistence */
@protocol MQTTFlow
/** The clientID of the flow element */
@property (strong, nonatomic) NSString *clientId;
/** The flag indicating incoming or outgoing flow element */
@property (strong, nonatomic) NSNumber *incomingFlag;
/** The flag indicating if the flow element is retained*/
@property (strong, nonatomic) NSNumber *retainedFlag;
/** The MQTTCommandType of the flow element, might be MQTT_None for offline queueing */
@property (strong, nonatomic) NSNumber *commandType;
/** The MQTTQosLevel of the flow element */
@property (strong, nonatomic) NSNumber *qosLevel;
/** The messageId of the flow element */
@property (strong, nonatomic) NSNumber *messageId;
/** The topic of the flow element */
@property (strong, nonatomic) NSString *topic;
/** The data of the flow element */
@property (strong, nonatomic) NSData *data;
/** The deadline of the flow elelment before (re)trying transmission */
@property (strong, nonatomic) NSDate *deadline;
@end
/** The MQTTPersistence protocol is an abstraction of persistence classes for MQTTSession */
@protocol MQTTPersistence
/** The maximum Window Size for outgoing inflight messages per clientID. Defaults to 16 */
@property (nonatomic) NSUInteger maxWindowSize;
/** The maximum number of messages kept per clientID and direction. Defaults to 1024 */
@property (nonatomic) NSUInteger maxMessages;
/** Indicates if the persistence implementation should make the information permannent. Defaults to NO */
@property (nonatomic) BOOL persistent;
/** The maximum size of the storage used for persistence in total in bytes. Defaults to 1024*1024 bytes */
@property (nonatomic) NSUInteger maxSize;
/** The current Window Size for outgoing inflight messages per clientID.
 * @param clientId
 * @return the current size of the outgoing inflight window
 */
- (NSUInteger)windowSize:(NSString *)clientId;
/** Stores one new message
 * @param clientId
 * @param topic
 * @param data
 * @param retainFlag
 * @param qos
 * @param msgId
 * @param incomingFlag
 * @param commandType
 * @param deadline
 * @return the created MQTTFlow element or nil if the maxWindowSize has been exceeded
 */
- (id<MQTTFlow>)storeMessageForClientId:(NSString *)clientId
                                  topic:(NSString *)topic
                                   data:(NSData *)data
                             retainFlag:(BOOL)retainFlag
                                    qos:(MQTTQosLevel)qos
                                  msgId:(UInt16)msgId
                           incomingFlag:(BOOL)incomingFlag
                            commandType:(UInt8)commandType
                               deadline:(NSDate *)deadline;
/** Deletes an MQTTFlow element
 * @param flow
 */
- (void)deleteFlow:(id<MQTTFlow>)flow;
/** Deletes all MQTTFlow elements of a clientId
 * @param clientId
 */
- (void)deleteAllFlowsForClientId:(NSString *)clientId;
/** Retrieves all MQTTFlow elements of a clientId and direction
 * @param clientId
 * @param incomingFlag
 * @return an NSArray of the retrieved MQTTFlow elements
 */
- (NSArray *)allFlowsforClientId:(NSString *)clientId
                    incomingFlag:(BOOL)incomingFlag;
/** Retrieves an MQTTFlow element
 * @param clientId
 * @param incomingFlag
 * @param messageId
 * @return the retrieved MQTTFlow element or nil if the elememt was not found
 */
- (id<MQTTFlow>)flowforClientId:(NSString *)clientId
                   incomingFlag:(BOOL)incomingFlag
                      messageId:(UInt16)messageId;
/** sync is called to allow the MQTTPersistence implemetation to save data permanently */
- (void)sync;
@end
frameworks/MQTTFramework.framework/Headers/MQTTSSLSecurityPolicy.h
New file
@@ -0,0 +1,158 @@
//
// MQTTSSLSecurityPolicy.h
// MQTTClient.framework
//
// Created by @bobwenx on 15/6/1.
//
// based on
//
// Copyright (c) 2011–2015 AFNetwork (http://alamofire.org/)
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
#import <Foundation/Foundation.h>
#import <Security/Security.h>
/**
## SSL Pinning Modes
The following constants are provided by `MQTTSSLPinningModeNone` as possible SSL pinning modes.
enum {
MQTTSSLPinningModeNone,
MQTTSSLPinningModePublicKey,
MQTTSSLPinningModeCertificate,
}
`MQTTSSLPinningModeNone`
Do not used pinned certificates to validate servers.
`MQTTSSLPinningModePublicKey`
Validate host certificates against public keys of pinned certificates.
`MQTTSSLPinningModeCertificate`
Validate host certificates against pinned certificates.
*/
typedef NS_ENUM(NSUInteger, MQTTSSLPinningMode) {
    // Do not used pinned certificates to validate servers.
    MQTTSSLPinningModeNone,
    // Validate host certificates against public keys of pinned certificates.
    MQTTSSLPinningModePublicKey,
    // Validate host certificates against pinned certificates.
    MQTTSSLPinningModeCertificate,
};
/**
`MQTTSSLSecurityPolicy` evaluates server trust against pinned X.509 certificates and public keys over secure connections.
If your app using security model which require pinning SSL certificates to helps prevent man-in-the-middle attacks
and other vulnerabilities. you need to set securityPolicy to properly value(see MQTTSSLSecurityPolicy.h for more detail).
NOTE: about self-signed server certificates:
if your server using Self-signed certificates to establish SSL/TLS connection, you need to set property:
MQTTSSLSecurityPolicy.allowInvalidCertificates=YES.
If SSL is enabled, by default it only evaluate server's certificates using CA infrastructure, and for most case, this type of check is enough.
However, if your app using security model which require pinning SSL certificates to helps prevent man-in-the-middle attacks
and other vulnerabilities. you may need to set securityPolicy to properly value(see MQTTSSLSecurityPolicy.h for more detail).
NOTE: about self-signed server certificates:
In CA infrastructure, you may establish a SSL/TLS connection with server which using self-signed certificates
by install the certificates into OS keychain(either programmatically or manually). however, this method has some disadvantages:
1. every socket you app created will trust certificates you added.
2. if user choice to remove certificates from keychain, you app need to handling certificates re-adding.
If you only want to verify the cert for the socket you are creating and for no other sockets in your app, you need to use
MQTTSSLSecurityPolicy.
And if you use self-signed server certificates, your need to set property: MQTTSSLSecurityPolicy.allowInvalidCertificates=YES
Adding pinned SSL certificates to your app helps prevent man-in-the-middle attacks and other vulnerabilities.
Applications dealing with sensitive customer data or financial information are strongly encouraged to route all communication
over an SSL/TLS connection with SSL pinning configured and enabled.
*/
@interface MQTTSSLSecurityPolicy : NSObject
/**
The criteria by which server trust should be evaluated against the pinned SSL certificates. Defaults to `MQTTSSLPinningMode`.
*/
@property (readonly, nonatomic, assign) MQTTSSLPinningMode SSLPinningMode;
/**
Whether to evaluate an entire SSL certificate chain, or just the leaf certificate. Defaults to `YES`.
*/
@property (nonatomic, assign) BOOL validatesCertificateChain;
/**
The certificates used to evaluate server trust according to the SSL pinning mode. By default, this property is set to any (`.cer`) certificates included in the app bundle.
Note: Array item type: NSData - Bytes of X.509 certificate file in der format.
Note that if you create an array with duplicate certificates, the duplicate certificates will be removed.
*/
@property (nonatomic, strong) NSArray *pinnedCertificates;
/**
Whether or not to trust servers with an invalid or expired SSL certificates. Defaults to `NO`.
Note: If your server-certificates are self signed, your should set this property to 'YES'.
*/
@property (nonatomic, assign) BOOL allowInvalidCertificates;
/**
Whether or not to validate the domain name in the certificate's CN field. Defaults to `YES`.
*/
@property (nonatomic, assign) BOOL validatesDomainName;
///-----------------------------------------
/// @name Getting Specific Security Policies
///-----------------------------------------
/**
Returns the shared default security policy, which does not allow invalid certificates, validates domain name, and does not validate against pinned certificates or public keys.
@return The default security policy.
*/
+ (instancetype)defaultPolicy;
///---------------------
/// @name Initialization
///---------------------
/**
Creates and returns a security policy with the specified pinning mode.
@param pinningMode The SSL pinning mode.
@return A new security policy.
*/
+ (instancetype)policyWithPinningMode:(MQTTSSLPinningMode)pinningMode;
///------------------------------
/// @name Evaluating Server Trust
///------------------------------
/**
Whether or not the specified server trust should be accepted, based on the security policy.
This method should be used when responding to an authentication challenge from a server.
@param serverTrust The X.509 certificate trust of the server.
@param domain The domain of serverTrust. If `nil`, the domain will not be validated.
@return Whether or not to trust the server.
*/
- (BOOL)evaluateServerTrust:(SecTrustRef)serverTrust
                  forDomain:(NSString *)domain;
@end
frameworks/MQTTFramework.framework/Headers/MQTTSSLSecurityPolicyDecoder.h
New file
@@ -0,0 +1,18 @@
//
// MQTTSSLSecurityPolicyDecoder.h
// MQTTClient.framework
//
// Copyright © 2013-2016, Christoph Krey
//
#import <Foundation/Foundation.h>
#import "MQTTSSLSecurityPolicy.h"
#import "MQTTCFSocketDecoder.h"
@interface MQTTSSLSecurityPolicyDecoder : MQTTCFSocketDecoder
@property(strong, nonatomic) MQTTSSLSecurityPolicy *securityPolicy;
@property(strong, nonatomic) NSString *securityDomain;
@end
frameworks/MQTTFramework.framework/Headers/MQTTSSLSecurityPolicyEncoder.h
New file
@@ -0,0 +1,17 @@
//
// MQTTSSLSecurityPolicyEncoder.h
// MQTTClient.framework
//
// Copyright © 2013-2016, Christoph Krey
//
#import <Foundation/Foundation.h>
#import "MQTTSSLSecurityPolicy.h"
#import "MQTTCFSocketEncoder.h"
@interface MQTTSSLSecurityPolicyEncoder : MQTTCFSocketEncoder
@property(strong, nonatomic) MQTTSSLSecurityPolicy *securityPolicy;
@property(strong, nonatomic) NSString *securityDomain;
@end
frameworks/MQTTFramework.framework/Headers/MQTTSSLSecurityPolicyTransport.h
New file
@@ -0,0 +1,30 @@
//
//  MQTTSSLSecurityPolicyTransport.h
//  MQTTClient
//
//  Created by Christoph Krey on 06.12.15.
//  Copyright © 2015-2016 Christoph Krey. All rights reserved.
//
#import "MQTTTransport.h"
#import "MQTTSSLSecurityPolicy.h"
#import "MQTTCFSocketTransport.h"
/** MQTTSSLSecurityPolicyTransport
 * implements an extension of the MQTTCFSocketTransport by replacing the OS's certificate chain evaluation
 */
@interface MQTTSSLSecurityPolicyTransport : MQTTCFSocketTransport
/**
 * The security policy used to evaluate server trust for secure connections.
 *
 * if your app using security model which require pinning SSL certificates to helps prevent man-in-the-middle attacks
 * and other vulnerabilities. you need to set securityPolicy to properly value(see MQTTSSLSecurityPolicy.h for more detail).
 *
 * NOTE: about self-signed server certificates:
 * if your server using Self-signed certificates to establish SSL/TLS connection, you need to set property:
 * MQTTSSLSecurityPolicy.allowInvalidCertificates=YES.
 */
@property (strong, nonatomic) MQTTSSLSecurityPolicy *securityPolicy;
@end
frameworks/MQTTFramework.framework/Headers/MQTTSession.h
New file
@@ -0,0 +1,778 @@
//
// MQTTSession.h
// MQTTClient.framework
//
/**
 Using MQTT in your Objective-C application
 @author Christoph Krey krey.christoph@gmail.com
 @copyright Copyright © 2013-2016, Christoph Krey
 based on Copyright (c) 2011, 2013, 2lemetry LLC
    All rights reserved. This program and the accompanying materials
    are made available under the terms of the Eclipse Public License v1.0
    which accompanies this distribution, and is available at
    http://www.eclipse.org/legal/epl-v10.html
 @see http://mqtt.org
 */
#import <Foundation/Foundation.h>
#import "MQTTMessage.h"
#import "MQTTPersistence.h"
#import "MQTTTransport.h"
@class MQTTSession;
@class MQTTSSLSecurityPolicy;
/**
 Enumeration of MQTTSession states
 */
typedef NS_ENUM(NSInteger, MQTTSessionStatus) {
    MQTTSessionStatusCreated,
    MQTTSessionStatusConnecting,
    MQTTSessionStatusConnected,
    MQTTSessionStatusDisconnecting,
    MQTTSessionStatusClosed,
    MQTTSessionStatusError
};
/**
 Enumeration of MQTTSession events
 */
typedef NS_ENUM(NSInteger, MQTTSessionEvent) {
    MQTTSessionEventConnected,
    MQTTSessionEventConnectionRefused,
    MQTTSessionEventConnectionClosed,
    MQTTSessionEventConnectionError,
    MQTTSessionEventProtocolError,
    MQTTSessionEventConnectionClosedByBroker
};
/**
 The error domain used for all errors created by MQTTSession
 */
extern NSString * const MQTTSessionErrorDomain;
/**
 The error codes used for all errors created by MQTTSession
 */
typedef NS_ENUM(NSInteger, MQTTSessionError) {
    MQTTSessionErrorConnectionRefused = -8, // Sent if the server closes the connection without sending an appropriate error CONNACK
    MQTTSessionErrorIllegalMessageReceived = -7,
    MQTTSessionErrorDroppingOutgoingMessage = -6, // For some reason the value is the same as for MQTTSessionErrorNoResponse
    MQTTSessionErrorNoResponse = -6, // For some reason the value is the same as for MQTTSessionErrorDroppingOutgoingMessage
    MQTTSessionErrorEncoderNotReady = -5,
    MQTTSessionErrorInvalidConnackReceived = -2, // Sent if the message received from server was an invalid connack message
    MQTTSessionErrorNoConnackReceived = -1, // Sent if first message received from server was no connack message
    MQTTSessionErrorConnackUnacceptableProtocolVersion = 1, // Value as defined by MQTT Protocol
    MQTTSessionErrorConnackIdentifierRejected = 2, // Value as defined by MQTT Protocol
    MQTTSessionErrorConnackServeUnavailable = 3, // Value as defined by MQTT Protocol
    MQTTSessionErrorConnackBadUsernameOrPassword = 4, // Value as defined by MQTT Protocol
    MQTTSessionErrorConnackNotAuthorized = 5, // Value as defined by MQTT Protocol
    MQTTSessionErrorConnackReserved = 6, // Should be value 6-255, as defined by MQTT Protocol
};
/** Session delegate gives your application control over the MQTTSession
 @note all callback methods are optional
 */
@protocol MQTTSessionDelegate <NSObject>
@optional
/** gets called when a new message was received
 @param session the MQTTSession reporting the new message
 @param data the data received, might be zero length
 @param topic the topic the data was published to
 @param qos the qos of the message
 @param retained indicates if the data retransmitted from server storage
 @param mid the Message Identifier of the message if qos = 1 or 2, zero otherwise
 */
- (void)newMessage:(MQTTSession *)session
              data:(NSData *)data
           onTopic:(NSString *)topic
               qos:(MQTTQosLevel)qos
          retained:(BOOL)retained
               mid:(unsigned int)mid;
/** gets called when a new message was received
 @param session the MQTTSession reporting the new message
 @param data the data received, might be zero length
 @param topic the topic the data was published to
 @param qos the qos of the message
 @param retained indicates if the data retransmitted from server storage
 @param mid the Message Identifier of the message if qos = 1 or 2, zero otherwise
 @return true if the message was or will be processed, false if the message shall not be ack-ed
 */
- (BOOL)newMessageWithFeedback:(MQTTSession *)session
                          data:(NSData *)data
                       onTopic:(NSString *)topic
                           qos:(MQTTQosLevel)qos
                      retained:(BOOL)retained
                           mid:(unsigned int)mid;
/** for mqttio-OBJC backward compatibility
 @param session see newMessage for description
 @param data see newMessage for description
 @param topic see newMessage for description
 */
- (void)session:(MQTTSession*)session newMessage:(NSData*)data onTopic:(NSString*)topic;
/** gets called when a connection is established, closed or a problem occurred
 @param session the MQTTSession reporting the event
 @param eventCode the code of the event
 @param error an optional additional error object with additional information
 */
- (void)handleEvent:(MQTTSession *)session event:(MQTTSessionEvent)eventCode error:(NSError *)error;
/** for mqttio-OBJC backward compatibility
 @param session the MQTTSession reporting the event
 @param eventCode the code of the event
 */
- (void)session:(MQTTSession*)session handleEvent:(MQTTSessionEvent)eventCode;
/** gets called when a connection has been successfully established
 @param session the MQTTSession reporting the connect
 */
- (void)connected:(MQTTSession *)session;
/** gets called when a connection has been successfully established
 @param session the MQTTSession reporting the connect
 @param sessionPresent represents the Session Present flag sent by the broker
 */
- (void)connected:(MQTTSession *)session sessionPresent:(BOOL)sessionPresent;
/** gets called when a connection has been refused
 @param session the MQTTSession reporting the refusal
 @param error an optional additional error object with additional information
 */
- (void)connectionRefused:(MQTTSession *)session error:(NSError *)error;
/** gets called when a connection has been closed
 @param session the MQTTSession reporting the close
 */
- (void)connectionClosed:(MQTTSession *)session;
/** gets called when a connection error happened
 @param session the MQTTSession reporting the connect error
 @param error an optional additional error object with additional information
 */
- (void)connectionError:(MQTTSession *)session error:(NSError *)error;
/** gets called when an MQTT protocol error happened
 @param session the MQTTSession reporting the protocol error
 @param error an optional additional error object with additional information
 */
- (void)protocolError:(MQTTSession *)session error:(NSError *)error;
/** gets called when a published message was actually delivered
 @param session the MQTTSession reporting the delivery
 @param msgID the Message Identifier of the delivered message
 @note this method is called after a publish with qos 1 or 2 only
 */
- (void)messageDelivered:(MQTTSession *)session msgID:(UInt16)msgID;
/** gets called when a subscription is acknowledged by the MQTT broker
 @param session the MQTTSession reporting the acknowledge
 @param msgID the Message Identifier of the SUBSCRIBE message
 @param qoss an array containing the granted QoS(s) related to the SUBSCRIBE message
    (see subscribeTopic, subscribeTopics)
 */
- (void)subAckReceived:(MQTTSession *)session msgID:(UInt16)msgID grantedQoss:(NSArray<NSNumber *> *)qoss;
/** gets called when an unsubscribe is acknowledged by the MQTT broker
 @param session the MQTTSession reporting the acknowledge
 @param msgID the Message Identifier of the UNSUBSCRIBE message
 */
- (void)unsubAckReceived:(MQTTSession *)session msgID:(UInt16)msgID;
/** gets called when a command is sent to the MQTT broker
 use this for low level monitoring of the MQTT connection
 @param session the MQTTSession reporting the sent command
 @param type the MQTT command type
 @param qos the Quality of Service of the command
 @param retained the retained status of the command
 @param duped the duplication status of the command
 @param mid the Message Identifier of the command
 @param data the payload data of the command if any, might be zero length
 */
- (void)sending:(MQTTSession *)session type:(MQTTCommandType)type qos:(MQTTQosLevel)qos retained:(BOOL)retained duped:(BOOL)duped mid:(UInt16)mid data:(NSData *)data;
/** gets called when a command is received from the MQTT broker
 use this for low level monitoring of the MQTT connection
 @param session the MQTTSession reporting the received command
 @param type the MQTT command type
 @param qos the Quality of Service of the command
 @param retained the retained status of the command
 @param duped the duplication status of the command
 @param mid the Message Identifier of the command
 @param data the payload data of the command if any, might be zero length
 */
- (void)received:(MQTTSession *)session type:(MQTTCommandType)type qos:(MQTTQosLevel)qos retained:(BOOL)retained duped:(BOOL)duped mid:(UInt16)mid data:(NSData *)data;
/** gets called when a command is received from the MQTT broker
 use this for low level control of the MQTT connection
 @param session the MQTTSession reporting the received command
 @param type the MQTT command type
 @param qos the Quality of Service of the command
 @param retained the retained status of the command
 @param duped the duplication status of the command
 @param mid the Message Identifier of the command
 @param data the payload data of the command if any, might be zero length
 @return true if the sessionmanager should ignore the received message
 */
- (BOOL)ignoreReceived:(MQTTSession *)session type:(MQTTCommandType)type qos:(MQTTQosLevel)qos retained:(BOOL)retained duped:(BOOL)duped mid:(UInt16)mid data:(NSData *)data;
/** gets called when the content of MQTTClients internal buffers change
 use for monitoring the completion of transmitted and received messages
 @param session the MQTTSession reporting the change
 @param queued for backward compatibility only: MQTTClient does not queue messages anymore except during QoS protocol
 @param flowingIn the number of incoming messages not acknowledged by the MQTTClient yet
 @param flowingOut the number of outgoing messages not yet acknowledged by the MQTT broker
 */
- (void)buffered:(MQTTSession *)session
          queued:(NSUInteger)queued
       flowingIn:(NSUInteger)flowingIn
      flowingOut:(NSUInteger)flowingOut;
/** gets called when the content of MQTTClients internal buffers change
 use for monitoring the completion of transmitted and received messages
 @param session the MQTTSession reporting the change
 @param flowingIn the number of incoming messages not acknowledged by the MQTTClient yet
 @param flowingOut the number of outgoing messages not yet acknowledged by the MQTT broker
 */
- (void)buffered:(MQTTSession *)session
       flowingIn:(NSUInteger)flowingIn
      flowingOut:(NSUInteger)flowingOut;
@end
typedef void (^MQTTConnectHandler)(NSError *error);
typedef void (^MQTTDisconnectHandler)(NSError *error);
typedef void (^MQTTSubscribeHandler)(NSError *error, NSArray<NSNumber *> *gQoss);
typedef void (^MQTTUnsubscribeHandler)(NSError *error);
typedef void (^MQTTPublishHandler)(NSError *error);
/** Session implements the MQTT protocol for your application
 *
 */
@interface MQTTSession : NSObject
/** set this member variable to receive delegate messages
 @code
 #import "MQTTClient.h"
 @interface MyClass : NSObject <MQTTSessionDelegate>
 ...
 @end
 ...
 MQTTSession *session = [[MQTTSession alloc] init];
 session.delegate = self;
 ...
 - (void)handleEvent:(MQTTSession *)session
        event:(MQTTSessionEvent)eventCode
        error:(NSError *)error {
    ...
 }
 - (void)newMessage:(MQTTSession *)session
        data:(NSData *)data
        onTopic:(NSString *)topic
        qos:(MQTTQosLevel)qos
        retained:(BOOL)retained
        mid:(unsigned int)mid {
    ...
 }
 @endcode
 */
@property (weak, nonatomic) id<MQTTSessionDelegate> delegate;
/** Control MQTT persistence by setting the properties of persistence before connecting to an MQTT broker.
    The settings are specific to a clientId.
    persistence.persistent = YES or NO (default) to establish file or in memory persistence. IMPORTANT: set immediately after creating the MQTTSession before calling any other method. Otherwise the default value (NO) will be used
        for this session.
    persistence.maxWindowSize (a positive number, default is 16) to control the number of messages sent before waiting for acknowledgement in Qos 1 or 2. Additional messages are
        stored and transmitted later.
    persistence.maxSize (a positive number of bytes, default is 64 MB) to limit the size of the persistence file. Messages published after the limit is reached are dropped.
    persistence.maxMessages (a positive number, default is 1024) to limit the number of messages stored. Additional messages published are dropped.
    Messages are deleted after they have been acknowledged.
*/
@property (strong, nonatomic) id<MQTTPersistence> persistence;
/** block called once when connection is established
 */
@property (copy, nonatomic) MQTTConnectHandler connectHandler;
/** block called when connection is established
 */
@property (strong) void (^connectionHandler)(MQTTSessionEvent event);
/** block called when message is received
 */
@property (strong) void (^messageHandler)(NSData* message, NSString* topic);
/** Session status
 */
@property (nonatomic, readonly) MQTTSessionStatus status;
/** Indicates if the broker found a persistent session when connecting with cleanSession:FALSE
 */
@property (nonatomic, readonly) BOOL sessionPresent;
/** see initWithClientId for description
 * @param clientId The Client Identifier identifies the Client to the Server. If nil, a random clientId is generated.
 */
@property (strong, nonatomic) NSString *clientId;
/** see userName an NSString object containing the user's name (or ID) for authentication. May be nil. */
@property (strong, nonatomic) NSString *userName;
/** see password an NSString object containing the user's password. If userName is nil, password must be nil as well.*/
@property (strong, nonatomic) NSString *password;
/** see keepAliveInterval The Keep Alive is a time interval measured in seconds.
 * The MQTTClient ensures that the interval between Control Packets being sent does not exceed
 * the Keep Alive value. In the  absence of sending any other Control Packets, the Client sends a PINGREQ Packet.
 */
@property (nonatomic) UInt16 keepAliveInterval;
/** leanSessionFlag specifies if the server should discard previous session information. */
@property (nonatomic) BOOL cleanSessionFlag;
/** willFlag If the Will Flag is set to YES this indicates that
 * a Will Message MUST be published by the Server when the Server detects
 * that the Client is disconnected for any reason other than the Client flowing a DISCONNECT Packet.
 */
@property (nonatomic) BOOL willFlag;
/** willTopic If the Will Flag is set to YES, the Will Topic is a string, nil otherwise. */
@property (strong, nonatomic) NSString *willTopic;
/** willMsg If the Will Flag is set to YES the Will Message must be specified, nil otherwise. */
@property (strong, nonatomic) NSData *willMsg;
/** willQoS specifies the QoS level to be used when publishing the Will Message.
 * If the Will Flag is set to NO, then the Will QoS MUST be set to 0.
 * If the Will Flag is set to YES, the Will QoS MUST be a valid MQTTQosLevel.
 */
@property (nonatomic) MQTTQosLevel willQoS;
/** willRetainFlag indicates if the server should publish the Will Messages with retainFlag.
 * If the Will Flag is set to NO, then the Will Retain Flag MUST be set to NO .
 * If the Will Flag is set to YES: If Will Retain is set to NO, the Serve
 * MUST publish the Will Message as a non-retained publication [MQTT-3.1.2-14].
 * If Will Retain is set to YES, the Server MUST publish the Will Message as a retained publication [MQTT-3.1.2-15].
 */
@property (nonatomic) BOOL willRetainFlag;
/** protocolLevel specifies the protocol to be used */
@property (nonatomic) MQTTProtocolVersion protocolLevel;
/** runLoop The runLoop where the streams are scheduled. If nil, defaults to [NSRunLoop currentRunLoop]. */
@property (strong, nonatomic) NSRunLoop *runLoop;
/** runLoopMode The runLoopMode where the streams are scheduled. If nil, defaults to NSRunLoopCommonModes. */
@property (strong, nonatomic) NSString *runLoopMode;
/** The security policy used to evaluate server trust for secure connections.
 * (see MQTTSSLSecurityPolicy.h for more detail).
 */
@property (strong, nonatomic) MQTTSSLSecurityPolicy *securityPolicy;
/** for mqttio-OBJC backward compatibility
 the connect message used is stored here
 */
@property (strong, nonatomic) MQTTMessage *connectMessage;
/** the transport provider for MQTTClient
 *
 * assign an in instance of a class implementing the MQTTTransport protocol e.g.
 * MQTTCFSocketTransport before connecting.
 */
@property (strong, nonatomic) id <MQTTTransport> transport;
/** certificates an NSArray holding client certificates or nil */
@property (strong, nonatomic) NSArray *certificates;
/** connect to the given host through the given transport with the given
 *  MQTT session parameters asynchronously
 *
 *  @exception NSInternalInconsistencyException if the parameters are invalid
 *
 */
- (void)connect;
/** connects to the specified MQTT server
 @param connectHandler identifies a block which is executed on successfull or unsuccessfull connect. Might be nil
 error is nil in the case of a successful connect
 sessionPresent indicates in MQTT 3.1.1 if persistent session data was present at the server
 @return nothing and returns immediately. To check the connect results, register as an MQTTSessionDelegate and
 - watch for events
 - watch for connect or connectionRefused messages
 - watch for error messages
 or use the connectHandler block
 @code
 #import "MQTTClient.h"
 MQTTSession *session = [[MQTTSession alloc] init];
 ...
 [session connectWithConnectHandler:^(NSError *error, BOOL sessionPresent) {
 if (error) {
 NSLog(@"Error Connect %@", error.localizedDescription);
 } else {
 NSLog(@"Connected sessionPresent:%d", sessionPresent);
 }
 }];
 @endcode
 */
- (void)connectWithConnectHandler:(MQTTConnectHandler)connectHandler;
/** disconnect gracefully
 *
 */
- (void)disconnect;
/** initialises the MQTT session with default values
 @return the initialised MQTTSession object
 @code
 #import "MQTTClient.h"
 MQTTSession *session = [[MQTTSession alloc] init];
 @endcode
 */
- (MQTTSession *)init;
/** subscribes to a topic at a specific QoS level
 @param topic see subscribeToTopic:atLevel:subscribeHandler: for description
 @param qosLevel  see subscribeToTopic:atLevel:subscribeHandler: for description
 @return the Message Identifier of the SUBSCRIBE message.
 @note returns immediately. To check results, register as an MQTTSessionDelegate and watch for events.
 @code
 #import "MQTTClient.h"
 MQTTSession *session = [[MQTTSession alloc] init];
 ...
 [session connect];
 ...
 [session subscribeToTopic:@"example/#" atLevel:2];
 @endcode
 */
- (UInt16)subscribeToTopic:(NSString *)topic atLevel:(MQTTQosLevel)qosLevel;
/** subscribes to a topic at a specific QoS level
 @param topic the Topic Filter to subscribe to.
 @param qosLevel specifies the QoS Level of the subscription.
 qosLevel can be 0, 1, or 2.
 @param subscribeHandler identifies a block which is executed on successfull or unsuccessfull subscription.
 Might be nil. error is nil in the case of a successful subscription. In this case gQoss represents an
 array of grantes Qos
 @return the Message Identifier of the SUBSCRIBE message.
 @note returns immediately. To check results, register as an MQTTSessionDelegate and watch for events.
 @code
 #import "MQTTClient.h"
 MQTTSession *session = [[MQTTSession alloc] init];
 ...
 [session connect];
 ...
 [session subscribeToTopic:@"example/#" atLevel:2 subscribeHandler:^(NSError *error, NSArray<NSNumber *> *gQoss){
    if (error) {
        NSLog(@"Subscription failed %@", error.localizedDescription);
    } else {
        NSLog(@"Subscription sucessfull! Granted Qos: %@", gQoss);
    }
 }];
 @endcode
 */
- (UInt16)subscribeToTopic:(NSString *)topic atLevel:(MQTTQosLevel)qosLevel subscribeHandler:(MQTTSubscribeHandler)subscribeHandler;
/** subscribes a number of topics
 @param topics an NSDictionary<NSString *, NSNumber *> containing the Topic Filters to subscribe to as keys and
    the corresponding QoS as NSNumber values
 @return the Message Identifier of the SUBSCRIBE message.
 @note returns immediately. To check results, register as an MQTTSessionDelegate and watch for events.
 @code
 #import "MQTTClient.h"
 MQTTSession *session = [[MQTTSession alloc] init];
 ...
 [session connect];
 [session subscribeToTopics:@{
 @"example/#": @(0),
 @"example/status": @(2),
 @"other/#": @(1)
 }];
 @endcode
 */
- (UInt16)subscribeToTopics:(NSDictionary<NSString *, NSNumber *> *)topics;
/** subscribes a number of topics
 @param topics an NSDictionary<NSString *, NSNumber *> containing the Topic Filters to subscribe to as keys and
    the corresponding QoS as NSNumber values
 @param subscribeHandler identifies a block which is executed on successfull or unsuccessfull subscription.
    Might be nil. error is nil in the case of a successful subscription. In this case gQoss represents an
    array of grantes Qos
 @return the Message Identifier of the SUBSCRIBE message.
 @note returns immediately. To check results, register as an MQTTSessionDelegate and watch for events.
 @code
 #import "MQTTClient.h"
 MQTTSession *session = [[MQTTSession alloc] init];
 ...
 [session connect];
 [session subscribeToTopics:@{
    @"example/#": @(0),
    @"example/status": @(2),
    @"other/#": @(1)
 } subscribeHandler:^(NSError *error, NSArray<NSNumber *> *gQoss){
    if (error) {
        NSLog(@"Subscription failed %@", error.localizedDescription);
    } else {
        NSLog(@"Subscription sucessfull! Granted Qos: %@", gQoss);
    }
 }];
 @endcode
 */
- (UInt16)subscribeToTopics:(NSDictionary<NSString *, NSNumber *> *)topics subscribeHandler:(MQTTSubscribeHandler)subscribeHandler;
/** unsubscribes from a topic
 @param topic the Topic Filter to unsubscribe from.
 @return the Message Identifier of the UNSUBSCRIBE message.
 @note returns immediately. To check results, register as an MQTTSessionDelegate and watch for events.
 @code
 #import "MQTTClient.h"
 MQTTSession *session = [[MQTTSession alloc] init];
 ...
 [session connect];
 [session unsubscribeTopic:@"example/#"];
 @endcode
 */
- (UInt16)unsubscribeTopic:(NSString *)topic;
/** unsubscribes from a topic
 @param topic the Topic Filter to unsubscribe from.
 @param unsubscribeHandler identifies a block which is executed on successfull or unsuccessfull subscription.
 Might be nil. error is nil in the case of a successful subscription. In this case gQoss represents an
 array of grantes Qos
 @return the Message Identifier of the UNSUBSCRIBE message.
 @note returns immediately.
 */
- (UInt16)unsubscribeTopic:(NSString *)topic unsubscribeHandler:(MQTTUnsubscribeHandler)unsubscribeHandler;
/** unsubscribes from a number of topics
 @param topics an NSArray<NSString *> of topics to unsubscribe from
 @return the Message Identifier of the UNSUBSCRIBE message.
 @note returns immediately. To check results, register as an MQTTSessionDelegate and watch for events.
 @code
 #import "MQTTClient.h"
 MQTTSession *session = [[MQTTSession alloc] init];
 ...
 [session connect];
 [session unsubscribeTopics:@[
 @"example/#",
 @"example/status",
 @"other/#"
 ]];
 @endcode
 */
- (UInt16)unsubscribeTopics:(NSArray<NSString *> *)topics;
/** unsubscribes from a number of topics
 @param topics an NSArray<NSString *> of topics to unsubscribe from
 @param unsubscribeHandler identifies a block which is executed on successfull or unsuccessfull subscription.
    Might be nil. error is nil in the case of a successful subscription. In this case gQoss represents an
    array of grantes Qos
 @return the Message Identifier of the UNSUBSCRIBE message.
 @note returns immediately.
 */
- (UInt16)unsubscribeTopics:(NSArray<NSString *> *)topics unsubscribeHandler:(MQTTUnsubscribeHandler)unsubscribeHandler;
/** publishes data on a given topic at a specified QoS level and retain flag
 @param data the data to be sent. length may range from 0 to 268,435,455 - 4 - _lengthof-topic_ bytes. Defaults to length 0.
 @param topic the Topic to identify the data
 @param retainFlag if YES, data is stored on the MQTT broker until overwritten by the next publish with retainFlag = YES
 @param qos specifies the Quality of Service for the publish
 qos can be 0, 1, or 2.
 @return the Message Identifier of the PUBLISH message. Zero if qos 0. If qos 1 or 2, zero if message was dropped
 @note returns immediately. To check results, register as an MQTTSessionDelegate and watch for events.
 @code
 #import "MQTTClient.h"
 MQTTSession *session = [[MQTTSession alloc] init];
 ...
 [session connect];
 [session publishData:[@"Sample Data" dataUsingEncoding:NSUTF8StringEncoding]
 topic:@"example/data"
 retain:YES
 qos:1];
 @endcode
 */
- (UInt16)publishData:(NSData *)data onTopic:(NSString *)topic retain:(BOOL)retainFlag qos:(MQTTQosLevel)qos;
/** publishes data on a given topic at a specified QoS level and retain flag
 @param data the data to be sent. length may range from 0 to 268,435,455 - 4 - _lengthof-topic_ bytes. Defaults to length 0.
 @param topic the Topic to identify the data
 @param retainFlag if YES, data is stored on the MQTT broker until overwritten by the next publish with retainFlag = YES
 @param qos specifies the Quality of Service for the publish
 qos can be 0, 1, or 2.
 @param publishHandler identifies a block which is executed on successfull or unsuccessfull connect. Might be nil
 error is nil in the case of a successful connect
 sessionPresent indicates in MQTT 3.1.1 if persistent session data was present at the server
 @return the Message Identifier of the PUBLISH message. Zero if qos 0. If qos 1 or 2, zero if message was dropped
 @note returns immediately. To check results, register as an MQTTSessionDelegate and watch for events.
 @code
 #import "MQTTClient.h"
 MQTTSession *session = [[MQTTSession alloc] init];
 ...
 [session connect];
 [session publishData:[@"Sample Data" dataUsingEncoding:NSUTF8StringEncoding]
 topic:@"example/data"
 retain:YES
 qos:1
 publishHandler:^(NSError *error){
 if (error) {
 DDLogVerbose(@"error: %@ %@", error.localizedDescription, payload);
 } else {
 DDLogVerbose(@"delivered:%@", payload);
 delivered++;
 }
 }];
 @endcode
 */
- (UInt16)publishData:(NSData *)data onTopic:(NSString *)topic retain:(BOOL)retainFlag qos:(MQTTQosLevel)qos publishHandler:(MQTTPublishHandler)publishHandler;
/** closes an MQTTSession gracefully
 If the connection was successfully established before, a DISCONNECT is sent.
 @param disconnectHandler identifies a block which is executed on successfull or unsuccessfull disconnect. Might be nil. error is nil in the case of a successful disconnect
 @code
 #import "MQTTClient.h"
 MQTTSession *session = [[MQTTSession alloc] init];
 ...
 [session connect];
 ...
 [session closeWithDisconnectHandler^(NSError *error) {
    if (error) {
        NSLog(@"Error Disconnect %@", error.localizedDescription);
    }
    NSLog(@"Session closed");
 }];
 @endcode
 */
- (void)closeWithDisconnectHandler:(MQTTDisconnectHandler)disconnectHandler;
/** closes an MQTTSession gracefully
  */
- (void)close;
@end
frameworks/MQTTFramework.framework/Headers/MQTTSessionLegacy.h
New file
@@ -0,0 +1,456 @@
//
// MQTTSessionLegacy.h
// MQTTClient.framework
//
/**
 Using MQTT in your Objective-C application
 This file contains definitions for mqttio-OBJC backward compatibility
 @author Christoph Krey krey.christoph@gmail.com
 @copyright Copyright © 2013-2016, Christoph Krey
 based on Copyright (c) 2011, 2013, 2lemetry LLC
    All rights reserved. This program and the accompanying materials
    are made available under the terms of the Eclipse Public License v1.0
    which accompanies this distribution, and is available at
    http://www.eclipse.org/legal/epl-v10.html
 @see http://mqtt.org
 */
#import <Foundation/Foundation.h>
#import "MQTTSession.h"
@interface MQTTSession(Create)
/** convenience initializer
 @param clientId see clientId for description.
 @param userName see username for description.
 @param password see password for description.
 @param keepAliveInterval see keepAliveInterval for description.
 @param cleanSessionFlag see cleanSessionFlag for description.
 @param willFlag see willFlag for description.
 @param willTopic see willTopic for description.
 @param willMsg see willMsg for description.
 @param willQoS see willQos for description.
 @param willRetainFlag see willRetainFlg for description.
 @param protocolLevel see protocolLevel for description.
 @param runLoop see runLoop for description.
 @param runLoopMode see runLoopMode for description.
 @return the initialised MQTTSession object
 @exception NSInternalInconsistencyException if the parameters are invalid
 */
- (MQTTSession *)initWithClientId:(NSString *)clientId
                         userName:(NSString *)userName
                         password:(NSString *)password
                        keepAlive:(UInt16)keepAliveInterval
                     cleanSession:(BOOL)cleanSessionFlag
                             will:(BOOL)willFlag
                        willTopic:(NSString *)willTopic
                          willMsg:(NSData *)willMsg
                          willQoS:(MQTTQosLevel)willQoS
                   willRetainFlag:(BOOL)willRetainFlag
                    protocolLevel:(UInt8)protocolLevel
                          runLoop:(NSRunLoop *)runLoop
                          forMode:(NSString *)runLoopMode;
/** alternative initializer
 @param clientId see initWithClientId for description.
 @param userName see initWithClientId for description.
 @param password see initWithClientId for description.
 @param keepAliveInterval see initWithClientId for description.
 @param cleanSessionFlag see initWithClientId for description.
 @param willFlag see initWithClientId for description.
 @param willTopic see initWithClientId for description.
 @param willMsg see initWithClientId for description.
 @param willQoS see initWithClientId for description.
 @param willRetainFlag see initWithClientId for description.
 @param protocolLevel see initWithClientId for description.
 @param runLoop see initWithClientId for description.
 @param runLoopMode see initWithClientId for description.
 @param securityPolicy see initWithClientId for description.
 @return the initialised MQTTSession object
 @exception NSInternalInconsistencyException if the parameters are invalid
 */
- (MQTTSession *)initWithClientId:(NSString *)clientId
                         userName:(NSString *)userName
                         password:(NSString *)password
                        keepAlive:(UInt16)keepAliveInterval
                     cleanSession:(BOOL)cleanSessionFlag
                             will:(BOOL)willFlag
                        willTopic:(NSString *)willTopic
                          willMsg:(NSData *)willMsg
                          willQoS:(MQTTQosLevel)willQoS
                   willRetainFlag:(BOOL)willRetainFlag
                    protocolLevel:(UInt8)protocolLevel
                          runLoop:(NSRunLoop *)runLoop
                          forMode:(NSString *)runLoopMode
                   securityPolicy:(MQTTSSLSecurityPolicy *) securityPolicy;
/** initialises the MQTT session
 *
 * this constructor can specifies SSL securityPolicy. the default value of securityPolicy is nil(which do nothing).
 *
 * if SSL is enabled, by default it only evaluate server's certificates using CA infrastructure, and for most case, this type of check is enough.
 * However, if your app using security model which require pinning SSL certificates to helps prevent man-in-the-middle attacks
 * and other vulnerabilities. you may need to set securityPolicy to properly value(see MQTTSSLSecurityPolicy.h for more detail).
 *
 * NOTE: about self-signed server certificates:
 * In CA infrastructure, you may establish a SSL/TLS connection with server which using self-signed certificates
 * by install the certificates into OS keychain(either programmatically or manually). however, this method has some disadvantages:
 *  1. every socket you app created will trust certificates you added.
 *  2. if user choice to remove certificates from keychain, you app need to handling certificates re-adding.
 *
 * If you only want to verify the cert for the socket you are creating and for no other sockets in your app, you need to use
 * MQTTSSLSecurityPolicy.
 * And if you use self-signed server certificates, your need to set property: MQTTSSLSecurityPolicy.allowInvalidCertificates=YES
 * (see MQTTSSLSecurityPolicy.h for more detail).
 *
 * @param clientId The Client Identifier identifies the Client to the Server. If nil, a random clientId is generated.
 * @param userName an NSString object containing the user's name (or ID) for authentication. May be nil.
 * @param password an NSString object containing the user's password. If userName is nil, password must be nil as well.
 * @param keepAliveInterval The Keep Alive is a time interval measured in seconds. The MQTTClient ensures that the interval between Control Packets being sent does not exceed the Keep Alive value. In the  absence of sending any other Control Packets, the Client sends a PINGREQ Packet.
 * @param cleanSessionFlag specifies if the server should discard previous session information.
 * @param willFlag If the Will Flag is set to YES this indicates that a Will Message MUST be published by the Server when the Server detects that the Client is disconnected for any reason other than the Client flowing a DISCONNECT Packet.
 * @param willTopic If the Will Flag is set to YES, the Will Topic is a string, nil otherwise.
 * @param willMsg If the Will Flag is set to YES the Will Message must be specified, nil otherwise.
 * @param willQoS specifies the QoS level to be used when publishing the Will Message. If the Will Flag is set to NO, then the Will QoS MUST be set to 0. If the Will Flag is set to YES, the value of Will QoS can be 0 (0x00), 1 (0x01), or 2 (0x02).
 * @param willRetainFlag indicates if the server should publish the Will Messages with retainFlag. If the Will Flag is set to NO, then the Will Retain Flag MUST be set to NO . If the Will Flag is set to YES: If Will Retain is set to NO, the Server MUST publish the Will Message as a non-retained publication [MQTT-3.1.2-14]. If Will Retain is set to YES, the Server MUST publish the Will Message as a retained publication [MQTT-3.1.2-15].
 * @param protocolLevel specifies the protocol to be used. The value of the Protocol Level field for the version 3.1.1 of the protocol is 4. The value for the version 3.1 is 3.
 * @param runLoop The runLoop where the streams are scheduled. If nil, defaults to [NSRunLoop currentRunLoop].
 * @param runLoopMode The runLoopMode where the streams are scheduled. If nil, defaults to NSRunLoopCommonModes.
 * @param securityPolicy The security policy used to evaluate server trust for secure connections.
 * @param certificates An identity certificate used to reply to a server requiring client certificates according to the description given for SSLSetCertificate(). You may build the certificates array yourself or use the sundry method clientCertFromP12
 * @return the initialised MQTTSession object
 * @exception NSInternalInconsistencyException if the parameters are invalid
 *
 * @code
 #import "MQTTClient.h"
 NSString* certificate = [[NSBundle bundleForClass:[MQTTSession class]] pathForResource:@"certificate" ofType:@"cer"];
 MQTTSSLSecurityPolicy *securityPolicy = [MQTTSSLSecurityPolicy policyWithPinningMode:MQTTSSLPinningModeCertificate];
 securityPolicy.pinnedCertificates = @[ [NSData dataWithContentsOfFile:certificate] ];
 securityPolicy.allowInvalidCertificates = YES; // if your certificate is self-signed(which didn't coupled with CA infrastructure)
 MQTTSession *session = [[MQTTSession alloc]
 initWithClientId:@"example-1234"
 userName:@"user"
 password:@"secret"
 keepAlive:60
 cleanSession:YES
 will:YES
 willTopic:@"example/status"
 willMsg:[[@"Client off-line"] dataUsingEncoding:NSUTF8StringEncoding]
 willQoS:2
 willRetainFlag:YES
 protocolLevel:4
 runLoop:[NSRunLoop currentRunLoop]
 forMode:NSRunLoopCommonModes
 securityPolicy:securityPolicy
 certificates:certificates];
 [session connectToHost:@"example-1234" port:1883 usingSSL:YES];
 @endcode
 */
- (MQTTSession *)initWithClientId:(NSString *)clientId
                         userName:(NSString *)userName
                         password:(NSString *)password
                        keepAlive:(UInt16)keepAliveInterval
                     cleanSession:(BOOL)cleanSessionFlag
                             will:(BOOL)willFlag
                        willTopic:(NSString *)willTopic
                          willMsg:(NSData *)willMsg
                          willQoS:(MQTTQosLevel)willQoS
                   willRetainFlag:(BOOL)willRetainFlag
                    protocolLevel:(UInt8)protocolLevel
                          runLoop:(NSRunLoop *)runLoop
                          forMode:(NSString *)runLoopMode
                   securityPolicy:(MQTTSSLSecurityPolicy *) securityPolicy
                     certificates:(NSArray *)certificates;
/**
* for mqttio-OBJC backward compatibility
* @param theClientId see initWithClientId for description.
* @return the initialised MQTTSession object
* All other parameters are set to defaults
*/
- (id)initWithClientId:(NSString *)theClientId;
/** for mqttio-OBJC backward compatibility
 @param theClientId see initWithClientId for description.
 @param theRunLoop see initWithClientId for description.
 @param theRunLoopMode see initWithClientId for description.
 @return the initialised MQTTSession object
 All other parameters are set to defaults
 */
- (id)initWithClientId:(NSString*)theClientId
               runLoop:(NSRunLoop*)theRunLoop
               forMode:(NSString*)theRunLoopMode;
/** for mqttio-OBJC backward compatibility
 @param theClientId see initWithClientId for description.
 @param theUsername see initWithClientId for description.
 @param thePassword see initWithClientId for description.
 @return the initialised MQTTSession object
 All other parameters are set to defaults
 */
- (id)initWithClientId:(NSString*)theClientId
              userName:(NSString*)theUsername
              password:(NSString*)thePassword;
/** for mqttio-OBJC backward compatibility
 @param theClientId see initWithClientId for description.
 @param theUserName see initWithClientId for description.
 @param thePassword see initWithClientId for description.
 @param theRunLoop see initWithClientId for description.
 @param theRunLoopMode see initWithClientId for description.
 @return the initialised MQTTSession object
 All other parameters are set to defaults
 */
- (id)initWithClientId:(NSString*)theClientId
              userName:(NSString*)theUserName
              password:(NSString*)thePassword
               runLoop:(NSRunLoop*)theRunLoop
               forMode:(NSString*)theRunLoopMode;
/** for mqttio-OBJC backward compatibility
 @param theClientId see initWithClientId for description.
 @param theUsername see initWithClientId for description.
 @param thePassword see initWithClientId for description.
 @param theKeepAliveInterval see initWithClientId for description.
 @param cleanSessionFlag see initWithClientId for description.
 @return the initialised MQTTSession object
 All other parameters are set to defaults
 */
- (id)initWithClientId:(NSString*)theClientId
              userName:(NSString*)theUsername
              password:(NSString*)thePassword
             keepAlive:(UInt16)theKeepAliveInterval
          cleanSession:(BOOL)cleanSessionFlag;
/** for mqttio-OBJC backward compatibility
 @param theClientId see initWithClientId for description.
 @param theUsername see initWithClientId for description.
 @param thePassword see initWithClientId for description.
 @param theKeepAlive see initWithClientId for description.
 @param theCleanSessionFlag see initWithClientId for description.
 @param theRunLoop see initWithClientId for description.
 @param theMode see initWithClientId for description.
 @return the initialised MQTTSession object
 All other parameters are set to defaults
 */
- (id)initWithClientId:(NSString*)theClientId
              userName:(NSString*)theUsername
              password:(NSString*)thePassword
             keepAlive:(UInt16)theKeepAlive
          cleanSession:(BOOL)theCleanSessionFlag
               runLoop:(NSRunLoop*)theRunLoop
               forMode:(NSString*)theMode;
/** for mqttio-OBJC backward compatibility
 @param theClientId see initWithClientId for description.
 @param theUserName see initWithClientId for description.
 @param thePassword see initWithClientId for description.
 @param theKeepAliveInterval see initWithClientId for description.
 @param theCleanSessionFlag see initWithClientId for description.
 @param willTopic see initWithClientId for description.
 @param willMsg see initWithClientId for description.
 @param willQoS see initWithClientId for description.
 @param willRetainFlag see initWithClientId for description.
 @return the initialised MQTTSession object
 All other parameters are set to defaults
 */
- (id)initWithClientId:(NSString*)theClientId
              userName:(NSString*)theUserName
              password:(NSString*)thePassword
             keepAlive:(UInt16)theKeepAliveInterval
          cleanSession:(BOOL)theCleanSessionFlag
             willTopic:(NSString*)willTopic
               willMsg:(NSData*)willMsg
               willQoS:(UInt8)willQoS
        willRetainFlag:(BOOL)willRetainFlag;
/** for mqttio-OBJC backward compatibility
 @param theClientId see initWithClientId for description.
 @param theUserName see initWithClientId for description.
 @param thePassword see initWithClientId for description.
 @param theKeepAliveInterval see initWithClientId for description.
 @param theCleanSessionFlag see initWithClientId for description.
 @param willTopic see initWithClientId for description.
 @param willMsg see initWithClientId for description.
 @param willQoS see initWithClientId for description.
 @param willRetainFlag see initWithClientId for description.
 @param theRunLoop see initWithClientId for description.
 @param theRunLoopMode see initWithClientId for description.
 @return the initialised MQTTSession object
 All other parameters are set to defaults
 */
- (id)initWithClientId:(NSString*)theClientId
              userName:(NSString*)theUserName
              password:(NSString*)thePassword
             keepAlive:(UInt16)theKeepAliveInterval
          cleanSession:(BOOL)theCleanSessionFlag
             willTopic:(NSString*)willTopic
               willMsg:(NSData*)willMsg
               willQoS:(UInt8)willQoS
        willRetainFlag:(BOOL)willRetainFlag
               runLoop:(NSRunLoop*)theRunLoop
               forMode:(NSString*)theRunLoopMode;
/** for mqttio-OBJC backward compatibility
 @param theClientId see initWithClientId for description.
 @param theKeepAliveInterval see initWithClientId for description.
 @param theConnectMessage has to be constructed using MQTTMessage connectMessage...
 @param theRunLoop see initWithClientId for description.
 @param theRunLoopMode see initWithClientId for description.
 @return the initialised MQTTSession object
 All other parameters are set to defaults
 */
- (id)initWithClientId:(NSString*)theClientId
             keepAlive:(UInt16)theKeepAliveInterval
        connectMessage:(MQTTMessage*)theConnectMessage
               runLoop:(NSRunLoop*)theRunLoop
               forMode:(NSString*)theRunLoopMode;
/** connects to the specified MQTT server
 @param host specifies the hostname or ip address to connect to. Defaults to @"localhost".
 @param port specifies the port to connect to
 @param usingSSL specifies whether to use SSL or not
 @param connectHandler identifies a block which is executed on successfull or unsuccessfull connect. Might be nil
 error is nil in the case of a successful connect
 sessionPresent indicates in MQTT 3.1.1 if persistent session data was present at the server
 @return nothing and returns immediately. To check the connect results, register as an MQTTSessionDelegate and
 - watch for events
 - watch for connect or connectionRefused messages
 - watch for error messages
 or use the connectHandler block
 @code
 #import "MQTTClient.h"
 MQTTSession *session = [[MQTTSession alloc] init];
 [session connectToHost:@"192.168.0.1" port:1883 usingSSL:NO connectHandler:^(NSError *error, BOOL sessionPresent) {
 if (error) {
 NSLog(@"Error Connect %@", error.localizedDescription);
 } else {
 NSLog(@"Connected sessionPresent:%d", sessionPresent);
 }
 }];
 @endcode
 @deprecated as not all connection parameters are supported, use connect
 */
- (void)connectToHost:(NSString *)host
                 port:(UInt32)port
             usingSSL:(BOOL)usingSSL
       connectHandler:(MQTTConnectHandler)connectHandler;
/** connects to the specified MQTT server
 @param host see connectToHost for description
 @param port see connectToHost for description
 @param usingSSL see connectToHost for description
 @return see connectToHost for description
 @deprecated as not all connection parameters are supported, use connect
 */
- (void)connectToHost:(NSString *)host port:(UInt32)port usingSSL:(BOOL)usingSSL;
/** for mqttio-OBJC backward compatibility
 @param ip see connectToHost for description
 @param port see connectToHost for description
 @deprecated as not all connection parameters are supported, use connect
 */
- (void)connectToHost:(NSString*)ip port:(UInt32)port;
/** for mqttio-OBJC backward compatibility
 @param ip see connectToHost for description
 @param port see connectToHost for description
 @param connHandler event handler block
 @param messHandler message handler block
 @deprecated as not all connection parameters are supported, use connect
 */
- (void)connectToHost:(NSString*)ip
                 port:(UInt32)port
withConnectionHandler:(void (^)(MQTTSessionEvent event))connHandler
       messageHandler:(void (^)(NSData* data, NSString* topic))messHandler;
/** for mqttio-OBJC backward compatibility
 @param ip see connectToHost for description
 @param port see connectToHost for description
 @param usingSSL indicator to use TLS
 @param connHandler event handler block
 @param messHandler message handler block
 */
- (void)connectToHost:(NSString*)ip
                 port:(UInt32)port
             usingSSL:(BOOL)usingSSL
withConnectionHandler:(void (^)(MQTTSessionEvent event))connHandler
       messageHandler:(void (^)(NSData* data, NSString* topic))messHandler;
/** for mqttio-OBJC backward compatibility
 @param theTopic see subscribeToTopic for description
 */
- (void)subscribeTopic:(NSString*)theTopic;
/** for mqttio-OBJC backward compatibility
 @param theData see publishData for description
 @param theTopic see publishData for description
  */
- (void)publishData:(NSData*)theData onTopic:(NSString*)theTopic;
/** for mqttio-OBJC backward compatibility
 @param theData see publishData for description
 @param theTopic see publishData for description
 */
- (void)publishDataAtLeastOnce:(NSData*)theData onTopic:(NSString*)theTopic;
/** for mqttio-OBJC backward compatibility
 @param theData see publishData for description
 @param theTopic see publishData for description
 @param retainFlag see publishData for description
 */
- (void)publishDataAtLeastOnce:(NSData*)theData onTopic:(NSString*)theTopic retain:(BOOL)retainFlag;
/** for mqttio-OBJC backward compatibility
 @param theData see publishData for description
 @param theTopic see publishData for description
 */
- (void)publishDataAtMostOnce:(NSData*)theData onTopic:(NSString*)theTopic;
/** for mqttio-OBJC backward compatibility
 @param theData see publishData for description
 @param theTopic see publishData for description
 @param retainFlag see publishData for description
 */
- (void)publishDataAtMostOnce:(NSData*)theData onTopic:(NSString*)theTopic retain:(BOOL)retainFlag;
/** for mqttio-OBJC backward compatibility
 @param theData see publishData for description
 @param theTopic see publishData for description
 */
- (void)publishDataExactlyOnce:(NSData*)theData onTopic:(NSString*)theTopic;
/** for mqttio-OBJC backward compatibility
 @param theData see publishData for description
 @param theTopic see publishData for description
 @param retainFlag see publishData for description
 */
- (void)publishDataExactlyOnce:(NSData*)theData onTopic:(NSString*)theTopic retain:(BOOL)retainFlag;
/** for mqttio-OBJC backward compatibility
 @param payload JSON payload is converted to NSData and then send. See publishData for description
 @param theTopic see publishData for description
 */
- (void)publishJson:(id)payload onTopic:(NSString*)theTopic;
@end
frameworks/MQTTFramework.framework/Headers/MQTTSessionManager.h
New file
@@ -0,0 +1,275 @@
//
//  MQTTSessionManager.h
//  MQTTClient
//
//  Created by Christoph Krey on 09.07.14.
//  Copyright © 2013-2016 Christoph Krey. All rights reserved.
//
#import <Foundation/Foundation.h>
#if TARGET_OS_IPHONE == 1
#import <UIKit/UIKit.h>
#endif
#import "MQTTSession.h"
#import "MQTTSessionLegacy.h"
#import "MQTTSSLSecurityPolicy.h"
/** delegate gives your application access to received messages
 */
@protocol MQTTSessionManagerDelegate <NSObject>
/**
 Enumeration of MQTTSessionManagerState values
 */
typedef NS_ENUM(int, MQTTSessionManagerState) {
    MQTTSessionManagerStateStarting,
    MQTTSessionManagerStateConnecting,
    MQTTSessionManagerStateError,
    MQTTSessionManagerStateConnected,
    MQTTSessionManagerStateClosing,
    MQTTSessionManagerStateClosed
};
/** gets called when a new message was received
 @param data the data received, might be zero length
 @param topic the topic the data was published to
 @param retained indicates if the data retransmitted from server storage
 */
- (void)handleMessage:(NSData *)data onTopic:(NSString *)topic retained:(BOOL)retained;
@optional
/** gets called when a published message was actually delivered
 @param msgID the Message Identifier of the delivered message
 @note this method is called after a publish with qos 1 or 2 only
 */
- (void)messageDelivered:(UInt16)msgID;
@end
/** SessionManager handles the MQTT session for your application
 */
@interface MQTTSessionManager : NSObject <MQTTSessionDelegate>
/** the delegate receiving incoming messages
 */
@property (weak, nonatomic) id<MQTTSessionManagerDelegate> delegate;
/** subscriptions is a dictionary of NSNumber instances indicating the MQTTQoSLevel.
 *  The keys are topic filters.
 *  The SessionManager subscribes to the given subscriptions after successfull (re-)connect
 *  according to the cleansession parameter and the state of the session as indicated by the broker.
 *  Setting a new subscriptions dictionary initiates SUBSCRIBE or UNSUBSCRIBE messages by SessionManager
 *  by comparing the old and new subscriptions.
 */
@property (strong, nonatomic) NSDictionary<NSString *, NSNumber *> *subscriptions;
/** effectiveSubscriptions s a dictionary of NSNumber instances indicating the granted MQTTQoSLevel, or 0x80 for subscription failure.
 *  The keys are topic filters.
 *  effectiveSubscriptions is observable and is updated everytime subscriptions change
 *  @code
        ...
        MQTTSessionManager *manager = [[MQTTSessionManager alloc] init];
        manager.delegate = self;
        [manager addObserver:self
            forKeyPath:@"effectiveSubscriptions"
            options:NSKeyValueObservingOptionInitial | NSKeyValueObservingOptionNew
            context:nil];
            manager.subscriptions = [@{@"#": @(0)} mutableCopy];
            [manager connectTo: ...
        ...
        [manager removeObserver:self forKeyPath:@"effectiveSubscriptions"];
        ...
    - (void)observeValueForKeyPath:(NSString *)keyPath
        ofObject:(id)object
        change:(NSDictionary<NSString *,id> *)change
        context:(void *)context {
        if ([keyPath isEqualToString:@"effectiveSubscriptions"]) {
            MQTTSessionManager *manager = (MQTTSessionManager *)object;
            DDLogVerbose(@"effectiveSubscriptions changed: %@", manager.effectiveSubscriptions);
        }
    }
 *  @endcode
 */
@property (readonly, strong, nonatomic) NSDictionary<NSString *, NSNumber *> *effectiveSubscriptions;
/** SessionManager status
 */
@property (nonatomic, readonly) MQTTSessionManagerState state;
/** SessionManager last error code when state equals MQTTSessionManagerStateError
 */
@property (nonatomic, readonly) NSError *lastErrorCode;
/** initWithPersistence sets the MQTTPersistence properties other than default
 * @param persistent YES or NO (default) to establish file or in memory persistence.
 * @param maxWindowSize (a positive number, default is 16) to control the number of messages sent before waiting for acknowledgement in Qos 1 or 2. Additional messages are stored and transmitted later.
 * @param maxSize (a positive number of bytes, default is 64 MB) to limit the size of the persistence file. Messages published after the limit is reached are dropped.
 * @param maxMessages (a positive number, default is 1024) to limit the number of messages stored. Additional messages published are dropped.
 * @return the initialized MQTTSessionManager object
 */
- (MQTTSessionManager *)initWithPersistence:(BOOL)persistent
                              maxWindowSize:(NSUInteger)maxWindowSize
                                maxMessages:(NSUInteger)maxMessages
                                    maxSize:(NSUInteger)maxSize;
/** Connects to the MQTT broker and stores the parameters for subsequent reconnects
 * @param host specifies the hostname or ip address to connect to. Defaults to @"localhost".
 * @param port specifies the port to connect to
 * @param tls specifies whether to use SSL or not
 * @param keepalive The Keep Alive is a time interval measured in seconds. The MQTTClient ensures that the interval between Control Packets being sent does not exceed the Keep Alive value. In the  absence of sending any other Control Packets, the Client sends a PINGREQ Packet.
 * @param clean specifies if the server should discard previous session information.
 * @param auth specifies the user and pass parameters should be used for authenthication
 * @param user an NSString object containing the user's name (or ID) for authentication. May be nil.
 * @param pass an NSString object containing the user's password. If userName is nil, password must be nil as well.
 * @param will indicates whether a will shall be sent
 * @param willTopic the Will Topic is a string, may be nil
 * @param willMsg the Will Message, might be zero length or nil
 * @param willQos specifies the QoS level to be used when publishing the Will Message.
 * @param willRetainFlag indicates if the server should publish the Will Messages with retainFlag.
 * @param clientId The Client Identifier identifies the Client to the Server. If nil, a random clientId is generated.
 * @param securityPolicy A custom SSL security policy or nil.
 * @param certificates An NSArray of the pinned certificates to use or nil.
 * @param protocolLevel Protocol version of the connection.
 */
- (void)connectTo:(NSString *)host
             port:(NSInteger)port
              tls:(BOOL)tls
        keepalive:(NSInteger)keepalive
            clean:(BOOL)clean
             auth:(BOOL)auth
             user:(NSString *)user
             pass:(NSString *)pass
             will:(BOOL)will
        willTopic:(NSString *)willTopic
          willMsg:(NSData *)willMsg
          willQos:(MQTTQosLevel)willQos
   willRetainFlag:(BOOL)willRetainFlag
     withClientId:(NSString *)clientId
   securityPolicy:(MQTTSSLSecurityPolicy *)securityPolicy
     certificates:(NSArray *)certificates
    protocolLevel:(MQTTProtocolVersion)protocolLevel;
/** Connects to the MQTT broker and stores the parameters for subsequent reconnects
 * @param host specifies the hostname or ip address to connect to. Defaults to @"localhost".
 * @param port specifies the port to connect to
 * @param tls specifies whether to use SSL or not
 * @param keepalive The Keep Alive is a time interval measured in seconds. The MQTTClient ensures that the interval between Control Packets being sent does not exceed the Keep Alive value. In the  absence of sending any other Control Packets, the Client sends a PINGREQ Packet.
 * @param clean specifies if the server should discard previous session information.
 * @param auth specifies the user and pass parameters should be used for authenthication
 * @param user an NSString object containing the user's name (or ID) for authentication. May be nil.
 * @param pass an NSString object containing the user's password. If userName is nil, password must be nil as well.
 * @param will indicates whether a will shall be sent
 * @param willTopic the Will Topic is a string, may be nil
 * @param willMsg the Will Message, might be zero length or nil
 * @param willQos specifies the QoS level to be used when publishing the Will Message.
 * @param willRetainFlag indicates if the server should publish the Will Messages with retainFlag.
 * @param clientId The Client Identifier identifies the Client to the Server. If nil, a random clientId is generated.
 * @param securityPolicy A custom SSL security policy or nil.
 * @param certificates An NSArray of the pinned certificates to use or nil.
 */
- (void)connectTo:(NSString *)host
             port:(NSInteger)port
              tls:(BOOL)tls
        keepalive:(NSInteger)keepalive
            clean:(BOOL)clean
             auth:(BOOL)auth
             user:(NSString *)user
             pass:(NSString *)pass
             will:(BOOL)will
        willTopic:(NSString *)willTopic
          willMsg:(NSData *)willMsg
          willQos:(MQTTQosLevel)willQos
   willRetainFlag:(BOOL)willRetainFlag
     withClientId:(NSString *)clientId
   securityPolicy:(MQTTSSLSecurityPolicy *)securityPolicy
     certificates:(NSArray *)certificates;
/** Convenience alternative to full paramter connectTo
 * @param host see connectTo description
 * @param port see connectTo description
 * @param tls see connectTo description
 * @param keepalive see connectTo description
 * @param clean see connectTo description
 * @param auth see connectTo description
 * @param user see connectTo description
 * @param pass see connectTo description
 * @param will see connectTo description
 * @param willTopic see connectTo description
 * @param willMsg see connectTo description
 * @param willQos see connectTo description
 * @param willRetainFlag see connectTo description
 * @param clientId see connectTo description
 */
- (void)connectTo:(NSString *)host
             port:(NSInteger)port
              tls:(BOOL)tls
        keepalive:(NSInteger)keepalive
            clean:(BOOL)clean
             auth:(BOOL)auth
             user:(NSString *)user
             pass:(NSString *)pass
             will:(BOOL)will
        willTopic:(NSString *)willTopic
          willMsg:(NSData *)willMsg
          willQos:(MQTTQosLevel)willQos
   willRetainFlag:(BOOL)willRetainFlag
     withClientId:(NSString *)clientId;
/** Convenience alternative to full paramter connectTo
 * @param host see connectTo description
 * @param port see connectTo description
 * @param tls see connectTo description
 * @param keepalive see connectTo description
 * @param clean see connectTo description
 * @param auth see connectTo description
 * @param user see connectTo description
 * @param pass see connectTo description
 * @param willTopic the Will Topic is a string, must not be nil
 * @param will the Will Message, might be zero length
 * @param willQos see connectTo description
 * @param willRetainFlag see connectTo description
 * @param clientId see connectTo description
 */
- (void)connectTo:(NSString *)host
                  port:(NSInteger)port
                   tls:(BOOL)tls
             keepalive:(NSInteger)keepalive
                 clean:(BOOL)clean
                  auth:(BOOL)auth
                  user:(NSString *)user
                  pass:(NSString *)pass
             willTopic:(NSString *)willTopic
                  will:(NSData *)will
               willQos:(MQTTQosLevel)willQos
        willRetainFlag:(BOOL)willRetainFlag
          withClientId:(NSString *)clientId;
/** Re-Connects to the MQTT broker using the parameters for given in the connectTo method
 */
- (void)connectToLast;
/** publishes data on a given topic at a specified QoS level and retain flag
 @param data the data to be sent. length may range from 0 to 268,435,455 - 4 - _lengthof-topic_ bytes. Defaults to length 0.
 @param topic the Topic to identify the data
 @param retainFlag if YES, data is stored on the MQTT broker until overwritten by the next publish with retainFlag = YES
 @param qos specifies the Quality of Service for the publish
 qos can be 0, 1, or 2.
 @return the Message Identifier of the PUBLISH message. Zero if qos 0. If qos 1 or 2, zero if message was dropped
 @note returns immediately.
 */
- (UInt16)sendData:(NSData *)data topic:(NSString *)topic qos:(MQTTQosLevel)qos retain:(BOOL)retainFlag;
/** Disconnects gracefully from the MQTT broker
 */
- (void)disconnect;
@end
frameworks/MQTTFramework.framework/Headers/MQTTSessionSynchron.h
New file
@@ -0,0 +1,389 @@
//
// MQTTSessionSynchron.h
// MQTTClient.framework
//
/**
 Synchronous API
 @author Christoph Krey krey.christoph@gmail.com
 @copyright Copyright © 2013-2016, Christoph Krey
 */
#import <Foundation/Foundation.h>
#import "MQTTSession.h"
@interface MQTTSession(Synchron)
/** connects to the specified MQTT server synchronously
 @param timeout defines the maximum time to wait. Defaults to 0 for no timeout.
 @return true if the connection was established
 @code
 #import "MQTTClient.h"
 MQTTSession *session = [[MQTTSession alloc] init];
 [session connectAndWaitTimeout:30];
 @endcode
 */
- (BOOL)connectAndWaitTimeout:(NSTimeInterval)timeout;
/** connects to the specified MQTT server synchronously
 @param host see connectAndWaitToHost:port:usingSSL:timeout: for details
 @param port see connectAndWaitToHost:port:usingSSL:timeout: for details
 @param usingSSL see connectAndWaitToHost:port:usingSSL:timeout: for details
 @return true if the connection was established
 @code
 #import "MQTTClient.h"
 MQTTSession *session = [[MQTTSession alloc] init];
 [session connectAndWaitToHost:@"192.168.0.1" port:1883 usingSSL:NO];
 @endcode
 @deprecated as not all connection parameters are supported, use connectAndWaitTimeout
 */
- (BOOL)connectAndWaitToHost:(NSString *)host
                        port:(UInt32)port
                    usingSSL:(BOOL)usingSSL;
/** connects to the specified MQTT server synchronously
 @param host specifies the hostname or ip address to connect to. Defaults to @"localhost".
 @param port spefifies the port to connect to
 @param usingSSL specifies whether to use SSL or not
 @param timeout defines the maximum time to wait
 @return true if the connection was established
 @code
 #import "MQTTClient.h"
 MQTTSession *session = [[MQTTSession alloc] init];
 [session connectAndWaitToHost:@"192.168.0.1" port:1883 usingSSL:NO];
 @endcode
 @deprecated as not all connection parameters are supported, use connectAndWaitTimeout
 */
- (BOOL)connectAndWaitToHost:(NSString *)host
                        port:(UInt32)port
                    usingSSL:(BOOL)usingSSL
                     timeout:(NSTimeInterval)timeout;
/** subscribes to a topic at a specific QoS level synchronously
 @param topic the Topic Filter to subscribe to.
 @param qosLevel specifies the QoS Level of the subscription.
 qosLevel can be 0, 1, or 2.
 @return TRUE if successfully subscribed
 @code
 #import "MQTTClient.h"
 MQTTSession *session = [[MQTTSession alloc] init];
 [session connectAndWaitTimeout:30];
 [session subscribeAndWaitToTopic:@"example/#" atLevel:2];
 @endcode
 */
- (BOOL)subscribeAndWaitToTopic:(NSString *)topic
                        atLevel:(MQTTQosLevel)qosLevel;
/** subscribes to a topic at a specific QoS level synchronously
 @param topic the Topic Filter to subscribe to.
 @param qosLevel specifies the QoS Level of the subscription.
 qosLevel can be 0, 1, or 2.
 @param timeout defines the maximum time to wait
 @return TRUE if successfully subscribed
 @code
 #import "MQTTClient.h"
 MQTTSession *session = [[MQTTSession alloc] init];
 [session connectAndWaitTimeout:30];
 [session subscribeAndWaitToTopic:@"example/#" atLevel:2 timeout:10];
 @endcode
 */
- (BOOL)subscribeAndWaitToTopic:(NSString *)topic
                        atLevel:(MQTTQosLevel)qosLevel
                        timeout:(NSTimeInterval)timeout;
/** subscribes a number of topics
 @param topics an NSDictionary<NSString *, NSNumber *> containing the Topic Filters to subscribe to as keys and
    the corresponding QoS as NSNumber values
 @return the Message Identifier of the SUBSCRIBE message.
 @note returns immediately. To check results, register as an MQTTSessionDelegate and watch for events.
 @code
 #import "MQTTClient.h"
 MQTTSession *session = [[MQTTSession alloc] init];
 [session connectAndWaitTimeout:30];
 [session subscribeAndWaitToTopics:@{
 @"example/#": @(0),
 @"example/status": @(2),
 @"other/#": @(1)
 }];
 @endcode
 */
- (BOOL)subscribeAndWaitToTopics:(NSDictionary<NSString *, NSNumber *> *)topics;
/** subscribes a number of topics
 @param topics an NSDictionary<NSString *, NSNumber *> containing the Topic Filters to subscribe to as keys and
 the corresponding QoS as NSNumber values
 @param timeout defines the maximum time to wait
 @return TRUE if the subscribe was succesfull
 @code
 #import "MQTTClient.h"
 MQTTSession *session = [[MQTTSession alloc] init];
 [session connectAndWaitTimeout:30];
 [session subscribeAndWaitToTopics:@{
 @"example/#": @(0),
 @"example/status": @(2),
 @"other/#": @(1)
 }
 timeout:10];
 @endcode
 */
- (BOOL)subscribeAndWaitToTopics:(NSDictionary<NSString *, NSNumber *> *)topics
                         timeout:(NSTimeInterval)timeout;
/** unsubscribes from a topic synchronously
 @param topic the Topic Filter to unsubscribe from.
 @return TRUE if sucessfully unsubscribed
 @code
 #import "MQTTClient.h"
 MQTTSession *session = [[MQTTSession alloc] init];
 [session connectAndWaitTimeout:30];
 ...
 [session unsubscribeAndWaitTopic:@"example/#"];
 @endcode
 */
- (BOOL)unsubscribeAndWaitTopic:(NSString *)topic;
/** unsubscribes from a topic synchronously
 @param topic the Topic Filter to unsubscribe from.
 @param timeout defines the maximum time to wait
 @return TRUE if sucessfully unsubscribed
 @code
 #import "MQTTClient.h"
 MQTTSession *session = [[MQTTSession alloc] init];
 [session connectAndWaitTimeout:30];
 ...
 [session unsubscribeAndWaitTopic:@"example/#" timeout:10];
 @endcode
 */
- (BOOL)unsubscribeAndWaitTopic:(NSString *)topic
                        timeout:(NSTimeInterval)timeout;
/** unsubscribes from a number of topics synchronously
 @param topics an NSArray<NSString *> of topics to unsubscribe from
 @return TRUE if the unsubscribe was successful
 @code
 #import "MQTTClient.h"
 MQTTSession *session = [[MQTTSession alloc] init];
 [session connectAndWaitTimeout:30];
 ...
 [session unsubscribeAndWaitTopics:@[
 @"example/#",
 @"example/status",
 @"other/#"
 ]];
 @endcode
 */
- (BOOL)unsubscribeAndWaitTopics:(NSArray<NSString *> *)topics;
/** unsubscribes from a number of topics synchronously
 @param topics an NSArray<NSString *> of topics to unsubscribe from
 @param timeout defines the maximum time to wait
 @return TRUE if the unsubscribe was successful
 @code
 #import "MQTTClient.h"
 MQTTSession *session = [[MQTTSession alloc] init];
 [session connectAndWaitTimeout:30];
 ...
 [session unsubscribeAndWaitTopics:@[
 @"example/#",
 @"example/status",
 @"other/#"
 ]
 timeout:10];
 @endcode
 */
- (BOOL)unsubscribeAndWaitTopics:(NSArray<NSString *> *)topics
                         timeout:(NSTimeInterval)timeout;
/** publishes synchronously data
 @param data see publishAndWaitData:onTopic:retain:qos:timeout: for details
 @param topic see publishAndWaitData:onTopic:retain:qos:timeout: for details
 @param retainFlag see publishAndWaitData:onTopic:retain:qos:timeout: for details
 @param qos see publishAndWaitData:onTopic:retain:qos:timeout: for details
 @returns TRUE if the publish was successful
 @code
 #import "MQTTClient.h"
 MQTTSession *session = [[MQTTSession alloc] init];
 [session connectAndWaitTimeout:30];
 [session publishAndWaitData:[@"Sample Data" dataUsingEncoding:NSUTF8StringEncoding]
 topic:@"example/data"
 retain:YES
 qos:1];
 @endcode
 */
- (BOOL)publishAndWaitData:(NSData *)data
                   onTopic:(NSString *)topic
                    retain:(BOOL)retainFlag
                       qos:(MQTTQosLevel)qos;
/** publishes synchronously data on a given topic at a specified QoS level and retain flag
 @param data the data to be sent. length may range from 0 to 268,435,455 - 4 - _lengthof-topic_ bytes. Defaults to length 0.
 @param topic the Topic to identify the data
 @param retainFlag if YES, data is stored on the MQTT broker until overwritten by the next publish with retainFlag = YES
 @param qos specifies the Quality of Service for the publish
 qos can be 0, 1, or 2.
 @param timeout defines the maximum time to wait
 @returns TRUE if the publish was successful
 @code
 #import "MQTTClient.h"
 MQTTSession *session = [[MQTTSession alloc] init];
 [session connectAndWaitTimeout:30];
 [session publishAndWaitData:[@"Sample Data" dataUsingEncoding:NSUTF8StringEncoding]
 topic:@"example/data"
 retain:YES
 qos:1
 timeout:10];
 @endcode
 */
- (BOOL)publishAndWaitData:(NSData *)data
                   onTopic:(NSString *)topic
                    retain:(BOOL)retainFlag
                       qos:(MQTTQosLevel)qos
                   timeout:(NSTimeInterval)timeout;
/** closes an MQTTSession gracefully synchronously
 If the connection was successfully established before, a DISCONNECT is sent.
 @code
 #import "MQTTClient.h"
 MQTTSession *session = [[MQTTSession alloc] init];
 [session connectAndWaitTimeout:30];
 ...
 [session closeAndWait];
 @endcode
 */
- (void)closeAndWait;
/** closes an MQTTSession gracefully synchronously
 @param timeout defines the maximum time to wait
 If the connection was successfully established before, a DISCONNECT is sent.
 @code
 #import "MQTTClient.h"
 MQTTSession *session = [[MQTTSession alloc] init];
 [session connectAndWaitTimeout:30];
 ...
 [session closeAndWait:10];
 @endcode
 */
- (void)closeAndWait:(NSTimeInterval)timeout;
@end
frameworks/MQTTFramework.framework/Headers/MQTTTransport.h
New file
@@ -0,0 +1,102 @@
//
//  MQTTTransport.h
//  MQTTClient
//
//  Created by Christoph Krey on 06.12.15.
//  Copyright © 2015-2016 Christoph Krey. All rights reserved.
//
#import <Foundation/Foundation.h>
@protocol MQTTTransportDelegate;
/** MQTTTransport is a protocol abstracting the underlying transport level for MQTTClient
 *
 */
@protocol MQTTTransport <NSObject>
/** MQTTTransport state defines the possible state of an abstract transport
 *
 */
 typedef NS_ENUM(NSInteger, MQTTTransportState) {
     /** MQTTTransportCreated indicates an initialized transport */
     MQTTTransportCreated = 0,
     /** MQTTTransportOpening indicates a transport in the process of opening a connection */
     MQTTTransportOpening,
     /** MQTTTransportCreated indicates a transport opened ready for communication */
     MQTTTransportOpen,
     /** MQTTTransportCreated indicates a transport in the process of closing */
     MQTTTransportClosing,
     /** MQTTTransportCreated indicates a closed transport */
     MQTTTransportClosed
 };
/** runLoop The runLoop where the streams are scheduled. If nil, defaults to [NSRunLoop currentRunLoop]. */
@property (strong, nonatomic) NSRunLoop * _Nonnull runLoop;
/** runLoopMode The runLoopMode where the streams are scheduled. If nil, defaults to NSRunLoopCommonModes. */
@property (strong, nonatomic) NSString * _Nonnull runLoopMode;
/** MQTTTransportDelegate needs to be set to a class implementing th MQTTTransportDelegate protocol
 * to receive delegate messages.
 */
@property (strong, nonatomic) _Nullable id<MQTTTransportDelegate> delegate;
/** state contains the current MQTTTransportState of the transport */
@property (nonatomic) MQTTTransportState state;
/** open opens the transport and prepares it for communication
 * actual transports may require additional parameters to be set before opening
 */
- (void)open;
/** send transmits a data message
 * @param data data to be send, might be zero length
 * @result a boolean indicating if the data could be send or not
 */
- (BOOL)send:(nonnull NSData *)data;
/** close closes the transport */
- (void)close;
@end
/** MQTTTransportDelegate protocol
 * Note: the implementation of the didReceiveMessage method is mandatory, the others are optional
 */
@protocol MQTTTransportDelegate <NSObject>
/** didReceiveMessage gets called when a message was received
 * @param mqttTransport the transport on which the message was received
 * @param message the data received which may be zero length
 */
 - (void)mqttTransport:(nonnull id<MQTTTransport>)mqttTransport didReceiveMessage:(nonnull NSData *)message;
@optional
/** mqttTransportDidOpen gets called when a transport is successfully opened
 * @param mqttTransport the transport which was successfully opened
 */
- (void)mqttTransportDidOpen:(_Nonnull id<MQTTTransport>)mqttTransport;
/** didFailWithError gets called when an error was detected on the transport
 * @param mqttTransport the transport which detected the error
 * @param error available error information, might be nil
 */
- (void)mqttTransport:(_Nonnull id<MQTTTransport>)mqttTransport didFailWithError:(nullable NSError *)error;
/** mqttTransportDidClose gets called when the transport closed
 * @param mqttTransport the transport which was closed
 */
- (void)mqttTransportDidClose:(_Nonnull id<MQTTTransport>)mqttTransport;
@end
@interface MQTTTransport : NSObject <MQTTTransport>
@end
frameworks/MQTTFramework.framework/Headers/MQTTWebsocketTransport.h
New file
@@ -0,0 +1,49 @@
//
//  MQTTWebsocketTransport.h
//  MQTTClient
//
//  Created by Christoph Krey on 06.12.15.
//  Copyright © 2015-2016 Christoph Krey. All rights reserved.
//
#import <Foundation/Foundation.h>
#import "MQTTTransport.h"
#import <SocketRocket/SRWebSocket.h>
/** MQTTCFSocketTransport
 * implements an MQTTTransport on top of Websockets (SocketRocket)
 */
@interface MQTTWebsocketTransport : MQTTTransport <MQTTTransport, SRWebSocketDelegate>
/** host an NSString containing the hostName or IP address of the host to connect to
 * defaults to @"localhost"
*/
@property (strong, nonatomic) NSString *host;
/** port an unsigned 16 bit integer containing the IP port number to connect to
 * defaults to 80
 */
@property (nonatomic) UInt16 port;
/** tls a boolean indicating whether the transport should be using security
 * defaults to NO
 */
@property (nonatomic) BOOL tls;
/** path an NSString indicating the path component of the websocket URL request
 * defaults to @"/html"
 */
@property (strong, nonatomic) NSString *path;
/** allowUntrustedCertificates a boolean indicating whether self signed or expired certificates should be accepted
 * defaults to NO
 */
@property (nonatomic) BOOL allowUntrustedCertificates;
/** pinnedCertificates an NSArray containing certificates to validate server certificates against
 * defaults to nil
 */
@property (strong, nonatomic) NSArray *pinnedCertificates;
@end
frameworks/MQTTFramework.framework/Info.plist
Binary files differ
frameworks/MQTTFramework.framework/MQTTFramework
Binary files differ
frameworks/MQTTFramework.framework/Modules/module.modulemap
New file
@@ -0,0 +1,6 @@
framework module MQTTFramework {
  umbrella header "MQTTFramework.h"
  export *
  module * { export * }
}
frameworks/WAAIhelpImpl.framework/Headers/WAAIhelpImpl.h
New file
@@ -0,0 +1,19 @@
//
//  WAAIhelpImpl.h
//  WAAIhelpImpl
//
//  Created by hank on 2018/5/17.
//  Copyright © 2018年 hank. All rights reserved.
//
#import <UIKit/UIKit.h>
//! Project version number for WAAIhelpImpl.
FOUNDATION_EXPORT double WAAIhelpImplVersionNumber;
//! Project version string for WAAIhelpImpl.
FOUNDATION_EXPORT const unsigned char WAAIhelpImplVersionString[];
// In this header, you should import all the public headers of your framework using statements like #import <WAAIhelpImpl/PublicHeader.h>
//time:2020/01/08 12:30 ver:1.4.0
frameworks/WAAIhelpImpl.framework/Info.plist
Binary files differ
frameworks/WAAIhelpImpl.framework/Modules/module.modulemap
New file
@@ -0,0 +1,6 @@
framework module WAAIhelpImpl {
  umbrella header "WAAIhelpImpl.h"
  export *
  module * { export * }
}
frameworks/WAAIhelpImpl.framework/WAAIhelpImpl
Binary files differ
res/ElvaChatServiceSDK.bundle/ab_op_list_ltem_bg.9.png
res/ElvaChatServiceSDK.bundle/ab_reward.png
res/ElvaChatServiceSDK.bundle/ar.lproj/Localizable.strings
New file
@@ -0,0 +1,22 @@
//阿拉伯语ar
"content_too_long"="لا تستخدم أكثر من %ld رمزا";
"ContactCustomerService" = "اِتصل بنا";
"self_service_interface" = "خدمة ذاتية";
"offLine"= "لقد انفصلت الشبكة. يرجى المحاولة مجددا لاحقا";
"CustomerService"="HELP";
"elva__mark_helpful_toast"="تم تأكيد السؤال مُفيدا";
"elva__mark_unhelpful_toast"="تم تعيين السؤال غير مفيد";
"elva__mark_yes_no_question"="هل كان هذا مفيدا؟";
"elva__mark_no"="لا";
"elva__mark_yes"="نعم";
"RewardBalance"="رموزك";
"GoTo" = "اتجه الى";
"Forum" = "منتدى الأسئلة و الإجابات";
"RewardSuccess" = "نجاج";
"RewardFailure" = "فشل";
"TokenInsufficient" = "الرموز الخاصة بك غير كافية";
"NeedMoreHelp" = "هل تريد المزيد من المساعدة؟";
"your question"="كتابة رسالة نصية";
"Cancel"="إلغاء";
"Success"="Success";
"Failed"="Failed";
res/ElvaChatServiceSDK.bundle/b27_icon_star_gray@2x.png
res/ElvaChatServiceSDK.bundle/b27_icon_star_yellow@2x.png
res/ElvaChatServiceSDK.bundle/back_2.png
res/ElvaChatServiceSDK.bundle/btn_close.png
res/ElvaChatServiceSDK.bundle/btn_search.png
res/ElvaChatServiceSDK.bundle/cai_has_clicked_ios.png
res/ElvaChatServiceSDK.bundle/chat5.png
res/ElvaChatServiceSDK.bundle/chat_send_message.png
res/ElvaChatServiceSDK.bundle/darkMode/ab_op_list_ltem_bg.9.png
res/ElvaChatServiceSDK.bundle/darkMode/back_2.png
res/ElvaChatServiceSDK.bundle/darkMode/btn_close.png
res/ElvaChatServiceSDK.bundle/darkMode/chat_send_message.png
res/ElvaChatServiceSDK.bundle/darkMode/message_receiver_background_normal.png
res/ElvaChatServiceSDK.bundle/darkMode/message_receiver_background_normal@2x.png
res/ElvaChatServiceSDK.bundle/darkMode/message_receiver_background_normal@3x.png
res/ElvaChatServiceSDK.bundle/darkMode/show_faq_list.png
res/ElvaChatServiceSDK.bundle/darkMode/uploadPic.png
res/ElvaChatServiceSDK.bundle/de.lproj/Localizable.strings
New file
@@ -0,0 +1,24 @@
//德语de,de-AT,de-CH,de-DE,de-LI,de-LU
"content_too_long"="Nicht mehr al%ld Zeichen!";
"ContactCustomerService" = "Kontaktieren uns";
"self_service_interface" = "Selbst-Service";
"offLine"= "Ihr Netzwerk ist getrennt, bitte versuchen Sie es später noch einmal";
"CustomerService"="HELP";
"elva__mark_helpful_toast"="Sie fanden es hilfreich.";
"elva__mark_unhelpful_toast"="Sie finden es nicht hilfreich.";
"elva__mark_yes_no_question"="Hilft das?";
"elva__mark_no"="Nein";
"elva__mark_yes"="Ja";
"RewardBalance"="Ihre Tokens:";
"GoTo" = "Gehen in die";
"Forum" = "Gemeinschaft der Fragen und Antworten";
"RewardSuccess" = "Erfolg";
"RewardFailure" = "Fehlgeschlagen";
"TokenInsufficient" = "Tokens reichen nicht aus";
"NeedMoreHelp" = "Benötigen weitere Hilfe?";
"your question"="Ihre Frage";
"Cancel"="stornieren";
"Oops, no relevant results were found"="Tut mir Leid, Keine Ergebnisse gefunden.";
"Success"="Success";
"Failed"="Failed";
res/ElvaChatServiceSDK.bundle/default_guide_elva.png
res/ElvaChatServiceSDK.bundle/default_guide_elva_robot.png
res/ElvaChatServiceSDK.bundle/default_player_elva.png
res/ElvaChatServiceSDK.bundle/ding_has_clicked_ios.png
res/ElvaChatServiceSDK.bundle/el-GR.lproj/Localizable.strings
New file
@@ -0,0 +1,33 @@
//希腊语el-GR,el-CY
"content_too_long"="Δεν μπορείτε να ξεπεράσετε τους %ld χαρακτήρες!";
"ContactCustomerService" = "Επικοινωνήστε μας";
"self_service_interface" = "Σελφ σέρβις";
"offLine"= "Το δίκτυό σας αποσυνδέθηκε, παρακαλώ προσπαθήστε αργότερα!";
"CustomerService"="HELP";
"elva__mark_helpful_toast"="Σας βοήθησε";
"elva__mark_unhelpful_toast"="Δεν σας βοήθησε";
"elva__mark_yes_no_question"="Σας βοήθησε;";
"elva__mark_no"="Όχι";
"elva__mark_yes"="Ναι";
"RewardBalance"="Το υπόλοιπο των πόντων σας:";
"GoTo" = "Μέχρι";
"Forum" = "Φόρουμ ερωτήσεων και απαντήσεων";
"RewardSuccess" = "Επιτυχής ανταμοιβή";
"RewardFailure" = "Αποτυχής ανταμοιβή";
"TokenInsufficient" = "Το υπόλοιπό σας δεν επαρκεί";
"NeedMoreHelp" = "Χρειάζεστε βοήθεια?";
"your question"="Εισάγετε ερώτηση";
"Success"="Success";
"Failed"="Failed";
res/ElvaChatServiceSDK.bundle/en.lproj/Localizable.strings
New file
@@ -0,0 +1,23 @@
//英语en
"content_too_long"="No more than %ld chars!";
"ContactCustomerService" = "Contact Us";
"self_service_interface" = "Self-Service";
"offLine"= "Your network is disconnected,please try again later";
"CustomerService"="HELP";
"elva__mark_helpful_toast"="You found this helpful";
"elva__mark_unhelpful_toast"="You didn't find this helpful";
"elva__mark_yes_no_question"="Was this helpful?";
"elva__mark_no"="NO";
"elva__mark_yes"="YES";
"RewardBalance"="Your tokens:";
"GoTo" = "Go to the";
"Forum" = "QA Forum";
"RewardSuccess" = "Success";
"RewardFailure" = "Failed";
"TokenInsufficient" = "Your tokens is insufficient";
"NeedMoreHelp" = "Need more help?";
"your question"="your question";
"Cancel"="Cancel";
"Oops, no relevant results were found"="Oops, no relevant results were found";
"Success"="Success";
"Failed"="Failed";
res/ElvaChatServiceSDK.bundle/es.lproj/Localizable.strings
New file
@@ -0,0 +1,23 @@
//西班牙语es
"content_too_long"="No más de %ld caracteres!";
"ContactCustomerService" = "CONTÁCTANOS";
"self_service_interface" = "Autoservicio";
"offLine"= "Su red está desconectada, inténtelo de nuevo más tarde.";
"CustomerService"="HELP";
"elva__mark_helpful_toast"="Le resultó útil";
"elva__mark_unhelpful_toast"="No le resultó útil";
"elva__mark_yes_no_question"="¿Sirvió de ayuda";
"elva__mark_no"="NO";
"elva__mark_yes"="Sí";
"RewardBalance"="Sus puntos:";
"GoTo" = "Ir a";
"Forum" = "Foro de QA";
"RewardSuccess" = "Éxito";
"RewardFailure" = "Ha fallado";
"TokenInsufficient" = "Sus puntos son insuficientes";
"NeedMoreHelp" = "Necesitas más ayuda?";
"your question"="Tu pregunta";
"Cancel"="Cancelar";
"Oops, no relevant results were found"="Lo sentimos mucho que no se puede encontrar ningún dato.";
"Success"="Success";
"Failed"="Failed";
res/ElvaChatServiceSDK.bundle/evaluate_submit.png
res/ElvaChatServiceSDK.bundle/fa.lproj/Localizable.strings
New file
@@ -0,0 +1,33 @@
//法斯语fa,fa-IR
"content_too_long"="نباید از %ld حروف بیشتر باشد.";
"ContactCustomerService" = "با ما تماس بگیرید";
"self_service_interface" = "پشتیبانی";
"offLine"= "اینترنت شما قطع می باشد ، لطفا بعدا امتحان کنید.";
"CustomerService"="HELP";
"elva__mark_helpful_toast"="این کمک مفیدی بود";
"elva__mark_unhelpful_toast"="کمک مفیدی نبود";
"elva__mark_yes_no_question"="آیا این مفید بود؟";
"elva__mark_no"="نه";
"elva__mark_yes"="بله";
"RewardBalance"="امتیاز باقیمانده شما";
"GoTo" = "برو به";
"Forum" = "گروه پرسش و پاسخ";
"RewardSuccess" = "موفقیت آمیز";
"RewardFailure" = "ناموفق";
"TokenInsufficient" = "امتیاز شما کافی نیست .";
"NeedMoreHelp" = "نیاز به کمک بیشتری دارید؟";
"your question"="سوال شما؟";
"Cancel"="لغو";
"Success"="Success";
"Failed"="Failed";
res/ElvaChatServiceSDK.bundle/fr-FR.lproj/Localizable.strings
New file
@@ -0,0 +1,24 @@
//法语fr,fr-FRfr-BE,fr-CA,fr-CH,fr-FR,fr-LU,fr-MC
"content_too_long"="Pas plus de %ld de caractères";
"ContactCustomerService" = "Contactez-nous";
"self_service_interface" = "Libre service";
"offLine"= "Votre connexion ne fonctionne pas, veuillez essayer de nouveau";
"CustomerService"="HELP";
"elva__mark_helpful_toast"="Est ce que cela vous aidé";
"elva__mark_unhelpful_toast"="Vous n'avez pas trouvez cela utile";
"elva__mark_yes_no_question"="Est-ce que cela a été utile?";
"elva__mark_no"="Non";
"elva__mark_yes"="Oui";
"RewardBalance"="Vos jetons";
"GoTo" = "Allez à";
"Forum" = "FAQ";
"RewardSuccess" = "Succès";
"RewardFailure" = "Echec";
"TokenInsufficient" = "Jeton insuffisant";
"NeedMoreHelp" = "Besoin d'aide?";
"your question"="Votre question";
"Cancel"="Annuler";
"Success"="Success";
"Failed"="Failed";
res/ElvaChatServiceSDK.bundle/id-ID.lproj/Localizable.strings
New file
@@ -0,0 +1,22 @@
//印度尼西亚语id,id-ID
"content_too_long"="Tidak dapat melebihi %ld karakter!";
"ContactCustomerService" = "Hubungi Kami";
"self_service_interface" = "Self-Service";
"offLine"= "Koneksi internet anda terputus, harap coba beberapa saat lagi";
"CustomerService"="HELP";
"elva__mark_helpful_toast"="Anda merasa terbantu";
"elva__mark_unhelpful_toast"="Anda merasa tidak terbantu";
"elva__mark_yes_no_question"="Apakah ini membantu?";
"elva__mark_no"="TIDAK";
"elva__mark_yes"="YA";
"RewardBalance"="Token Anda:";
"GoTo" = "Pergi ke";
"Forum" = "Forum Q&A";
"RewardSuccess" = "Berhasil";
"RewardFailure" = "Gagal";
"TokenInsufficient" = "Saldo token Anda tidak mencukupi";
"NeedMoreHelp" = "butuh lebih bantuan?";
"your question"="masukkan pertanyaan";
"Cancel"="membatalkan";
"Success"="Success";
"Failed"="Failed";
res/ElvaChatServiceSDK.bundle/it-IT.lproj/Localizable.strings
New file
@@ -0,0 +1,33 @@
//意大利语it,it-CH,it-IT
"content_too_long"="Non più di %ld caratteri!";
"ContactCustomerService" = "Contattaci";
"self_service_interface" = "Self Service";
"offLine"= "Il tuo collegamento si è interrotto, si prega di effettuare nuovamente l'accesso!";
"CustomerService"="HELP";
"elva__mark_helpful_toast"="Lo hai trovato utile";
"elva__mark_unhelpful_toast"="Lo hai trovato inutile";
"elva__mark_yes_no_question"="Questo è utile?";
"elva__mark_no"="No";
"elva__mark_yes"="Si";
"RewardBalance"="Il tuo bilancio punti:";
"GoTo" = "Fino a";
"Forum" = "Spazio domande";
"RewardSuccess" = "Premiazione riuscita";
"RewardFailure" = "Premiazione fallita";
"TokenInsufficient" = "Bilancio insufficiente";
"NeedMoreHelp" = "Serve ancora aiuto?";
"your question"="Inserire problema";
"Cancel"="Annulla";
"Success"="Success";
"Failed"="Failed";
res/ElvaChatServiceSDK.bundle/ja.lproj/Localizable.strings
New file
@@ -0,0 +1,25 @@
//日语ja
"content_too_long"="%ld文字を超えています。";
"ContactCustomerService" = "お問い合わせ";
"self_service_interface" = "セルフサービス";
"offLine"= "接続が切れました。もう一度試してください。";
"CustomerService"="HELP";
"elva__mark_helpful_toast"="ご評価ありがとうございました。";
"elva__mark_unhelpful_toast"="ご評価ありがとうございました。";
"elva__mark_yes_no_question"="お役に立ちましたか?";
"elva__mark_no"="いいえ";
"elva__mark_yes"="はい";
"RewardBalance"="ポイント残高:";
"GoTo" = "へ";
"Forum" = "QAフォーム";
"RewardSuccess" = "成功した";
"RewardFailure" = "失敗した";
"TokenInsufficient" = "残高不足";
"NeedMoreHelp" = "他のお問い合わせ内容がございますか?";
"your question"="お問い合わせ内容をご入力ください。";
"Cancel"="取り消し";
"Oops, no relevant results were found"="申し訳ございません、結果が見つかりませんでした。";
"Success"="成功";
"Failed"="失敗";
"Please tell us more details"="原因を具体的に書いてください。";
res/ElvaChatServiceSDK.bundle/ko.lproj/Localizable.strings
New file
@@ -0,0 +1,23 @@
//韩语ko
"content_too_long"="%ld 단어를 초과 할 수 없습니다!";
"ContactCustomerService" = "연락하기";
"self_service_interface" = "셀프 서비스";
"offLine"= "네트워크 연결이 끊어졌습니다. 나중에 다시 시도하십시오.";
"CustomerService"="HELP";
"elva__mark_helpful_toast"="질문이 도움이 되었다고 표시되었습니다";
"elva__mark_unhelpful_toast"="질문이 도움이 되지 않았다고 표시되었습니다";
"elva__mark_yes_no_question"="이 내용이 유용했나요?";
"elva__mark_no"="아니요";
"elva__mark_yes"="예";
"RewardBalance"="포인트 잔고:";
"GoTo" = "가기";
"Forum" = "Q&A 커뮤니티";
"RewardSuccess" = "성공";
"RewardFailure" = "실패";
"TokenInsufficient" = "토큰이 부족합니다.";
"NeedMoreHelp" = "도움이 더 필요하십니까?";
"your question"="귀하의 질문";
"Cancel"="취소";
"Oops, no relevant results were found"="해당 검색 결과가 없습니다.";
"Success"="Success";
"Failed"="Failed";
res/ElvaChatServiceSDK.bundle/loading.png
res/ElvaChatServiceSDK.bundle/message_receiver_background_normal.png
res/ElvaChatServiceSDK.bundle/message_receiver_background_normal@2x.png
res/ElvaChatServiceSDK.bundle/message_receiver_background_normal@3x.png
res/ElvaChatServiceSDK.bundle/message_sender_background_normal.png
res/ElvaChatServiceSDK.bundle/message_sender_background_normal@2x.png
res/ElvaChatServiceSDK.bundle/message_sender_background_normal@3x.png
res/ElvaChatServiceSDK.bundle/pl-PL.lproj/Localizable.strings
New file
@@ -0,0 +1,33 @@
//波兰语pl,pl-PL
"content_too_long"="Nie więcej niż %ld znaków!";
"ContactCustomerService" = "Obsługa klienta";
"self_service_interface" = "Samoobsługa";
"offLine"= "Brak dostępu do sieci, proszę spróbuj ponownie później.";
"CustomerService"="HELP";
"elva__mark_helpful_toast"="Uznałeś to za przydatne.";
"elva__mark_unhelpful_toast"="Nie uznałeś tego za przydatne.";
"elva__mark_yes_no_question"="Czy było to przydatne?";
"elva__mark_no"="Nie";
"elva__mark_yes"="Tak";
"RewardBalance"="Twój bilans punktów:";
"GoTo" = "Idź do";
"Forum" = "Forum pytań i odpowiedzi.";
"RewardSuccess" = "Sukces.";
"RewardFailure" = "Porażka.";
"TokenInsufficient" = "Niewystarczająca ilość punktów.";
"NeedMoreHelp" = "Bisogno Di Più Aiuto?";
"your question"="Wprowadź pytanie";
"Cancel"="Anuluj";
"Success"="Success";
"Failed"="Failed";
res/ElvaChatServiceSDK.bundle/pt-PT.lproj/Localizable.strings
New file
@@ -0,0 +1,25 @@
//葡萄牙语pt,pt-BR,pt-PT
"content_too_long"="Não pode ser mais de %ld palavras!";
"ContactCustomerService" = "Contate-Nos";
"self_service_interface" = "Self-Service";
"offLine"= "Sua conexão foi desconectada, entre novamente!";
"CustomerService"="HELP";
"elva__mark_helpful_toast"="Isso é útil";
"elva__mark_unhelpful_toast"="Isso não é útil";
"elva__mark_yes_no_question"="É útil?";
"elva__mark_no"="Não";
"elva__mark_yes"="Sim";
"RewardBalance"="Seus saldos de ponto:";
"GoTo" = "Chegar";
"Forum" = "Comunidade de pergunta e resposta";
"RewardSuccess" = "Recompense com sucesso";
"RewardFailure" = "Recompense não com sucesso";
"TokenInsufficient" = "Saldos insuficientes";
"NeedMoreHelp" = "Precisa mais ajuda?";
"your question"="Entra a pergunta";
"Cancel"="cancelar";
"Success"="Success";
"Failed"="Failed";
res/ElvaChatServiceSDK.bundle/ru.lproj/Localizable.strings
New file
@@ -0,0 +1,23 @@
//俄语ru
"content_too_long"="Не более %ld символов!";
"ContactCustomerService" = "Свяжитесь с нами";
"self_service_interface" = "Самообслуживание";
"offLine"= "Вы не подключены к сети, повторите попытку позже";
"CustomerService"="HELP";
"elva__mark_helpful_toast"="Вопрос был обозначен как Полезный";
"elva__mark_unhelpful_toast"="Вопрос был обозначен как Бесполезный";
"elva__mark_yes_no_question"="Это вам помогло?";
"elva__mark_no"="НЕТ";
"elva__mark_yes"="ДА";
"RewardBalance"="Остаток баллов:";
"GoTo" = "Перейти";
"Forum" = "QA форум";
"RewardSuccess" = "Успешно";
"RewardFailure" = "Неудачно";
"TokenInsufficient" = "Недостаточно баллов";
"NeedMoreHelp" = "Нужна помощь?";
"your question"="Ваш вопрос";
"Cancel"="отменить";
"Oops, no relevant results were found"="Извините, по вашему запросу ничего не найдено.";
"Success"="Success";
"Failed"="Failed";
res/ElvaChatServiceSDK.bundle/show_faq_list.png
res/ElvaChatServiceSDK.bundle/sv-SE.lproj/Localizable.strings
New file
@@ -0,0 +1,25 @@
//瑞典语sv,sv-FI,sv-SE
"content_too_long"="Får inte vara längre än %ld tecken!";
"ContactCustomerService" = "Kontakta KS";
"self_service_interface" = "Självservice";
"offLine"= "Anslutning bruten, försök igen!";
"CustomerService"="HELP";
"elva__mark_helpful_toast"="Fick du hjälp av detta?";
"elva__mark_unhelpful_toast"="Fick du inte hjälp av detta?";
"elva__mark_yes_no_question"="Fick du hjälp av detta?";
"elva__mark_no"="Nej";
"elva__mark_yes"="Ja";
"RewardBalance"="Dina poäng:";
"GoTo" = "Gå till";
"Forum" = "Frågeforum";
"RewardSuccess" = "Lyckades";
"RewardFailure" = "Misslyckades";
"TokenInsufficient" = "Du har inte tillräckligt med poäng";
"NeedMoreHelp" = "Behöver mer hjälp?";
"your question"="Ange fråga";
"Cancel"="annullera";
"Success"="Success";
"Failed"="Failed";
res/ElvaChatServiceSDK.bundle/th.lproj/Localizable.strings
New file
@@ -0,0 +1,22 @@
//泰语th
"content_too_long"="ไม่เกิน %ld ตัวอักษร!";
"ContactCustomerService" = "ติดต่อเรา";
"self_service_interface" = "Self-Service";
"offLine"= "การเชื่อมต่อผิดพลาด กรุณาเข้าระบบอีกครั้ง!";
"CustomerService"="HELP";
"elva__mark_helpful_toast"="คำถามนี้ถูกระบุว่ามีประโยชน์";
"elva__mark_unhelpful_toast"="คำถามนี้ถูกระบุว่าไม่มีประโยชน์";
"elva__mark_yes_no_question"="ข้อมูลดังกล่าวมีประโยชน์หรือไม่";
"elva__mark_no"="ไม่ใช่";
"elva__mark_yes"="ใช่";
"RewardBalance"="แต้มของคุณเหลือ:";
"GoTo" = "ถึง";
"Forum" = "ถามตอบ";
"RewardSuccess" = "ให้รางวัลสำเร็จ";
"RewardFailure" = "ให้รางวัลล้มเหลว";
"TokenInsufficient" = "จำนวนคงเหลือไม่พอ";
"NeedMoreHelp" = "ต้องการความช่วยเหลือ?";
"your question"="คำถามของคุณ";
"Cancel"="ยกเลิก";
"Success"="Success";
"Failed"="Failed";
res/ElvaChatServiceSDK.bundle/tr.lproj/Localizable.strings
New file
@@ -0,0 +1,22 @@
//土耳其语tr
"content_too_long"="En fazla %ld karakter kullanılabilir!";
"ContactCustomerService" = "İletişim";
"self_service_interface" = "Kendin Hallet";
"offLine"= "Bağlantı hatası,lütfen tekrar deneyin!";
"CustomerService"="HELP";
"elva__mark_helpful_toast"="Bunu faydalı buldum!";
"elva__mark_unhelpful_toast"="Bunu faydalı bulmadım!";
"elva__mark_yes_no_question"="Bunu faydalı buldunuz mu?";
"elva__mark_no"="Hayır";
"elva__mark_yes"="Evet";
"RewardBalance"="Puanınız:";
"GoTo" = "Git:";
"Forum" = "Sıkça Sorulan Sorular";
"RewardSuccess" = "Başarılı!";
"RewardFailure" = "Başarısız!";
"TokenInsufficient" = "Bakiyeniz yetersiz!";
"NeedMoreHelp" = "Ihtiyacınız yardıma?";
"your question"="Sorunuzu girin!";
"Cancel"="iptal etmek";
"Success"="Success";
"Failed"="Failed";
res/ElvaChatServiceSDK.bundle/uploadPic.png
res/ElvaChatServiceSDK.bundle/vi-VN.lproj/Localizable.strings
New file
@@ -0,0 +1,25 @@
//越南语vi,vi-VN
"content_too_long"="Không vượt quá %ld ký tự!";
"ContactCustomerService" = "Liên hệ CSKH";
"self_service_interface" = "Dịch vụ tự động";
"offLine"= "Đã mất kết nối, hãy vào lại!";
"CustomerService"="HELP";
"elva__mark_helpful_toast"="Phát hiện có hỗ trợ";
"elva__mark_unhelpful_toast"="Phát hiện không có hỗ trợ";
"elva__mark_yes_no_question"="Ở đây có hỗ trợ không?";
"elva__mark_no"="Không";
"elva__mark_yes"="Có";
"RewardBalance"="Tích điểm còn:";
"GoTo" = "Đến";
"Forum" = "Cộng đồng hỏi đáp";
"RewardSuccess" = "Thưởng thành công";
"RewardFailure" = "Thưởng thất bại";
"TokenInsufficient" = "Không còn đủ";
"NeedMoreHelp" = "cần thêm giúp?";
"your question"="Lỗi nhập";
"Cancel"="hủy bỏ";
"Success"="Success";
"Failed"="Failed";
res/ElvaChatServiceSDK.bundle/zh-Hans.lproj/Localizable.strings
New file
@@ -0,0 +1,24 @@
//中文简体zh-Hans
"content_too_long"="不能超过%ld个字!";
"ContactCustomerService" = "联系客服";
"self_service_interface" = "自助服务";
"offLine"= "您的网络连接已经断开,请检查网络!";
"CustomerService"="HELP";
"elva__mark_helpful_toast"="你发现这有帮助";
"elva__mark_unhelpful_toast"="你发现这无帮助";
"elva__mark_yes_no_question"="这有帮助吗";
"elva__mark_no"="否";
"elva__mark_yes"="是";
"RewardBalance"="您的积分余额:";
"GoTo" = "到";
"Forum" = "问答社区";
"RewardSuccess" = "打赏成功";
"RewardFailure" = "打赏失败";
"TokenInsufficient" = "余额不足";
"NeedMoreHelp" = "需要更多帮助?";
"your question"="输入问题";
"Cancel"="取消";
"Oops, no relevant results were found"="抱歉,未找到相关结果";
"Success"="成功";
"Failed"="失败";
"Please tell us more details"="请告知我们具体原因";
res/ElvaChatServiceSDK.bundle/zh-Hant.lproj/Localizable.strings
New file
@@ -0,0 +1,24 @@
//中文繁体zh-Hant
"content_too_long"="不能超過%ld個字!";
"ContactCustomerService" = "聯系客服";
"self_service_interface" = "自助服務";
"offLine"= "您的網絡連接已經斷開,請檢查網絡!";
"CustomerService"="HELP";
"elva__mark_helpful_toast"="妳發現這有幫助";
"elva__mark_unhelpful_toast"="妳發現這無幫助";
"elva__mark_yes_no_question"="這有幫助嗎?";
"elva__mark_no"="否";
"elva__mark_yes"="是";
"RewardBalance"="您的積分餘額:";
"GoTo" = "到";
"Forum" = "問答社區";
"RewardSuccess" = "打賞成功";
"RewardFailure" = "打賞失敗";
"TokenInsufficient" = "餘額不足";
"NeedMoreHelp" = "需要更多幫助?";
"your question"="輸入問題";
"Cancel"="取消";
"Oops, no relevant results were found"="抱歉,未找到相關結果";
"Success"="成功";
"Failed"="失敗";
"Please tell us more details"="請告知我們具體原因";