Commit 4172aca147230e860b20eabe1e5e29ce69166f7a
1 parent
c5a35a8c
no message
Showing
43 changed files
with
0 additions
and
4849 deletions
Too many changes to show.
To preserve performance only 43 of 2662 files are displayed.
Example/Products/CNLivePlayer.framework/CNLivePlayer deleted
100644 → 0
No preview for this file type
Example/Products/CNLivePlayer.framework/Headers/CNLivePlayer.h deleted
100644 → 0
| 1 | -// | |
| 2 | -// CNLivePlayer.h | |
| 3 | -// CNLivePlayer_Example | |
| 4 | -// | |
| 5 | -// Created by CNLive-zxw on 2019/7/26. | |
| 6 | -// Copyright © 2019 153993236@qq.com. All rights reserved. | |
| 7 | -// | |
| 8 | - | |
| 9 | -#import <Foundation/Foundation.h> | |
| 10 | -#import <libksygpulive/KSYMoviePlayerController.h> | |
| 11 | -#import "KSYMoviePlayerDefines.h" | |
| 12 | - | |
| 13 | -// 枚举定义 | |
| 14 | -#import "CNLivePlayerDefines.h" | |
| 15 | - | |
| 16 | -// 播放器管理类 | |
| 17 | -#import "CNLivePlayerManager.h" | |
| 18 | - | |
| 19 | -//缓存url | |
| 20 | -#import "CNLivePlayerCache.h" | |
| 21 | - | |
| 22 | -NS_ASSUME_NONNULL_BEGIN | |
| 23 | - | |
| 24 | -/* | |
| 25 | - * 获取主播状态通知 | |
| 26 | - */ | |
| 27 | -UIKIT_EXTERN NSString *const CNLiveHostStatusChangedNotification; | |
| 28 | - | |
| 29 | -/* | |
| 30 | - * 成功回调 | |
| 31 | - */ | |
| 32 | -typedef void(^AuthSuccessBlock)(void); | |
| 33 | - | |
| 34 | -/* | |
| 35 | - * 失败回调 | |
| 36 | - */ | |
| 37 | -typedef void(^AuthFailureBlock)(NSDictionary *errorInfo); | |
| 38 | - | |
| 39 | -@interface CNLivePlayer : NSObject | |
| 40 | - | |
| 41 | -/* | |
| 42 | - * 播放器类型 | |
| 43 | - */ | |
| 44 | -@property (nonatomic, assign, readonly) CNLivePlayerType type; | |
| 45 | - | |
| 46 | -/* | |
| 47 | - * 播放器 | |
| 48 | - */ | |
| 49 | -@property (nonatomic, strong) KSYMoviePlayerController *player; | |
| 50 | - | |
| 51 | -#pragma mark - 初始化方法 | |
| 52 | -/* | |
| 53 | - * 初始化播放器并设置播放地址 | |
| 54 | - * | |
| 55 | - * url 视频url | |
| 56 | - * | |
| 57 | - */ | |
| 58 | -- (instancetype)initWithContentURL:(NSURL *)url; | |
| 59 | - | |
| 60 | - | |
| 61 | -/* 初始化点播播放器 初始化成功后才能对播放器进行设置(如:自动播放、是否开启硬件解码等)和调用准备播放视频方法(prepareToPlay) | |
| 62 | - * | |
| 63 | - * videoId 视频Id | |
| 64 | - * authSuccess 初始化成功block | |
| 65 | - * authFailed 初始化失败block 回调一个errorInfo的字典 | |
| 66 | - * | |
| 67 | - */ | |
| 68 | -- (instancetype)initVodPlayerWithVideoId:(NSString *)videoId authSuccess:(AuthSuccessBlock)authSuccessBlock authFailure:(AuthFailureBlock)authFailureBlock; | |
| 69 | - | |
| 70 | - | |
| 71 | -/* 初始化直播播放器(* 以channelId播放) 初始化成功后才能对播放器进行设置(如:自动播放、是否开启硬件解码等)和调用准备播放视频方法(prepareToPlay) | |
| 72 | - * | |
| 73 | - * channelId 直播视频Id (注* 若agree为YES时,必传,用于获取主播状态; 若agree为NO,可不传) | |
| 74 | - * activityId 活动Id | |
| 75 | - * agree 是否允许获取主播状态 YES:获取 NO:不获取 | |
| 76 | - * authSuccess 初始化成功block | |
| 77 | - * authFailed 初始化失败block 回调一个errorInfo的字典 | |
| 78 | - * | |
| 79 | - * result 获取主播状态 YES:获取状态成功 | |
| 80 | - * NO:获取失败,不影响视频播放,但是获取不到主播离开、回来、直播结束等通知。 | |
| 81 | - * 可通过- (void)getHostStatus:(void(^)(BOOL result))result;方法重新获取 | |
| 82 | - */ | |
| 83 | -- (instancetype)initLivePlayerWithChannelId:(NSString *)channelId activityId:(NSString *)activityId hostStatus:(BOOL)agree authSuccess:(AuthSuccessBlock)authSuccessBlock authFailure:(AuthFailureBlock)authFailureBlock getHostStatusResult:(void(^)(BOOL result))result; | |
| 84 | - | |
| 85 | - | |
| 86 | -/* 初始化音频播放器 初始化成功后才能对播放器进行设置(如:自动播放、是否开启硬件解码等)和调用准备播放视频方法(prepareToPlay) | |
| 87 | - * | |
| 88 | - * contentId 音频Id | |
| 89 | - * authSuccess 初始化成功block | |
| 90 | - * authFailed 初始化失败block 回调一个errorInfo的字典 | |
| 91 | - * | |
| 92 | - */ | |
| 93 | -- (instancetype)initAudioPlayerWithAudioId:(NSString *)audioId authSuccess:(AuthSuccessBlock)authSuccessBlock authFailure:(AuthFailureBlock)authFailureBlock; | |
| 94 | - | |
| 95 | -#pragma mark - 属性 | |
| 96 | -/** | |
| 97 | - @abstract 正在播放的视频文件的地址,该地址可以是本地地址或者服务器地址。 | |
| 98 | - */ | |
| 99 | -@property (nonatomic, readonly) NSURL *contentURL; | |
| 100 | - | |
| 101 | -/** | |
| 102 | - @abstract 包含视频播放内容的VIEW(只读)。 | |
| 103 | - @discussion view的使用逻辑: | |
| 104 | - | |
| 105 | - * 可以通过frame设置view大大小 | |
| 106 | - * 使用[scalingMode]([KSYMoviePlayerController scalingMode]) 可以更改视频内容在VIEW中的显示情况 | |
| 107 | - | |
| 108 | - @see scalingMode | |
| 109 | - */ | |
| 110 | -// The view in which the media and playback controls are displayed. | |
| 111 | -@property (nonatomic, strong, readonly) UIView *view; | |
| 112 | - | |
| 113 | -/* | |
| 114 | - * 主播直播状态(只读) | |
| 115 | - */ | |
| 116 | -@property (nonatomic, assign, readonly) CNLiveHostStatus hostStatus; | |
| 117 | - | |
| 118 | -/** | |
| 119 | - @abstract 是否静音 | |
| 120 | - @discussion | |
| 121 | - * 默认不静音 | |
| 122 | - * [prepareToPlay]方法前设置即生效,也可以在播放过程中动态切换 | |
| 123 | - */ | |
| 124 | -@property (nonatomic) BOOL shouldMute; | |
| 125 | - | |
| 126 | -/** | |
| 127 | - @abstract 是否循环播放 | |
| 128 | - @discussion 默认不循环 | |
| 129 | - * 只在[prepareToPlay]调用前设置生效; | |
| 130 | - * 只有点播生效,直播场景请勿设置 | |
| 131 | - */ | |
| 132 | -@property (nonatomic) BOOL shouldLoop; | |
| 133 | - | |
| 134 | -/** | |
| 135 | - @abstract 指定逆时针旋转角度,只能是0/90/180/270, 不符合上述值不进行旋转 | |
| 136 | - */ | |
| 137 | -@property (nonatomic, assign) int rotateDegress; | |
| 138 | - | |
| 139 | -/** | |
| 140 | - @abstract 是否打断其他后台的音乐播放 | |
| 141 | - @discussion 也可以理解为是否允许和其他音频同时播放 | |
| 142 | - @discussion YES:开始播放时,会打断其他的后台播放音频,也会被其他音频播放打断 | |
| 143 | - @discussion NO: 可以与其他后台播放共存,相互之间不会被打断 | |
| 144 | - @discussion 默认为YES | |
| 145 | - */ | |
| 146 | -@property (nonatomic) BOOL bInterruptOtherAudio; | |
| 147 | - | |
| 148 | -/* | |
| 149 | - * 查询视频准备是否完成(只读) | |
| 150 | - */ | |
| 151 | -@property (nonatomic, readonly) BOOL isPreparedToPlay; | |
| 152 | - | |
| 153 | -#pragma mark - 方法 | |
| 154 | -/* | |
| 155 | - * 获取主播状态(离开/已结束) | |
| 156 | - */ | |
| 157 | -- (void)getHostStatus:(void(^)(BOOL result))result; | |
| 158 | - | |
| 159 | -/* 给播放器设置内容id 设置成功后才能播放(如:自动播放、是否开启硬件解码等)和调用准备播放视频方法(prepareToPlay) | |
| 160 | - * 切换视频 | |
| 161 | - * contentId 内容Id | |
| 162 | - * type 内容类型 | |
| 163 | - * | |
| 164 | - */ | |
| 165 | -- (void)setPlayerWithContentId:(NSString *)contentId type:(CNLivePlayerType)type authSuccess:(AuthSuccessBlock)authSuccessBlock authFailure:(AuthFailureBlock)authFailureBlock; | |
| 166 | - | |
| 167 | -/* | |
| 168 | - * 销毁播放器 | |
| 169 | - */ | |
| 170 | -- (void)destroyPlayer; | |
| 171 | - | |
| 172 | -/* | |
| 173 | - * 准备视频播放 | |
| 174 | - * MPMediaPlaybackIsPreparedToPlayDidChangeNotification 播放器完成对视频文件的初始化时发送通知 | |
| 175 | - */ | |
| 176 | -- (void)prepareToPlay; | |
| 177 | - | |
| 178 | -/* | |
| 179 | - * 视频播放 | |
| 180 | - */ | |
| 181 | -- (void)play; | |
| 182 | - | |
| 183 | -/* | |
| 184 | - * 当前播放器是否在播放 | |
| 185 | - */ | |
| 186 | -- (BOOL)isPlaying; | |
| 187 | - | |
| 188 | -/* | |
| 189 | - * 视频暂停 | |
| 190 | - */ | |
| 191 | -- (void)pause; | |
| 192 | - | |
| 193 | -/* | |
| 194 | - * 视频停止 | |
| 195 | - */ | |
| 196 | -- (void)stop; | |
| 197 | - | |
| 198 | -/* | |
| 199 | - * 视频截图 | |
| 200 | - */ | |
| 201 | -- (UIImage *)thumbnailImageAtCurrentTime; | |
| 202 | - | |
| 203 | -@end | |
| 204 | - | |
| 205 | -NS_ASSUME_NONNULL_END |
Example/Products/CNLivePlayer.framework/Headers/CNLivePlayerCache.h deleted
100644 → 0
| 1 | -// | |
| 2 | -// CNLivePlayerCache.h | |
| 3 | -// CNLivePlayer_Example | |
| 4 | -// | |
| 5 | -// Created by CNLive-zxw on 2019/7/26. | |
| 6 | -// Copyright © 2019 153993236@qq.com. All rights reserved. | |
| 7 | -// | |
| 8 | - | |
| 9 | -#import <Foundation/Foundation.h> | |
| 10 | - | |
| 11 | -NS_ASSUME_NONNULL_BEGIN | |
| 12 | - | |
| 13 | -@interface CNLivePlayerCache : NSObject | |
| 14 | - | |
| 15 | -/** | |
| 16 | - * 存储或者修改数据 | |
| 17 | - * | |
| 18 | - * @param data 保存的数据 | |
| 19 | - * @param key 保存的key | |
| 20 | - */ | |
| 21 | -+ (void)player_SaveDataCache:(id)data forKey:(NSString *)key; | |
| 22 | - | |
| 23 | - | |
| 24 | -/** | |
| 25 | - * 读取数据 | |
| 26 | - * | |
| 27 | - * @param key 保存的key | |
| 28 | - * | |
| 29 | - * @return 返回id | |
| 30 | - */ | |
| 31 | -+ (id)player_ReadCache:(NSString *)key; | |
| 32 | - | |
| 33 | - | |
| 34 | -/** | |
| 35 | - * 读取缓存文件的大小 | |
| 36 | - * | |
| 37 | - * @return 返回NSString | |
| 38 | - */ | |
| 39 | -+ (NSString *)player_GetAllHttpCacheSize; | |
| 40 | - | |
| 41 | - | |
| 42 | -/** | |
| 43 | - * 是否缓存过 | |
| 44 | - * | |
| 45 | - * @param key 保存的key | |
| 46 | - * | |
| 47 | - * @return 返回NSString | |
| 48 | - */ | |
| 49 | -+ (BOOL)player_IsCache:(NSString *)key; | |
| 50 | - | |
| 51 | - | |
| 52 | -/** | |
| 53 | - * 删除某个磁盘缓存文件 | |
| 54 | - * | |
| 55 | - * @param key 保存的key(就是请求的url) | |
| 56 | - * | |
| 57 | - */ | |
| 58 | -+ (void)player_RemoveChache:(NSString *)key; | |
| 59 | - | |
| 60 | - | |
| 61 | -/** | |
| 62 | - * 磁盘最大缓存开销 | |
| 63 | - * 默认是30*1024*1024 | |
| 64 | - */ | |
| 65 | -+ (void)player_SetCostLimit:(NSInteger)costLimit; | |
| 66 | - | |
| 67 | - | |
| 68 | -/** | |
| 69 | - * 删除所有的磁盘缓存url(YYCache) | |
| 70 | - */ | |
| 71 | -+ (void)player_RemoveAllUrlCache; | |
| 72 | - | |
| 73 | - | |
| 74 | -/** | |
| 75 | - * 删除所有的磁盘缓存url(YYCache) | |
| 76 | - * 删除所有的磁盘缓存视频(KSYHTTPProxyService) | |
| 77 | - */ | |
| 78 | -+ (void)player_clearAllCache; | |
| 79 | - | |
| 80 | -@end | |
| 81 | - | |
| 82 | -NS_ASSUME_NONNULL_END |
Example/Products/CNLivePlayer.framework/Headers/CNLivePlayerDefines.h deleted
100644 → 0
| 1 | -// | |
| 2 | -// CNLivePlayerDefines.h | |
| 3 | -// CNLivePlayer | |
| 4 | -// | |
| 5 | -// Created by CNLive-zxw on 2019/8/14. | |
| 6 | -// Copyright © 2019 153993236@qq.com. All rights reserved. | |
| 7 | -// | |
| 8 | - | |
| 9 | -#ifndef CNLivePlayerDefines_h | |
| 10 | -#define CNLivePlayerDefines_h | |
| 11 | - | |
| 12 | -/* | |
| 13 | - * 播放器类型 | |
| 14 | - */ | |
| 15 | -typedef NS_ENUM(NSUInteger, CNLivePlayerType) { | |
| 16 | - CNLivePlayerVod, //点播 | |
| 17 | - CNLivePlayerLive, //直播 | |
| 18 | - CNLivePlayerAudio //音频 | |
| 19 | - | |
| 20 | -}; | |
| 21 | - | |
| 22 | -/** | |
| 23 | - * 主播直播状态 | |
| 24 | - */ | |
| 25 | -typedef NS_ENUM(NSUInteger, CNLiveHostStatus) { | |
| 26 | - //主播直播中 | |
| 27 | - CNLiveHostStatusLiving = 1, | |
| 28 | - //直播已结束 | |
| 29 | - CNLiveHostStatusEnd = 2, | |
| 30 | - //主播已离开 | |
| 31 | - CNLiveHostStatusLeaving = 3 | |
| 32 | - | |
| 33 | -}; | |
| 34 | - | |
| 35 | -#endif /* CNLivePlayerDefines_h */ |
Example/Products/CNLivePlayer.framework/Headers/CNLivePlayerManager.h deleted
100644 → 0
| 1 | -// | |
| 2 | -// CNLivePlayerManager.h | |
| 3 | -// CNLivePlayer_Example | |
| 4 | -// | |
| 5 | -// Created by CNLive-zxw on 2019/7/26. | |
| 6 | -// Copyright © 2019 153993236@qq.com. All rights reserved. | |
| 7 | -// | |
| 8 | - | |
| 9 | -#import <Foundation/Foundation.h> | |
| 10 | - | |
| 11 | -#define PLAYER_AppID [CNLivePlayerManager manager].appId?[CNLivePlayerManager manager].appId:@"" | |
| 12 | -#define PLAYER_AppKey [CNLivePlayerManager manager].appKey?[CNLivePlayerManager manager].appKey:@"" | |
| 13 | -#define PLAYER_UserId [CNLivePlayerManager manager].userId?[CNLivePlayerManager manager].userId:@"" | |
| 14 | -#define PLAYER_ChannelName [CNLivePlayerManager manager].channelName?[CNLivePlayerManager manager].channelName:@"" | |
| 15 | -#define PLAYER_Tag [CNLivePlayerManager manager].tag?[CNLivePlayerManager manager].tag:@"" | |
| 16 | -#define PLAYER_TestEnvironment [CNLivePlayerManager manager].isTestEnvironment | |
| 17 | - | |
| 18 | -NS_ASSUME_NONNULL_BEGIN | |
| 19 | - | |
| 20 | -@interface CNLivePlayerManager : NSObject | |
| 21 | -+ (CNLivePlayerManager *)manager; | |
| 22 | - | |
| 23 | -/** | |
| 24 | - * 应用ID(只读) | |
| 25 | - */ | |
| 26 | -@property (nonatomic, copy, readonly) NSString *appId; | |
| 27 | - | |
| 28 | -/** | |
| 29 | - * 应用KEY(只读) | |
| 30 | - */ | |
| 31 | -@property (nonatomic, copy, readonly) NSString *appKey; | |
| 32 | - | |
| 33 | -/** | |
| 34 | - * 是否是测试环境 | |
| 35 | - */ | |
| 36 | -@property (nonatomic, assign, readonly) BOOL isTestEnvironment; | |
| 37 | - | |
| 38 | -/** | |
| 39 | - * 用户ID | |
| 40 | - */ | |
| 41 | -@property (nonatomic, copy) NSString *userId; | |
| 42 | - | |
| 43 | -/** | |
| 44 | - * ChannelName 网++定制 | |
| 45 | - */ | |
| 46 | -@property (nonatomic, copy) NSString *channelName; | |
| 47 | - | |
| 48 | -/** | |
| 49 | - * tag 网++定制 | |
| 50 | - */ | |
| 51 | -@property (nonatomic, copy) NSString *tag; | |
| 52 | - | |
| 53 | -/** | |
| 54 | - * from 网++定制 | |
| 55 | - */ | |
| 56 | -@property (nonatomic, copy) NSString *from; | |
| 57 | - | |
| 58 | -/** | |
| 59 | - @abstract 初始化直播云SDK(该方法默认正式环境) | |
| 60 | - @param appId 在open.cnlive.com网站申请得到的appId | |
| 61 | - @param appKey 在open.cnlive.com网站申请得到的appKey | |
| 62 | - @warning 必传参数 | |
| 63 | - */ | |
| 64 | -+ (void)setAppId:(NSString *)appId appKey:(NSString *)appKey; | |
| 65 | - | |
| 66 | -/** | |
| 67 | - @abstract 初始化直播云SDK | |
| 68 | - @param appId 在open.cnlive.com网站申请得到的appId | |
| 69 | - @param appKey 在open.cnlive.com网站申请得到的appKey | |
| 70 | - @param isTestEnvironment YES:测试环境 NO:正式环境 | |
| 71 | - @warning 必传参数 | |
| 72 | - */ | |
| 73 | -+ (void)setAppId:(NSString *)appId appKey:(NSString *)appKey isTestEnvironment:(BOOL)isTestEnvironment; | |
| 74 | - | |
| 75 | -/** | |
| 76 | - @abstract 获取版本号 | |
| 77 | - */ | |
| 78 | -+ (NSString *)getVersion; | |
| 79 | - | |
| 80 | - | |
| 81 | -@end | |
| 82 | - | |
| 83 | -NS_ASSUME_NONNULL_END |
Example/Products/CNLivePlayer.framework/Info.plist deleted
100644 → 0
No preview for this file type
Example/Products/CNLivePlayer.framework/Modules/module.modulemap deleted
100644 → 0
Example/Products/CNLivePlayer.framework/PrivateHeaders/CNLivePlayer-umbrella.h deleted
100644 → 0
| 1 | -#ifdef __OBJC__ | |
| 2 | -#import <UIKit/UIKit.h> | |
| 3 | -#else | |
| 4 | -#ifndef FOUNDATION_EXPORT | |
| 5 | -#if defined(__cplusplus) | |
| 6 | -#define FOUNDATION_EXPORT extern "C" | |
| 7 | -#else | |
| 8 | -#define FOUNDATION_EXPORT extern | |
| 9 | -#endif | |
| 10 | -#endif | |
| 11 | -#endif | |
| 12 | - | |
| 13 | -#import "CNLivePlayer.h" | |
| 14 | -#import "CNLivePlayerConst.h" | |
| 15 | -#import "CNLivePlayerDefines.h" | |
| 16 | -#import "CNLivePlayerManager.h" | |
| 17 | -#import "CNLivePlayerCache.h" | |
| 18 | -#import "CNLivePlayerCache.h" | |
| 19 | -#import "CNLivePlayerNetworkManager.h" | |
| 20 | -#import "CNLiveURLRequestSerialization.h" | |
| 21 | -#import "CNLivePlayer.h" | |
| 22 | -#import "CNLivePlayerConst.h" | |
| 23 | -#import "CNLivePlayerDefines.h" | |
| 24 | -#import "CNLivePlayerManager.h" | |
| 25 | -#import "CNLivePlayerTools.h" | |
| 26 | - | |
| 27 | -FOUNDATION_EXPORT double CNLivePlayerVersionNumber; | |
| 28 | -FOUNDATION_EXPORT const unsigned char CNLivePlayerVersionString[]; | |
| 29 | - |
Example/Products/CNLivePlayer.framework/PrivateHeaders/CNLivePlayerConst.h deleted
100644 → 0
| 1 | -// | |
| 2 | -// CNLivePlayerConst.h | |
| 3 | -// CNLivePlayer | |
| 4 | -// | |
| 5 | -// Created by CNLive-zxw on 2019/8/14. | |
| 6 | -// Copyright © 2019 153993236@qq.com. All rights reserved. | |
| 7 | -// | |
| 8 | - | |
| 9 | -#ifndef CNLivePlayerConst_h | |
| 10 | -#define CNLivePlayerConst_h | |
| 11 | - | |
| 12 | -#pragma mark - 版本号 | |
| 13 | -#define PlayerSDKVersion @"0.0.1" //播放器SDK版本 | |
| 14 | - | |
| 15 | -#pragma mark - 探针 | |
| 16 | -#define StatUrl [CNLivePlayerManager manager].isTestEnvironment?@"http://app.sta.cnlive.com/app.jpg": @"http://app.sta.cnlive.com/app.jpg" | |
| 17 | -#define StatVersion @"4.0" //探针版本 | |
| 18 | -#define StatAppVersion ([[[NSBundle mainBundle] infoDictionary] objectForKey: @"CFBundleShortVersionString"]) | |
| 19 | - | |
| 20 | -#pragma mark - 鉴权 | |
| 21 | -#define authUrl [NSString stringWithFormat:@"%@/platform/valid", [CNLivePlayerManager manager].isTestEnvironment ? @"http://test.open.cnlive.com/openapi/api2" : @"http://api.cnlive.com/open/api2"] | |
| 22 | - | |
| 23 | -#pragma mark - 点播 | |
| 24 | -#define vodUrl [CNLivePlayerManager manager].isTestEnvironment ? @"http://test.open.cnlive.com/openapi/api2/vod_ips/vodplayByAPP":@"http://api.cnlive.com/open/api2/vod_ips/vodplayByAPP" | |
| 25 | - | |
| 26 | -#pragma mark - 直播 | |
| 27 | -#define liveUrl [CNLivePlayerManager manager].isTestEnvironment ? @"http://test.open.cnlive.com/openapi/api2/live_ips/liveplayByAPP":@"http://api.cnlive.com/open/api2/live_ips/liveplayByAPP" | |
| 28 | - | |
| 29 | -#endif /* CNLivePlayerConst_h */ |
Example/Products/CNLivePlayer.framework/PrivateHeaders/CNLivePlayerNetworkManager.h deleted
100644 → 0
| 1 | -// | |
| 2 | -// CNLivePlayerNetworkManager.h | |
| 3 | -// CNLivePlayer_Example | |
| 4 | -// | |
| 5 | -// Created by CNLive-zxw on 2019/7/26. | |
| 6 | -// Copyright © 2019 153993236@qq.com. All rights reserved. | |
| 7 | -// | |
| 8 | - | |
| 9 | -#import <Foundation/Foundation.h> | |
| 10 | - | |
| 11 | -NS_ASSUME_NONNULL_BEGIN | |
| 12 | -typedef void(^GetVideoURLSuccessBlock)(NSString * _Nullable videoURL, NSInteger code); | |
| 13 | - | |
| 14 | -@interface CNLivePlayerNetworkManager : NSObject | |
| 15 | -/** | |
| 16 | - * 设置超时时间 | |
| 17 | - */ | |
| 18 | -@property (nonatomic, assign) NSTimeInterval timeoutInterval; | |
| 19 | - | |
| 20 | -/** | |
| 21 | - * 缓存策略 | |
| 22 | - */ | |
| 23 | -@property (nonatomic, assign) NSURLRequestCachePolicy cachePolicy; | |
| 24 | - | |
| 25 | -+ (CNLivePlayerNetworkManager *)manager; | |
| 26 | - | |
| 27 | -/** | |
| 28 | - * GET 请求 | |
| 29 | - * @param URL url | |
| 30 | - * @param parameters 上传参数 | |
| 31 | - * @param success 请求成功回调 | |
| 32 | - * @param failure 请求失败回调 | |
| 33 | - */ | |
| 34 | -+ (void)GET:(nullable NSString *)URL parameters:(nullable NSDictionary *)parameters success:(nullable void (^)(NSURLResponse *_Nullable response, id _Nullable responseObject))success failure:(nullable void (^)(NSURLResponse *_Nullable response, NSError *_Nullable error))failure; | |
| 35 | - | |
| 36 | -/** | |
| 37 | - * POST 请求 | |
| 38 | - * @param URL url | |
| 39 | - * @param parameters 上传参数 | |
| 40 | - * @param success 请求成功回调 | |
| 41 | - * @param failure 请求失败回调 | |
| 42 | - */ | |
| 43 | -+ (void)POST:(nullable NSString *)URL parameters:(nullable NSDictionary *)parameters success:(nullable void (^)(NSURLResponse *_Nullable response, id _Nullable responseObject))success failure:(nullable void (^)(NSURLResponse *_Nullable response, NSError *_Nullable error))failure; | |
| 44 | - | |
| 45 | - | |
| 46 | -#pragma mark - 针对具体业务 | |
| 47 | -/** | |
| 48 | - * 鉴权 | |
| 49 | - */ | |
| 50 | -- (void)authenticate:(NSString *)URL success:(void (^)(NSURLResponse * _Nullable, id _Nullable))success failure:(void (^)(NSURLResponse * _Nullable, NSError * _Nullable))failure; | |
| 51 | - | |
| 52 | -/** | |
| 53 | - * 获取视频url | |
| 54 | - */ | |
| 55 | -+ (void)getVideoURL:(nullable NSString *)URL success:(GetVideoURLSuccessBlock)success; | |
| 56 | - | |
| 57 | - | |
| 58 | -@end | |
| 59 | - | |
| 60 | -NS_ASSUME_NONNULL_END |
Example/Products/CNLivePlayer.framework/PrivateHeaders/CNLivePlayerTools.h deleted
100644 → 0
| 1 | -// | |
| 2 | -// CNLivePlayerTools.h | |
| 3 | -// CNLivePlayer_Example | |
| 4 | -// | |
| 5 | -// Created by CNLive-zxw on 2019/7/26. | |
| 6 | -// Copyright © 2019 153993236@qq.com. All rights reserved. | |
| 7 | -// | |
| 8 | - | |
| 9 | -#import <Foundation/Foundation.h> | |
| 10 | - | |
| 11 | -@interface CNLivePlayerTools : NSObject | |
| 12 | - | |
| 13 | -/** | |
| 14 | - * SHA1加密 | |
| 15 | - */ | |
| 16 | -+ (NSString *)encryptionSignWithUrl:(NSString *)url parameter:(NSDictionary *)parameter; | |
| 17 | - | |
| 18 | -+ (NSString *)sha1:(NSString *)string; | |
| 19 | - | |
| 20 | -+ (NSString *)signvalue:(NSDictionary*)parameter; | |
| 21 | - | |
| 22 | -/** | |
| 23 | - * 获取UUID_Timestamp | |
| 24 | - */ | |
| 25 | -+ (NSString *)getUidForTimestamp:(NSString *)timestamp; | |
| 26 | - | |
| 27 | -//错误信息 | |
| 28 | -+ (NSError *)customErrorWithResponseObject:(id)responseObject errorInfo:(NSString *)errorInfo; | |
| 29 | - | |
| 30 | -/** | |
| 31 | - * 验证是是否为是空字符串 | |
| 32 | - */ | |
| 33 | -+ (BOOL)isEmptyString:(NSString *)string; | |
| 34 | - | |
| 35 | -/** | |
| 36 | - * 获取时间戳 | |
| 37 | - */ | |
| 38 | -+ (NSString *)getTimestamp; | |
| 39 | - | |
| 40 | - | |
| 41 | -#pragma mark - 方法 | |
| 42 | -/** | |
| 43 | - * 视频出错,上传接口 | |
| 44 | - */ | |
| 45 | -+ (void)errorStat:(NSString *)errorString contentId:(NSString *)contentId idName:(NSString *)idName; | |
| 46 | - | |
| 47 | -+ (void)statSDKWithContentId:(NSString *)contentId idName:(NSString *)idName; | |
| 48 | - | |
| 49 | -@end |
Example/Products/CNLivePlayer.framework/PrivateHeaders/CNLiveURLRequestSerialization.h deleted
100644 → 0
| 1 | -// | |
| 2 | -// CNLiveURLRequestSerialization.h | |
| 3 | -// CNLivePlayer_Example | |
| 4 | -// | |
| 5 | -// Created by CNLive-zxw on 2019/7/26. | |
| 6 | -// Copyright © 2019 153993236@qq.com. All rights reserved. | |
| 7 | -// | |
| 8 | - | |
| 9 | -#import <Foundation/Foundation.h> | |
| 10 | - | |
| 11 | -NS_ASSUME_NONNULL_BEGIN | |
| 12 | - | |
| 13 | -@interface CNLiveURLRequestSerialization : NSObject | |
| 14 | -+ (nullable NSString *)cn_QueryStringFromParameters:(nullable NSDictionary *)parameters; | |
| 15 | - | |
| 16 | -@end | |
| 17 | - | |
| 18 | -NS_ASSUME_NONNULL_END |
Example/build/Debug-iphoneos/CNLivePlayer/CNLivePlayer.framework/CNLivePlayer deleted
100644 → 0
No preview for this file type
Example/build/Debug-iphoneos/CNLivePlayer/CNLivePlayer.framework/Headers/CNLivePlayer.h deleted
100644 → 0
| 1 | -// | |
| 2 | -// CNLivePlayer.h | |
| 3 | -// CNLivePlayer_Example | |
| 4 | -// | |
| 5 | -// Created by CNLive-zxw on 2019/7/26. | |
| 6 | -// Copyright © 2019 153993236@qq.com. All rights reserved. | |
| 7 | -// | |
| 8 | - | |
| 9 | -#import <Foundation/Foundation.h> | |
| 10 | -#import <libksygpulive/KSYMoviePlayerController.h> | |
| 11 | -#import "KSYMoviePlayerDefines.h" | |
| 12 | - | |
| 13 | -// 枚举定义 | |
| 14 | -#import "CNLivePlayerDefines.h" | |
| 15 | - | |
| 16 | -// 播放器管理类 | |
| 17 | -#import "CNLivePlayerManager.h" | |
| 18 | - | |
| 19 | -//缓存url | |
| 20 | -#import "CNLivePlayerCache.h" | |
| 21 | - | |
| 22 | -NS_ASSUME_NONNULL_BEGIN | |
| 23 | - | |
| 24 | -/* | |
| 25 | - * 获取主播状态通知 | |
| 26 | - */ | |
| 27 | -UIKIT_EXTERN NSString *const CNLiveHostStatusChangedNotification; | |
| 28 | - | |
| 29 | -/* | |
| 30 | - * 成功回调 | |
| 31 | - */ | |
| 32 | -typedef void(^AuthSuccessBlock)(void); | |
| 33 | - | |
| 34 | -/* | |
| 35 | - * 失败回调 | |
| 36 | - */ | |
| 37 | -typedef void(^AuthFailureBlock)(NSDictionary *errorInfo); | |
| 38 | - | |
| 39 | -@interface CNLivePlayer : NSObject | |
| 40 | - | |
| 41 | -/* | |
| 42 | - * 播放器类型 | |
| 43 | - */ | |
| 44 | -@property (nonatomic, assign, readonly) CNLivePlayerType type; | |
| 45 | - | |
| 46 | -/* | |
| 47 | - * 播放器 | |
| 48 | - */ | |
| 49 | -@property (nonatomic, strong) KSYMoviePlayerController *player; | |
| 50 | - | |
| 51 | -#pragma mark - 初始化方法 | |
| 52 | -/* | |
| 53 | - * 初始化播放器并设置播放地址 | |
| 54 | - * | |
| 55 | - * url 视频url | |
| 56 | - * | |
| 57 | - */ | |
| 58 | -- (instancetype)initWithContentURL:(NSURL *)url; | |
| 59 | - | |
| 60 | - | |
| 61 | -/* 初始化点播播放器 初始化成功后才能对播放器进行设置(如:自动播放、是否开启硬件解码等)和调用准备播放视频方法(prepareToPlay) | |
| 62 | - * | |
| 63 | - * videoId 视频Id | |
| 64 | - * authSuccess 初始化成功block | |
| 65 | - * authFailed 初始化失败block 回调一个errorInfo的字典 | |
| 66 | - * | |
| 67 | - */ | |
| 68 | -- (instancetype)initVodPlayerWithVideoId:(NSString *)videoId authSuccess:(AuthSuccessBlock)authSuccessBlock authFailure:(AuthFailureBlock)authFailureBlock; | |
| 69 | - | |
| 70 | - | |
| 71 | -/* 初始化直播播放器(* 以channelId播放) 初始化成功后才能对播放器进行设置(如:自动播放、是否开启硬件解码等)和调用准备播放视频方法(prepareToPlay) | |
| 72 | - * | |
| 73 | - * channelId 直播视频Id (注* 若agree为YES时,必传,用于获取主播状态; 若agree为NO,可不传) | |
| 74 | - * activityId 活动Id | |
| 75 | - * agree 是否允许获取主播状态 YES:获取 NO:不获取 | |
| 76 | - * authSuccess 初始化成功block | |
| 77 | - * authFailed 初始化失败block 回调一个errorInfo的字典 | |
| 78 | - * | |
| 79 | - * result 获取主播状态 YES:获取状态成功 | |
| 80 | - * NO:获取失败,不影响视频播放,但是获取不到主播离开、回来、直播结束等通知。 | |
| 81 | - * 可通过- (void)getHostStatus:(void(^)(BOOL result))result;方法重新获取 | |
| 82 | - */ | |
| 83 | -- (instancetype)initLivePlayerWithChannelId:(NSString *)channelId activityId:(NSString *)activityId hostStatus:(BOOL)agree authSuccess:(AuthSuccessBlock)authSuccessBlock authFailure:(AuthFailureBlock)authFailureBlock getHostStatusResult:(void(^)(BOOL result))result; | |
| 84 | - | |
| 85 | - | |
| 86 | -/* 初始化音频播放器 初始化成功后才能对播放器进行设置(如:自动播放、是否开启硬件解码等)和调用准备播放视频方法(prepareToPlay) | |
| 87 | - * | |
| 88 | - * contentId 音频Id | |
| 89 | - * authSuccess 初始化成功block | |
| 90 | - * authFailed 初始化失败block 回调一个errorInfo的字典 | |
| 91 | - * | |
| 92 | - */ | |
| 93 | -- (instancetype)initAudioPlayerWithAudioId:(NSString *)audioId authSuccess:(AuthSuccessBlock)authSuccessBlock authFailure:(AuthFailureBlock)authFailureBlock; | |
| 94 | - | |
| 95 | -#pragma mark - 属性 | |
| 96 | -/** | |
| 97 | - @abstract 正在播放的视频文件的地址,该地址可以是本地地址或者服务器地址。 | |
| 98 | - */ | |
| 99 | -@property (nonatomic, readonly) NSURL *contentURL; | |
| 100 | - | |
| 101 | -/** | |
| 102 | - @abstract 包含视频播放内容的VIEW(只读)。 | |
| 103 | - @discussion view的使用逻辑: | |
| 104 | - | |
| 105 | - * 可以通过frame设置view大大小 | |
| 106 | - * 使用[scalingMode]([KSYMoviePlayerController scalingMode]) 可以更改视频内容在VIEW中的显示情况 | |
| 107 | - | |
| 108 | - @see scalingMode | |
| 109 | - */ | |
| 110 | -// The view in which the media and playback controls are displayed. | |
| 111 | -@property (nonatomic, strong, readonly) UIView *view; | |
| 112 | - | |
| 113 | -/* | |
| 114 | - * 主播直播状态(只读) | |
| 115 | - */ | |
| 116 | -@property (nonatomic, assign, readonly) CNLiveHostStatus hostStatus; | |
| 117 | - | |
| 118 | -/** | |
| 119 | - @abstract 是否静音 | |
| 120 | - @discussion | |
| 121 | - * 默认不静音 | |
| 122 | - * [prepareToPlay]方法前设置即生效,也可以在播放过程中动态切换 | |
| 123 | - */ | |
| 124 | -@property (nonatomic) BOOL shouldMute; | |
| 125 | - | |
| 126 | -/** | |
| 127 | - @abstract 是否循环播放 | |
| 128 | - @discussion 默认不循环 | |
| 129 | - * 只在[prepareToPlay]调用前设置生效; | |
| 130 | - * 只有点播生效,直播场景请勿设置 | |
| 131 | - */ | |
| 132 | -@property (nonatomic) BOOL shouldLoop; | |
| 133 | - | |
| 134 | -/** | |
| 135 | - @abstract 指定逆时针旋转角度,只能是0/90/180/270, 不符合上述值不进行旋转 | |
| 136 | - */ | |
| 137 | -@property (nonatomic, assign) int rotateDegress; | |
| 138 | - | |
| 139 | -/** | |
| 140 | - @abstract 是否打断其他后台的音乐播放 | |
| 141 | - @discussion 也可以理解为是否允许和其他音频同时播放 | |
| 142 | - @discussion YES:开始播放时,会打断其他的后台播放音频,也会被其他音频播放打断 | |
| 143 | - @discussion NO: 可以与其他后台播放共存,相互之间不会被打断 | |
| 144 | - @discussion 默认为YES | |
| 145 | - */ | |
| 146 | -@property (nonatomic) BOOL bInterruptOtherAudio; | |
| 147 | - | |
| 148 | -/* | |
| 149 | - * 查询视频准备是否完成(只读) | |
| 150 | - */ | |
| 151 | -@property (nonatomic, readonly) BOOL isPreparedToPlay; | |
| 152 | - | |
| 153 | -#pragma mark - 方法 | |
| 154 | -/* | |
| 155 | - * 获取主播状态(离开/已结束) | |
| 156 | - */ | |
| 157 | -- (void)getHostStatus:(void(^)(BOOL result))result; | |
| 158 | - | |
| 159 | -/* 给播放器设置内容id 设置成功后才能播放(如:自动播放、是否开启硬件解码等)和调用准备播放视频方法(prepareToPlay) | |
| 160 | - * 切换视频 | |
| 161 | - * contentId 内容Id | |
| 162 | - * type 内容类型 | |
| 163 | - * | |
| 164 | - */ | |
| 165 | -- (void)setPlayerWithContentId:(NSString *)contentId type:(CNLivePlayerType)type authSuccess:(AuthSuccessBlock)authSuccessBlock authFailure:(AuthFailureBlock)authFailureBlock; | |
| 166 | - | |
| 167 | -/* | |
| 168 | - * 销毁播放器 | |
| 169 | - */ | |
| 170 | -- (void)destroyPlayer; | |
| 171 | - | |
| 172 | -/* | |
| 173 | - * 准备视频播放 | |
| 174 | - * MPMediaPlaybackIsPreparedToPlayDidChangeNotification 播放器完成对视频文件的初始化时发送通知 | |
| 175 | - */ | |
| 176 | -- (void)prepareToPlay; | |
| 177 | - | |
| 178 | -/* | |
| 179 | - * 视频播放 | |
| 180 | - */ | |
| 181 | -- (void)play; | |
| 182 | - | |
| 183 | -/* | |
| 184 | - * 当前播放器是否在播放 | |
| 185 | - */ | |
| 186 | -- (BOOL)isPlaying; | |
| 187 | - | |
| 188 | -/* | |
| 189 | - * 视频暂停 | |
| 190 | - */ | |
| 191 | -- (void)pause; | |
| 192 | - | |
| 193 | -/* | |
| 194 | - * 视频停止 | |
| 195 | - */ | |
| 196 | -- (void)stop; | |
| 197 | - | |
| 198 | -/* | |
| 199 | - * 视频截图 | |
| 200 | - */ | |
| 201 | -- (UIImage *)thumbnailImageAtCurrentTime; | |
| 202 | - | |
| 203 | -@end | |
| 204 | - | |
| 205 | -NS_ASSUME_NONNULL_END |
Example/build/Debug-iphoneos/CNLivePlayer/CNLivePlayer.framework/Headers/CNLivePlayerCache.h deleted
100644 → 0
| 1 | -// | |
| 2 | -// CNLivePlayerCache.h | |
| 3 | -// CNLivePlayer_Example | |
| 4 | -// | |
| 5 | -// Created by CNLive-zxw on 2019/7/26. | |
| 6 | -// Copyright © 2019 153993236@qq.com. All rights reserved. | |
| 7 | -// | |
| 8 | - | |
| 9 | -#import <Foundation/Foundation.h> | |
| 10 | - | |
| 11 | -NS_ASSUME_NONNULL_BEGIN | |
| 12 | - | |
| 13 | -@interface CNLivePlayerCache : NSObject | |
| 14 | - | |
| 15 | -/** | |
| 16 | - * 存储或者修改数据 | |
| 17 | - * | |
| 18 | - * @param data 保存的数据 | |
| 19 | - * @param key 保存的key | |
| 20 | - */ | |
| 21 | -+ (void)player_SaveDataCache:(id)data forKey:(NSString *)key; | |
| 22 | - | |
| 23 | - | |
| 24 | -/** | |
| 25 | - * 读取数据 | |
| 26 | - * | |
| 27 | - * @param key 保存的key | |
| 28 | - * | |
| 29 | - * @return 返回id | |
| 30 | - */ | |
| 31 | -+ (id)player_ReadCache:(NSString *)key; | |
| 32 | - | |
| 33 | - | |
| 34 | -/** | |
| 35 | - * 读取缓存文件的大小 | |
| 36 | - * | |
| 37 | - * @return 返回NSString | |
| 38 | - */ | |
| 39 | -+ (NSString *)player_GetAllHttpCacheSize; | |
| 40 | - | |
| 41 | - | |
| 42 | -/** | |
| 43 | - * 是否缓存过 | |
| 44 | - * | |
| 45 | - * @param key 保存的key | |
| 46 | - * | |
| 47 | - * @return 返回NSString | |
| 48 | - */ | |
| 49 | -+ (BOOL)player_IsCache:(NSString *)key; | |
| 50 | - | |
| 51 | - | |
| 52 | -/** | |
| 53 | - * 删除某个磁盘缓存文件 | |
| 54 | - * | |
| 55 | - * @param key 保存的key(就是请求的url) | |
| 56 | - * | |
| 57 | - */ | |
| 58 | -+ (void)player_RemoveChache:(NSString *)key; | |
| 59 | - | |
| 60 | - | |
| 61 | -/** | |
| 62 | - * 磁盘最大缓存开销 | |
| 63 | - * 默认是30*1024*1024 | |
| 64 | - */ | |
| 65 | -+ (void)player_SetCostLimit:(NSInteger)costLimit; | |
| 66 | - | |
| 67 | - | |
| 68 | -/** | |
| 69 | - * 删除所有的磁盘缓存url(YYCache) | |
| 70 | - */ | |
| 71 | -+ (void)player_RemoveAllUrlCache; | |
| 72 | - | |
| 73 | - | |
| 74 | -/** | |
| 75 | - * 删除所有的磁盘缓存url(YYCache) | |
| 76 | - * 删除所有的磁盘缓存视频(KSYHTTPProxyService) | |
| 77 | - */ | |
| 78 | -+ (void)player_clearAllCache; | |
| 79 | - | |
| 80 | -@end | |
| 81 | - | |
| 82 | -NS_ASSUME_NONNULL_END |
Example/build/Debug-iphoneos/CNLivePlayer/CNLivePlayer.framework/Headers/CNLivePlayerDefines.h deleted
100644 → 0
| 1 | -// | |
| 2 | -// CNLivePlayerDefines.h | |
| 3 | -// CNLivePlayer | |
| 4 | -// | |
| 5 | -// Created by CNLive-zxw on 2019/8/14. | |
| 6 | -// Copyright © 2019 153993236@qq.com. All rights reserved. | |
| 7 | -// | |
| 8 | - | |
| 9 | -#ifndef CNLivePlayerDefines_h | |
| 10 | -#define CNLivePlayerDefines_h | |
| 11 | - | |
| 12 | -/* | |
| 13 | - * 播放器类型 | |
| 14 | - */ | |
| 15 | -typedef NS_ENUM(NSUInteger, CNLivePlayerType) { | |
| 16 | - CNLivePlayerVod, //点播 | |
| 17 | - CNLivePlayerLive, //直播 | |
| 18 | - CNLivePlayerAudio //音频 | |
| 19 | - | |
| 20 | -}; | |
| 21 | - | |
| 22 | -/** | |
| 23 | - * 主播直播状态 | |
| 24 | - */ | |
| 25 | -typedef NS_ENUM(NSUInteger, CNLiveHostStatus) { | |
| 26 | - //主播直播中 | |
| 27 | - CNLiveHostStatusLiving = 1, | |
| 28 | - //直播已结束 | |
| 29 | - CNLiveHostStatusEnd = 2, | |
| 30 | - //主播已离开 | |
| 31 | - CNLiveHostStatusLeaving = 3 | |
| 32 | - | |
| 33 | -}; | |
| 34 | - | |
| 35 | -#endif /* CNLivePlayerDefines_h */ |
Example/build/Debug-iphoneos/CNLivePlayer/CNLivePlayer.framework/Headers/CNLivePlayerManager.h deleted
100644 → 0
| 1 | -// | |
| 2 | -// CNLivePlayerManager.h | |
| 3 | -// CNLivePlayer_Example | |
| 4 | -// | |
| 5 | -// Created by CNLive-zxw on 2019/7/26. | |
| 6 | -// Copyright © 2019 153993236@qq.com. All rights reserved. | |
| 7 | -// | |
| 8 | - | |
| 9 | -#import <Foundation/Foundation.h> | |
| 10 | - | |
| 11 | -#define PLAYER_AppID [CNLivePlayerManager manager].appId?[CNLivePlayerManager manager].appId:@"" | |
| 12 | -#define PLAYER_AppKey [CNLivePlayerManager manager].appKey?[CNLivePlayerManager manager].appKey:@"" | |
| 13 | -#define PLAYER_UserId [CNLivePlayerManager manager].userId?[CNLivePlayerManager manager].userId:@"" | |
| 14 | -#define PLAYER_ChannelName [CNLivePlayerManager manager].channelName?[CNLivePlayerManager manager].channelName:@"" | |
| 15 | -#define PLAYER_Tag [CNLivePlayerManager manager].tag?[CNLivePlayerManager manager].tag:@"" | |
| 16 | -#define PLAYER_TestEnvironment [CNLivePlayerManager manager].isTestEnvironment | |
| 17 | - | |
| 18 | -NS_ASSUME_NONNULL_BEGIN | |
| 19 | - | |
| 20 | -@interface CNLivePlayerManager : NSObject | |
| 21 | -+ (CNLivePlayerManager *)manager; | |
| 22 | - | |
| 23 | -/** | |
| 24 | - * 应用ID(只读) | |
| 25 | - */ | |
| 26 | -@property (nonatomic, copy, readonly) NSString *appId; | |
| 27 | - | |
| 28 | -/** | |
| 29 | - * 应用KEY(只读) | |
| 30 | - */ | |
| 31 | -@property (nonatomic, copy, readonly) NSString *appKey; | |
| 32 | - | |
| 33 | -/** | |
| 34 | - * 是否是测试环境 | |
| 35 | - */ | |
| 36 | -@property (nonatomic, assign, readonly) BOOL isTestEnvironment; | |
| 37 | - | |
| 38 | -/** | |
| 39 | - * 用户ID | |
| 40 | - */ | |
| 41 | -@property (nonatomic, copy) NSString *userId; | |
| 42 | - | |
| 43 | -/** | |
| 44 | - * ChannelName 网++定制 | |
| 45 | - */ | |
| 46 | -@property (nonatomic, copy) NSString *channelName; | |
| 47 | - | |
| 48 | -/** | |
| 49 | - * tag 网++定制 | |
| 50 | - */ | |
| 51 | -@property (nonatomic, copy) NSString *tag; | |
| 52 | - | |
| 53 | -/** | |
| 54 | - * from 网++定制 | |
| 55 | - */ | |
| 56 | -@property (nonatomic, copy) NSString *from; | |
| 57 | - | |
| 58 | -/** | |
| 59 | - @abstract 初始化直播云SDK(该方法默认正式环境) | |
| 60 | - @param appId 在open.cnlive.com网站申请得到的appId | |
| 61 | - @param appKey 在open.cnlive.com网站申请得到的appKey | |
| 62 | - @warning 必传参数 | |
| 63 | - */ | |
| 64 | -+ (void)setAppId:(NSString *)appId appKey:(NSString *)appKey; | |
| 65 | - | |
| 66 | -/** | |
| 67 | - @abstract 初始化直播云SDK | |
| 68 | - @param appId 在open.cnlive.com网站申请得到的appId | |
| 69 | - @param appKey 在open.cnlive.com网站申请得到的appKey | |
| 70 | - @param isTestEnvironment YES:测试环境 NO:正式环境 | |
| 71 | - @warning 必传参数 | |
| 72 | - */ | |
| 73 | -+ (void)setAppId:(NSString *)appId appKey:(NSString *)appKey isTestEnvironment:(BOOL)isTestEnvironment; | |
| 74 | - | |
| 75 | -/** | |
| 76 | - @abstract 获取版本号 | |
| 77 | - */ | |
| 78 | -+ (NSString *)getVersion; | |
| 79 | - | |
| 80 | - | |
| 81 | -@end | |
| 82 | - | |
| 83 | -NS_ASSUME_NONNULL_END |
Example/build/Debug-iphoneos/CNLivePlayer/CNLivePlayer.framework/Info.plist deleted
100644 → 0
No preview for this file type
Example/build/Debug-iphoneos/CNLivePlayer/CNLivePlayer.framework/Modules/module.modulemap deleted
100644 → 0
Example/build/Debug-iphoneos/CNLivePlayer/CNLivePlayer.framework/PrivateHeaders/CNLivePlayer-umbrella.h deleted
100644 → 0
| 1 | -#ifdef __OBJC__ | |
| 2 | -#import <UIKit/UIKit.h> | |
| 3 | -#else | |
| 4 | -#ifndef FOUNDATION_EXPORT | |
| 5 | -#if defined(__cplusplus) | |
| 6 | -#define FOUNDATION_EXPORT extern "C" | |
| 7 | -#else | |
| 8 | -#define FOUNDATION_EXPORT extern | |
| 9 | -#endif | |
| 10 | -#endif | |
| 11 | -#endif | |
| 12 | - | |
| 13 | -#import "CNLivePlayer.h" | |
| 14 | -#import "CNLivePlayerConst.h" | |
| 15 | -#import "CNLivePlayerDefines.h" | |
| 16 | -#import "CNLivePlayerManager.h" | |
| 17 | -#import "CNLivePlayerCache.h" | |
| 18 | -#import "CNLivePlayerCache.h" | |
| 19 | -#import "CNLivePlayerNetworkManager.h" | |
| 20 | -#import "CNLiveURLRequestSerialization.h" | |
| 21 | -#import "CNLivePlayer.h" | |
| 22 | -#import "CNLivePlayerConst.h" | |
| 23 | -#import "CNLivePlayerDefines.h" | |
| 24 | -#import "CNLivePlayerManager.h" | |
| 25 | -#import "CNLivePlayerTools.h" | |
| 26 | - | |
| 27 | -FOUNDATION_EXPORT double CNLivePlayerVersionNumber; | |
| 28 | -FOUNDATION_EXPORT const unsigned char CNLivePlayerVersionString[]; | |
| 29 | - |
Example/build/Debug-iphoneos/CNLivePlayer/CNLivePlayer.framework/PrivateHeaders/CNLivePlayerConst.h deleted
100644 → 0
| 1 | -// | |
| 2 | -// CNLivePlayerConst.h | |
| 3 | -// CNLivePlayer | |
| 4 | -// | |
| 5 | -// Created by CNLive-zxw on 2019/8/14. | |
| 6 | -// Copyright © 2019 153993236@qq.com. All rights reserved. | |
| 7 | -// | |
| 8 | - | |
| 9 | -#ifndef CNLivePlayerConst_h | |
| 10 | -#define CNLivePlayerConst_h | |
| 11 | - | |
| 12 | -#pragma mark - 版本号 | |
| 13 | -#define PlayerSDKVersion @"0.0.1" //播放器SDK版本 | |
| 14 | - | |
| 15 | -#pragma mark - 探针 | |
| 16 | -#define StatUrl [CNLivePlayerManager manager].isTestEnvironment?@"http://app.sta.cnlive.com/app.jpg": @"http://app.sta.cnlive.com/app.jpg" | |
| 17 | -#define StatVersion @"4.0" //探针版本 | |
| 18 | -#define StatAppVersion ([[[NSBundle mainBundle] infoDictionary] objectForKey: @"CFBundleShortVersionString"]) | |
| 19 | - | |
| 20 | -#pragma mark - 鉴权 | |
| 21 | -#define authUrl [NSString stringWithFormat:@"%@/platform/valid", [CNLivePlayerManager manager].isTestEnvironment ? @"http://test.open.cnlive.com/openapi/api2" : @"http://api.cnlive.com/open/api2"] | |
| 22 | - | |
| 23 | -#pragma mark - 点播 | |
| 24 | -#define vodUrl [CNLivePlayerManager manager].isTestEnvironment ? @"http://test.open.cnlive.com/openapi/api2/vod_ips/vodplayByAPP":@"http://api.cnlive.com/open/api2/vod_ips/vodplayByAPP" | |
| 25 | - | |
| 26 | -#pragma mark - 直播 | |
| 27 | -#define liveUrl [CNLivePlayerManager manager].isTestEnvironment ? @"http://test.open.cnlive.com/openapi/api2/live_ips/liveplayByAPP":@"http://api.cnlive.com/open/api2/live_ips/liveplayByAPP" | |
| 28 | - | |
| 29 | -#endif /* CNLivePlayerConst_h */ |
Example/build/Debug-iphoneos/CNLivePlayer/CNLivePlayer.framework/PrivateHeaders/CNLivePlayerNetworkManager.h deleted
100644 → 0
| 1 | -// | |
| 2 | -// CNLivePlayerNetworkManager.h | |
| 3 | -// CNLivePlayer_Example | |
| 4 | -// | |
| 5 | -// Created by CNLive-zxw on 2019/7/26. | |
| 6 | -// Copyright © 2019 153993236@qq.com. All rights reserved. | |
| 7 | -// | |
| 8 | - | |
| 9 | -#import <Foundation/Foundation.h> | |
| 10 | - | |
| 11 | -NS_ASSUME_NONNULL_BEGIN | |
| 12 | -typedef void(^GetVideoURLSuccessBlock)(NSString * _Nullable videoURL, NSInteger code); | |
| 13 | - | |
| 14 | -@interface CNLivePlayerNetworkManager : NSObject | |
| 15 | -/** | |
| 16 | - * 设置超时时间 | |
| 17 | - */ | |
| 18 | -@property (nonatomic, assign) NSTimeInterval timeoutInterval; | |
| 19 | - | |
| 20 | -/** | |
| 21 | - * 缓存策略 | |
| 22 | - */ | |
| 23 | -@property (nonatomic, assign) NSURLRequestCachePolicy cachePolicy; | |
| 24 | - | |
| 25 | -+ (CNLivePlayerNetworkManager *)manager; | |
| 26 | - | |
| 27 | -/** | |
| 28 | - * GET 请求 | |
| 29 | - * @param URL url | |
| 30 | - * @param parameters 上传参数 | |
| 31 | - * @param success 请求成功回调 | |
| 32 | - * @param failure 请求失败回调 | |
| 33 | - */ | |
| 34 | -+ (void)GET:(nullable NSString *)URL parameters:(nullable NSDictionary *)parameters success:(nullable void (^)(NSURLResponse *_Nullable response, id _Nullable responseObject))success failure:(nullable void (^)(NSURLResponse *_Nullable response, NSError *_Nullable error))failure; | |
| 35 | - | |
| 36 | -/** | |
| 37 | - * POST 请求 | |
| 38 | - * @param URL url | |
| 39 | - * @param parameters 上传参数 | |
| 40 | - * @param success 请求成功回调 | |
| 41 | - * @param failure 请求失败回调 | |
| 42 | - */ | |
| 43 | -+ (void)POST:(nullable NSString *)URL parameters:(nullable NSDictionary *)parameters success:(nullable void (^)(NSURLResponse *_Nullable response, id _Nullable responseObject))success failure:(nullable void (^)(NSURLResponse *_Nullable response, NSError *_Nullable error))failure; | |
| 44 | - | |
| 45 | - | |
| 46 | -#pragma mark - 针对具体业务 | |
| 47 | -/** | |
| 48 | - * 鉴权 | |
| 49 | - */ | |
| 50 | -- (void)authenticate:(NSString *)URL success:(void (^)(NSURLResponse * _Nullable, id _Nullable))success failure:(void (^)(NSURLResponse * _Nullable, NSError * _Nullable))failure; | |
| 51 | - | |
| 52 | -/** | |
| 53 | - * 获取视频url | |
| 54 | - */ | |
| 55 | -+ (void)getVideoURL:(nullable NSString *)URL success:(GetVideoURLSuccessBlock)success; | |
| 56 | - | |
| 57 | - | |
| 58 | -@end | |
| 59 | - | |
| 60 | -NS_ASSUME_NONNULL_END |
Example/build/Debug-iphoneos/CNLivePlayer/CNLivePlayer.framework/PrivateHeaders/CNLivePlayerTools.h deleted
100644 → 0
| 1 | -// | |
| 2 | -// CNLivePlayerTools.h | |
| 3 | -// CNLivePlayer_Example | |
| 4 | -// | |
| 5 | -// Created by CNLive-zxw on 2019/7/26. | |
| 6 | -// Copyright © 2019 153993236@qq.com. All rights reserved. | |
| 7 | -// | |
| 8 | - | |
| 9 | -#import <Foundation/Foundation.h> | |
| 10 | - | |
| 11 | -@interface CNLivePlayerTools : NSObject | |
| 12 | - | |
| 13 | -/** | |
| 14 | - * SHA1加密 | |
| 15 | - */ | |
| 16 | -+ (NSString *)encryptionSignWithUrl:(NSString *)url parameter:(NSDictionary *)parameter; | |
| 17 | - | |
| 18 | -+ (NSString *)sha1:(NSString *)string; | |
| 19 | - | |
| 20 | -+ (NSString *)signvalue:(NSDictionary*)parameter; | |
| 21 | - | |
| 22 | -/** | |
| 23 | - * 获取UUID_Timestamp | |
| 24 | - */ | |
| 25 | -+ (NSString *)getUidForTimestamp:(NSString *)timestamp; | |
| 26 | - | |
| 27 | -//错误信息 | |
| 28 | -+ (NSError *)customErrorWithResponseObject:(id)responseObject errorInfo:(NSString *)errorInfo; | |
| 29 | - | |
| 30 | -/** | |
| 31 | - * 验证是是否为是空字符串 | |
| 32 | - */ | |
| 33 | -+ (BOOL)isEmptyString:(NSString *)string; | |
| 34 | - | |
| 35 | -/** | |
| 36 | - * 获取时间戳 | |
| 37 | - */ | |
| 38 | -+ (NSString *)getTimestamp; | |
| 39 | - | |
| 40 | - | |
| 41 | -#pragma mark - 方法 | |
| 42 | -/** | |
| 43 | - * 视频出错,上传接口 | |
| 44 | - */ | |
| 45 | -+ (void)errorStat:(NSString *)errorString contentId:(NSString *)contentId idName:(NSString *)idName; | |
| 46 | - | |
| 47 | -+ (void)statSDKWithContentId:(NSString *)contentId idName:(NSString *)idName; | |
| 48 | - | |
| 49 | -@end |
Example/build/Debug-iphoneos/CNLivePlayer/CNLivePlayer.framework/PrivateHeaders/CNLiveURLRequestSerialization.h deleted
100644 → 0
| 1 | -// | |
| 2 | -// CNLiveURLRequestSerialization.h | |
| 3 | -// CNLivePlayer_Example | |
| 4 | -// | |
| 5 | -// Created by CNLive-zxw on 2019/7/26. | |
| 6 | -// Copyright © 2019 153993236@qq.com. All rights reserved. | |
| 7 | -// | |
| 8 | - | |
| 9 | -#import <Foundation/Foundation.h> | |
| 10 | - | |
| 11 | -NS_ASSUME_NONNULL_BEGIN | |
| 12 | - | |
| 13 | -@interface CNLiveURLRequestSerialization : NSObject | |
| 14 | -+ (nullable NSString *)cn_QueryStringFromParameters:(nullable NSDictionary *)parameters; | |
| 15 | - | |
| 16 | -@end | |
| 17 | - | |
| 18 | -NS_ASSUME_NONNULL_END |
Example/build/Debug-iphoneos/CocoaAsyncSocket/CocoaAsyncSocket.framework/CocoaAsyncSocket deleted
100755 → 0
No preview for this file type
Example/build/Debug-iphoneos/CocoaAsyncSocket/CocoaAsyncSocket.framework/Headers/CocoaAsyncSocket-umbrella.h deleted
100644 → 0
| 1 | -#ifdef __OBJC__ | |
| 2 | -#import <UIKit/UIKit.h> | |
| 3 | -#else | |
| 4 | -#ifndef FOUNDATION_EXPORT | |
| 5 | -#if defined(__cplusplus) | |
| 6 | -#define FOUNDATION_EXPORT extern "C" | |
| 7 | -#else | |
| 8 | -#define FOUNDATION_EXPORT extern | |
| 9 | -#endif | |
| 10 | -#endif | |
| 11 | -#endif | |
| 12 | - | |
| 13 | -#import "GCDAsyncSocket.h" | |
| 14 | -#import "GCDAsyncUdpSocket.h" | |
| 15 | - | |
| 16 | -FOUNDATION_EXPORT double CocoaAsyncSocketVersionNumber; | |
| 17 | -FOUNDATION_EXPORT const unsigned char CocoaAsyncSocketVersionString[]; | |
| 18 | - |
Example/build/Debug-iphoneos/CocoaAsyncSocket/CocoaAsyncSocket.framework/Headers/GCDAsyncSocket.h deleted
100644 → 0
| 1 | -// | |
| 2 | -// GCDAsyncSocket.h | |
| 3 | -// | |
| 4 | -// This class is in the public domain. | |
| 5 | -// Originally created by Robbie Hanson in Q3 2010. | |
| 6 | -// Updated and maintained by Deusty LLC and the Apple development community. | |
| 7 | -// | |
| 8 | -// https://github.com/robbiehanson/CocoaAsyncSocket | |
| 9 | -// | |
| 10 | - | |
| 11 | -#import <Foundation/Foundation.h> | |
| 12 | -#import <Security/Security.h> | |
| 13 | -#import <Security/SecureTransport.h> | |
| 14 | -#import <dispatch/dispatch.h> | |
| 15 | -#import <Availability.h> | |
| 16 | - | |
| 17 | -#include <sys/socket.h> // AF_INET, AF_INET6 | |
| 18 | - | |
| 19 | -@class GCDAsyncReadPacket; | |
| 20 | -@class GCDAsyncWritePacket; | |
| 21 | -@class GCDAsyncSocketPreBuffer; | |
| 22 | -@protocol GCDAsyncSocketDelegate; | |
| 23 | - | |
| 24 | -NS_ASSUME_NONNULL_BEGIN | |
| 25 | - | |
| 26 | -extern NSString *const GCDAsyncSocketException; | |
| 27 | -extern NSString *const GCDAsyncSocketErrorDomain; | |
| 28 | - | |
| 29 | -extern NSString *const GCDAsyncSocketQueueName; | |
| 30 | -extern NSString *const GCDAsyncSocketThreadName; | |
| 31 | - | |
| 32 | -extern NSString *const GCDAsyncSocketManuallyEvaluateTrust; | |
| 33 | -#if TARGET_OS_IPHONE | |
| 34 | -extern NSString *const GCDAsyncSocketUseCFStreamForTLS; | |
| 35 | -#endif | |
| 36 | -#define GCDAsyncSocketSSLPeerName (NSString *)kCFStreamSSLPeerName | |
| 37 | -#define GCDAsyncSocketSSLCertificates (NSString *)kCFStreamSSLCertificates | |
| 38 | -#define GCDAsyncSocketSSLIsServer (NSString *)kCFStreamSSLIsServer | |
| 39 | -extern NSString *const GCDAsyncSocketSSLPeerID; | |
| 40 | -extern NSString *const GCDAsyncSocketSSLProtocolVersionMin; | |
| 41 | -extern NSString *const GCDAsyncSocketSSLProtocolVersionMax; | |
| 42 | -extern NSString *const GCDAsyncSocketSSLSessionOptionFalseStart; | |
| 43 | -extern NSString *const GCDAsyncSocketSSLSessionOptionSendOneByteRecord; | |
| 44 | -extern NSString *const GCDAsyncSocketSSLCipherSuites; | |
| 45 | -#if !TARGET_OS_IPHONE | |
| 46 | -extern NSString *const GCDAsyncSocketSSLDiffieHellmanParameters; | |
| 47 | -#endif | |
| 48 | - | |
| 49 | -#define GCDAsyncSocketLoggingContext 65535 | |
| 50 | - | |
| 51 | - | |
| 52 | -typedef NS_ENUM(NSInteger, GCDAsyncSocketError) { | |
| 53 | - GCDAsyncSocketNoError = 0, // Never used | |
| 54 | - GCDAsyncSocketBadConfigError, // Invalid configuration | |
| 55 | - GCDAsyncSocketBadParamError, // Invalid parameter was passed | |
| 56 | - GCDAsyncSocketConnectTimeoutError, // A connect operation timed out | |
| 57 | - GCDAsyncSocketReadTimeoutError, // A read operation timed out | |
| 58 | - GCDAsyncSocketWriteTimeoutError, // A write operation timed out | |
| 59 | - GCDAsyncSocketReadMaxedOutError, // Reached set maxLength without completing | |
| 60 | - GCDAsyncSocketClosedError, // The remote peer closed the connection | |
| 61 | - GCDAsyncSocketOtherError, // Description provided in userInfo | |
| 62 | -}; | |
| 63 | - | |
| 64 | -//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | |
| 65 | -#pragma mark - | |
| 66 | -//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | |
| 67 | - | |
| 68 | - | |
| 69 | -@interface GCDAsyncSocket : NSObject | |
| 70 | - | |
| 71 | -/** | |
| 72 | - * GCDAsyncSocket uses the standard delegate paradigm, | |
| 73 | - * but executes all delegate callbacks on a given delegate dispatch queue. | |
| 74 | - * This allows for maximum concurrency, while at the same time providing easy thread safety. | |
| 75 | - * | |
| 76 | - * You MUST set a delegate AND delegate dispatch queue before attempting to | |
| 77 | - * use the socket, or you will get an error. | |
| 78 | - * | |
| 79 | - * The socket queue is optional. | |
| 80 | - * If you pass NULL, GCDAsyncSocket will automatically create it's own socket queue. | |
| 81 | - * If you choose to provide a socket queue, the socket queue must not be a concurrent queue. | |
| 82 | - * If you choose to provide a socket queue, and the socket queue has a configured target queue, | |
| 83 | - * then please see the discussion for the method markSocketQueueTargetQueue. | |
| 84 | - * | |
| 85 | - * The delegate queue and socket queue can optionally be the same. | |
| 86 | -**/ | |
| 87 | -- (instancetype)init; | |
| 88 | -- (instancetype)initWithSocketQueue:(nullable dispatch_queue_t)sq; | |
| 89 | -- (instancetype)initWithDelegate:(nullable id<GCDAsyncSocketDelegate>)aDelegate delegateQueue:(nullable dispatch_queue_t)dq; | |
| 90 | -- (instancetype)initWithDelegate:(nullable id<GCDAsyncSocketDelegate>)aDelegate delegateQueue:(nullable dispatch_queue_t)dq socketQueue:(nullable dispatch_queue_t)sq; | |
| 91 | - | |
| 92 | -/** | |
| 93 | - * Create GCDAsyncSocket from already connect BSD socket file descriptor | |
| 94 | -**/ | |
| 95 | -+ (nullable instancetype)socketFromConnectedSocketFD:(int)socketFD socketQueue:(nullable dispatch_queue_t)sq error:(NSError**)error; | |
| 96 | - | |
| 97 | -+ (nullable instancetype)socketFromConnectedSocketFD:(int)socketFD delegate:(nullable id<GCDAsyncSocketDelegate>)aDelegate delegateQueue:(nullable dispatch_queue_t)dq error:(NSError**)error; | |
| 98 | - | |
| 99 | -+ (nullable instancetype)socketFromConnectedSocketFD:(int)socketFD delegate:(nullable id<GCDAsyncSocketDelegate>)aDelegate delegateQueue:(nullable dispatch_queue_t)dq socketQueue:(nullable dispatch_queue_t)sq error:(NSError **)error; | |
| 100 | - | |
| 101 | -#pragma mark Configuration | |
| 102 | - | |
| 103 | -@property (atomic, weak, readwrite, nullable) id<GCDAsyncSocketDelegate> delegate; | |
| 104 | -#if OS_OBJECT_USE_OBJC | |
| 105 | -@property (atomic, strong, readwrite, nullable) dispatch_queue_t delegateQueue; | |
| 106 | -#else | |
| 107 | -@property (atomic, assign, readwrite, nullable) dispatch_queue_t delegateQueue; | |
| 108 | -#endif | |
| 109 | - | |
| 110 | -- (void)getDelegate:(id<GCDAsyncSocketDelegate> __nullable * __nullable)delegatePtr delegateQueue:(dispatch_queue_t __nullable * __nullable)delegateQueuePtr; | |
| 111 | -- (void)setDelegate:(nullable id<GCDAsyncSocketDelegate>)delegate delegateQueue:(nullable dispatch_queue_t)delegateQueue; | |
| 112 | - | |
| 113 | -/** | |
| 114 | - * If you are setting the delegate to nil within the delegate's dealloc method, | |
| 115 | - * you may need to use the synchronous versions below. | |
| 116 | -**/ | |
| 117 | -- (void)synchronouslySetDelegate:(nullable id<GCDAsyncSocketDelegate>)delegate; | |
| 118 | -- (void)synchronouslySetDelegateQueue:(nullable dispatch_queue_t)delegateQueue; | |
| 119 | -- (void)synchronouslySetDelegate:(nullable id<GCDAsyncSocketDelegate>)delegate delegateQueue:(nullable dispatch_queue_t)delegateQueue; | |
| 120 | - | |
| 121 | -/** | |
| 122 | - * By default, both IPv4 and IPv6 are enabled. | |
| 123 | - * | |
| 124 | - * For accepting incoming connections, this means GCDAsyncSocket automatically supports both protocols, | |
| 125 | - * and can simulataneously accept incoming connections on either protocol. | |
| 126 | - * | |
| 127 | - * For outgoing connections, this means GCDAsyncSocket can connect to remote hosts running either protocol. | |
| 128 | - * If a DNS lookup returns only IPv4 results, GCDAsyncSocket will automatically use IPv4. | |
| 129 | - * If a DNS lookup returns only IPv6 results, GCDAsyncSocket will automatically use IPv6. | |
| 130 | - * If a DNS lookup returns both IPv4 and IPv6 results, the preferred protocol will be chosen. | |
| 131 | - * By default, the preferred protocol is IPv4, but may be configured as desired. | |
| 132 | -**/ | |
| 133 | - | |
| 134 | -@property (atomic, assign, readwrite, getter=isIPv4Enabled) BOOL IPv4Enabled; | |
| 135 | -@property (atomic, assign, readwrite, getter=isIPv6Enabled) BOOL IPv6Enabled; | |
| 136 | - | |
| 137 | -@property (atomic, assign, readwrite, getter=isIPv4PreferredOverIPv6) BOOL IPv4PreferredOverIPv6; | |
| 138 | - | |
| 139 | -/** | |
| 140 | - * When connecting to both IPv4 and IPv6 using Happy Eyeballs (RFC 6555) https://tools.ietf.org/html/rfc6555 | |
| 141 | - * this is the delay between connecting to the preferred protocol and the fallback protocol. | |
| 142 | - * | |
| 143 | - * Defaults to 300ms. | |
| 144 | -**/ | |
| 145 | -@property (atomic, assign, readwrite) NSTimeInterval alternateAddressDelay; | |
| 146 | - | |
| 147 | -/** | |
| 148 | - * User data allows you to associate arbitrary information with the socket. | |
| 149 | - * This data is not used internally by socket in any way. | |
| 150 | -**/ | |
| 151 | -@property (atomic, strong, readwrite, nullable) id userData; | |
| 152 | - | |
| 153 | -#pragma mark Accepting | |
| 154 | - | |
| 155 | -/** | |
| 156 | - * Tells the socket to begin listening and accepting connections on the given port. | |
| 157 | - * When a connection is accepted, a new instance of GCDAsyncSocket will be spawned to handle it, | |
| 158 | - * and the socket:didAcceptNewSocket: delegate method will be invoked. | |
| 159 | - * | |
| 160 | - * The socket will listen on all available interfaces (e.g. wifi, ethernet, etc) | |
| 161 | -**/ | |
| 162 | -- (BOOL)acceptOnPort:(uint16_t)port error:(NSError **)errPtr; | |
| 163 | - | |
| 164 | -/** | |
| 165 | - * This method is the same as acceptOnPort:error: with the | |
| 166 | - * additional option of specifying which interface to listen on. | |
| 167 | - * | |
| 168 | - * For example, you could specify that the socket should only accept connections over ethernet, | |
| 169 | - * and not other interfaces such as wifi. | |
| 170 | - * | |
| 171 | - * The interface may be specified by name (e.g. "en1" or "lo0") or by IP address (e.g. "192.168.4.34"). | |
| 172 | - * You may also use the special strings "localhost" or "loopback" to specify that | |
| 173 | - * the socket only accept connections from the local machine. | |
| 174 | - * | |
| 175 | - * You can see the list of interfaces via the command line utility "ifconfig", | |
| 176 | - * or programmatically via the getifaddrs() function. | |
| 177 | - * | |
| 178 | - * To accept connections on any interface pass nil, or simply use the acceptOnPort:error: method. | |
| 179 | -**/ | |
| 180 | -- (BOOL)acceptOnInterface:(nullable NSString *)interface port:(uint16_t)port error:(NSError **)errPtr; | |
| 181 | - | |
| 182 | -/** | |
| 183 | - * Tells the socket to begin listening and accepting connections on the unix domain at the given url. | |
| 184 | - * When a connection is accepted, a new instance of GCDAsyncSocket will be spawned to handle it, | |
| 185 | - * and the socket:didAcceptNewSocket: delegate method will be invoked. | |
| 186 | - * | |
| 187 | - * The socket will listen on all available interfaces (e.g. wifi, ethernet, etc) | |
| 188 | - **/ | |
| 189 | -- (BOOL)acceptOnUrl:(NSURL *)url error:(NSError **)errPtr; | |
| 190 | - | |
| 191 | -#pragma mark Connecting | |
| 192 | - | |
| 193 | -/** | |
| 194 | - * Connects to the given host and port. | |
| 195 | - * | |
| 196 | - * This method invokes connectToHost:onPort:viaInterface:withTimeout:error: | |
| 197 | - * and uses the default interface, and no timeout. | |
| 198 | -**/ | |
| 199 | -- (BOOL)connectToHost:(NSString *)host onPort:(uint16_t)port error:(NSError **)errPtr; | |
| 200 | - | |
| 201 | -/** | |
| 202 | - * Connects to the given host and port with an optional timeout. | |
| 203 | - * | |
| 204 | - * This method invokes connectToHost:onPort:viaInterface:withTimeout:error: and uses the default interface. | |
| 205 | -**/ | |
| 206 | -- (BOOL)connectToHost:(NSString *)host | |
| 207 | - onPort:(uint16_t)port | |
| 208 | - withTimeout:(NSTimeInterval)timeout | |
| 209 | - error:(NSError **)errPtr; | |
| 210 | - | |
| 211 | -/** | |
| 212 | - * Connects to the given host & port, via the optional interface, with an optional timeout. | |
| 213 | - * | |
| 214 | - * The host may be a domain name (e.g. "deusty.com") or an IP address string (e.g. "192.168.0.2"). | |
| 215 | - * The host may also be the special strings "localhost" or "loopback" to specify connecting | |
| 216 | - * to a service on the local machine. | |
| 217 | - * | |
| 218 | - * The interface may be a name (e.g. "en1" or "lo0") or the corresponding IP address (e.g. "192.168.4.35"). | |
| 219 | - * The interface may also be used to specify the local port (see below). | |
| 220 | - * | |
| 221 | - * To not time out use a negative time interval. | |
| 222 | - * | |
| 223 | - * This method will return NO if an error is detected, and set the error pointer (if one was given). | |
| 224 | - * Possible errors would be a nil host, invalid interface, or socket is already connected. | |
| 225 | - * | |
| 226 | - * If no errors are detected, this method will start a background connect operation and immediately return YES. | |
| 227 | - * The delegate callbacks are used to notify you when the socket connects, or if the host was unreachable. | |
| 228 | - * | |
| 229 | - * Since this class supports queued reads and writes, you can immediately start reading and/or writing. | |
| 230 | - * All read/write operations will be queued, and upon socket connection, | |
| 231 | - * the operations will be dequeued and processed in order. | |
| 232 | - * | |
| 233 | - * The interface may optionally contain a port number at the end of the string, separated by a colon. | |
| 234 | - * This allows you to specify the local port that should be used for the outgoing connection. (read paragraph to end) | |
| 235 | - * To specify both interface and local port: "en1:8082" or "192.168.4.35:2424". | |
| 236 | - * To specify only local port: ":8082". | |
| 237 | - * Please note this is an advanced feature, and is somewhat hidden on purpose. | |
| 238 | - * You should understand that 99.999% of the time you should NOT specify the local port for an outgoing connection. | |
| 239 | - * If you think you need to, there is a very good chance you have a fundamental misunderstanding somewhere. | |
| 240 | - * Local ports do NOT need to match remote ports. In fact, they almost never do. | |
| 241 | - * This feature is here for networking professionals using very advanced techniques. | |
| 242 | -**/ | |
| 243 | -- (BOOL)connectToHost:(NSString *)host | |
| 244 | - onPort:(uint16_t)port | |
| 245 | - viaInterface:(nullable NSString *)interface | |
| 246 | - withTimeout:(NSTimeInterval)timeout | |
| 247 | - error:(NSError **)errPtr; | |
| 248 | - | |
| 249 | -/** | |
| 250 | - * Connects to the given address, specified as a sockaddr structure wrapped in a NSData object. | |
| 251 | - * For example, a NSData object returned from NSNetService's addresses method. | |
| 252 | - * | |
| 253 | - * If you have an existing struct sockaddr you can convert it to a NSData object like so: | |
| 254 | - * struct sockaddr sa -> NSData *dsa = [NSData dataWithBytes:&remoteAddr length:remoteAddr.sa_len]; | |
| 255 | - * struct sockaddr *sa -> NSData *dsa = [NSData dataWithBytes:remoteAddr length:remoteAddr->sa_len]; | |
| 256 | - * | |
| 257 | - * This method invokes connectToAdd | |
| 258 | -**/ | |
| 259 | -- (BOOL)connectToAddress:(NSData *)remoteAddr error:(NSError **)errPtr; | |
| 260 | - | |
| 261 | -/** | |
| 262 | - * This method is the same as connectToAddress:error: with an additional timeout option. | |
| 263 | - * To not time out use a negative time interval, or simply use the connectToAddress:error: method. | |
| 264 | -**/ | |
| 265 | -- (BOOL)connectToAddress:(NSData *)remoteAddr withTimeout:(NSTimeInterval)timeout error:(NSError **)errPtr; | |
| 266 | - | |
| 267 | -/** | |
| 268 | - * Connects to the given address, using the specified interface and timeout. | |
| 269 | - * | |
| 270 | - * The address is specified as a sockaddr structure wrapped in a NSData object. | |
| 271 | - * For example, a NSData object returned from NSNetService's addresses method. | |
| 272 | - * | |
| 273 | - * If you have an existing struct sockaddr you can convert it to a NSData object like so: | |
| 274 | - * struct sockaddr sa -> NSData *dsa = [NSData dataWithBytes:&remoteAddr length:remoteAddr.sa_len]; | |
| 275 | - * struct sockaddr *sa -> NSData *dsa = [NSData dataWithBytes:remoteAddr length:remoteAddr->sa_len]; | |
| 276 | - * | |
| 277 | - * The interface may be a name (e.g. "en1" or "lo0") or the corresponding IP address (e.g. "192.168.4.35"). | |
| 278 | - * The interface may also be used to specify the local port (see below). | |
| 279 | - * | |
| 280 | - * The timeout is optional. To not time out use a negative time interval. | |
| 281 | - * | |
| 282 | - * This method will return NO if an error is detected, and set the error pointer (if one was given). | |
| 283 | - * Possible errors would be a nil host, invalid interface, or socket is already connected. | |
| 284 | - * | |
| 285 | - * If no errors are detected, this method will start a background connect operation and immediately return YES. | |
| 286 | - * The delegate callbacks are used to notify you when the socket connects, or if the host was unreachable. | |
| 287 | - * | |
| 288 | - * Since this class supports queued reads and writes, you can immediately start reading and/or writing. | |
| 289 | - * All read/write operations will be queued, and upon socket connection, | |
| 290 | - * the operations will be dequeued and processed in order. | |
| 291 | - * | |
| 292 | - * The interface may optionally contain a port number at the end of the string, separated by a colon. | |
| 293 | - * This allows you to specify the local port that should be used for the outgoing connection. (read paragraph to end) | |
| 294 | - * To specify both interface and local port: "en1:8082" or "192.168.4.35:2424". | |
| 295 | - * To specify only local port: ":8082". | |
| 296 | - * Please note this is an advanced feature, and is somewhat hidden on purpose. | |
| 297 | - * You should understand that 99.999% of the time you should NOT specify the local port for an outgoing connection. | |
| 298 | - * If you think you need to, there is a very good chance you have a fundamental misunderstanding somewhere. | |
| 299 | - * Local ports do NOT need to match remote ports. In fact, they almost never do. | |
| 300 | - * This feature is here for networking professionals using very advanced techniques. | |
| 301 | -**/ | |
| 302 | -- (BOOL)connectToAddress:(NSData *)remoteAddr | |
| 303 | - viaInterface:(nullable NSString *)interface | |
| 304 | - withTimeout:(NSTimeInterval)timeout | |
| 305 | - error:(NSError **)errPtr; | |
| 306 | -/** | |
| 307 | - * Connects to the unix domain socket at the given url, using the specified timeout. | |
| 308 | - */ | |
| 309 | -- (BOOL)connectToUrl:(NSURL *)url withTimeout:(NSTimeInterval)timeout error:(NSError **)errPtr; | |
| 310 | - | |
| 311 | -#pragma mark Disconnecting | |
| 312 | - | |
| 313 | -/** | |
| 314 | - * Disconnects immediately (synchronously). Any pending reads or writes are dropped. | |
| 315 | - * | |
| 316 | - * If the socket is not already disconnected, an invocation to the socketDidDisconnect:withError: delegate method | |
| 317 | - * will be queued onto the delegateQueue asynchronously (behind any previously queued delegate methods). | |
| 318 | - * In other words, the disconnected delegate method will be invoked sometime shortly after this method returns. | |
| 319 | - * | |
| 320 | - * Please note the recommended way of releasing a GCDAsyncSocket instance (e.g. in a dealloc method) | |
| 321 | - * [asyncSocket setDelegate:nil]; | |
| 322 | - * [asyncSocket disconnect]; | |
| 323 | - * [asyncSocket release]; | |
| 324 | - * | |
| 325 | - * If you plan on disconnecting the socket, and then immediately asking it to connect again, | |
| 326 | - * you'll likely want to do so like this: | |
| 327 | - * [asyncSocket setDelegate:nil]; | |
| 328 | - * [asyncSocket disconnect]; | |
| 329 | - * [asyncSocket setDelegate:self]; | |
| 330 | - * [asyncSocket connect...]; | |
| 331 | -**/ | |
| 332 | -- (void)disconnect; | |
| 333 | - | |
| 334 | -/** | |
| 335 | - * Disconnects after all pending reads have completed. | |
| 336 | - * After calling this, the read and write methods will do nothing. | |
| 337 | - * The socket will disconnect even if there are still pending writes. | |
| 338 | -**/ | |
| 339 | -- (void)disconnectAfterReading; | |
| 340 | - | |
| 341 | -/** | |
| 342 | - * Disconnects after all pending writes have completed. | |
| 343 | - * After calling this, the read and write methods will do nothing. | |
| 344 | - * The socket will disconnect even if there are still pending reads. | |
| 345 | -**/ | |
| 346 | -- (void)disconnectAfterWriting; | |
| 347 | - | |
| 348 | -/** | |
| 349 | - * Disconnects after all pending reads and writes have completed. | |
| 350 | - * After calling this, the read and write methods will do nothing. | |
| 351 | -**/ | |
| 352 | -- (void)disconnectAfterReadingAndWriting; | |
| 353 | - | |
| 354 | -#pragma mark Diagnostics | |
| 355 | - | |
| 356 | -/** | |
| 357 | - * Returns whether the socket is disconnected or connected. | |
| 358 | - * | |
| 359 | - * A disconnected socket may be recycled. | |
| 360 | - * That is, it can be used again for connecting or listening. | |
| 361 | - * | |
| 362 | - * If a socket is in the process of connecting, it may be neither disconnected nor connected. | |
| 363 | -**/ | |
| 364 | -@property (atomic, readonly) BOOL isDisconnected; | |
| 365 | -@property (atomic, readonly) BOOL isConnected; | |
| 366 | - | |
| 367 | -/** | |
| 368 | - * Returns the local or remote host and port to which this socket is connected, or nil and 0 if not connected. | |
| 369 | - * The host will be an IP address. | |
| 370 | -**/ | |
| 371 | -@property (atomic, readonly, nullable) NSString *connectedHost; | |
| 372 | -@property (atomic, readonly) uint16_t connectedPort; | |
| 373 | -@property (atomic, readonly, nullable) NSURL *connectedUrl; | |
| 374 | - | |
| 375 | -@property (atomic, readonly, nullable) NSString *localHost; | |
| 376 | -@property (atomic, readonly) uint16_t localPort; | |
| 377 | - | |
| 378 | -/** | |
| 379 | - * Returns the local or remote address to which this socket is connected, | |
| 380 | - * specified as a sockaddr structure wrapped in a NSData object. | |
| 381 | - * | |
| 382 | - * @seealso connectedHost | |
| 383 | - * @seealso connectedPort | |
| 384 | - * @seealso localHost | |
| 385 | - * @seealso localPort | |
| 386 | -**/ | |
| 387 | -@property (atomic, readonly, nullable) NSData *connectedAddress; | |
| 388 | -@property (atomic, readonly, nullable) NSData *localAddress; | |
| 389 | - | |
| 390 | -/** | |
| 391 | - * Returns whether the socket is IPv4 or IPv6. | |
| 392 | - * An accepting socket may be both. | |
| 393 | -**/ | |
| 394 | -@property (atomic, readonly) BOOL isIPv4; | |
| 395 | -@property (atomic, readonly) BOOL isIPv6; | |
| 396 | - | |
| 397 | -/** | |
| 398 | - * Returns whether or not the socket has been secured via SSL/TLS. | |
| 399 | - * | |
| 400 | - * See also the startTLS method. | |
| 401 | -**/ | |
| 402 | -@property (atomic, readonly) BOOL isSecure; | |
| 403 | - | |
| 404 | -#pragma mark Reading | |
| 405 | - | |
| 406 | -// The readData and writeData methods won't block (they are asynchronous). | |
| 407 | -// | |
| 408 | -// When a read is complete the socket:didReadData:withTag: delegate method is dispatched on the delegateQueue. | |
| 409 | -// When a write is complete the socket:didWriteDataWithTag: delegate method is dispatched on the delegateQueue. | |
| 410 | -// | |
| 411 | -// You may optionally set a timeout for any read/write operation. (To not timeout, use a negative time interval.) | |
| 412 | -// If a read/write opertion times out, the corresponding "socket:shouldTimeout..." delegate method | |
| 413 | -// is called to optionally allow you to extend the timeout. | |
| 414 | -// Upon a timeout, the "socket:didDisconnectWithError:" method is called | |
| 415 | -// | |
| 416 | -// The tag is for your convenience. | |
| 417 | -// You can use it as an array index, step number, state id, pointer, etc. | |
| 418 | - | |
| 419 | -/** | |
| 420 | - * Reads the first available bytes that become available on the socket. | |
| 421 | - * | |
| 422 | - * If the timeout value is negative, the read operation will not use a timeout. | |
| 423 | -**/ | |
| 424 | -- (void)readDataWithTimeout:(NSTimeInterval)timeout tag:(long)tag; | |
| 425 | - | |
| 426 | -/** | |
| 427 | - * Reads the first available bytes that become available on the socket. | |
| 428 | - * The bytes will be appended to the given byte buffer starting at the given offset. | |
| 429 | - * The given buffer will automatically be increased in size if needed. | |
| 430 | - * | |
| 431 | - * If the timeout value is negative, the read operation will not use a timeout. | |
| 432 | - * If the buffer if nil, the socket will create a buffer for you. | |
| 433 | - * | |
| 434 | - * If the bufferOffset is greater than the length of the given buffer, | |
| 435 | - * the method will do nothing, and the delegate will not be called. | |
| 436 | - * | |
| 437 | - * If you pass a buffer, you must not alter it in any way while the socket is using it. | |
| 438 | - * After completion, the data returned in socket:didReadData:withTag: will be a subset of the given buffer. | |
| 439 | - * That is, it will reference the bytes that were appended to the given buffer via | |
| 440 | - * the method [NSData dataWithBytesNoCopy:length:freeWhenDone:NO]. | |
| 441 | -**/ | |
| 442 | -- (void)readDataWithTimeout:(NSTimeInterval)timeout | |
| 443 | - buffer:(nullable NSMutableData *)buffer | |
| 444 | - bufferOffset:(NSUInteger)offset | |
| 445 | - tag:(long)tag; | |
| 446 | - | |
| 447 | -/** | |
| 448 | - * Reads the first available bytes that become available on the socket. | |
| 449 | - * The bytes will be appended to the given byte buffer starting at the given offset. | |
| 450 | - * The given buffer will automatically be increased in size if needed. | |
| 451 | - * A maximum of length bytes will be read. | |
| 452 | - * | |
| 453 | - * If the timeout value is negative, the read operation will not use a timeout. | |
| 454 | - * If the buffer if nil, a buffer will automatically be created for you. | |
| 455 | - * If maxLength is zero, no length restriction is enforced. | |
| 456 | - * | |
| 457 | - * If the bufferOffset is greater than the length of the given buffer, | |
| 458 | - * the method will do nothing, and the delegate will not be called. | |
| 459 | - * | |
| 460 | - * If you pass a buffer, you must not alter it in any way while the socket is using it. | |
| 461 | - * After completion, the data returned in socket:didReadData:withTag: will be a subset of the given buffer. | |
| 462 | - * That is, it will reference the bytes that were appended to the given buffer via | |
| 463 | - * the method [NSData dataWithBytesNoCopy:length:freeWhenDone:NO]. | |
| 464 | -**/ | |
| 465 | -- (void)readDataWithTimeout:(NSTimeInterval)timeout | |
| 466 | - buffer:(nullable NSMutableData *)buffer | |
| 467 | - bufferOffset:(NSUInteger)offset | |
| 468 | - maxLength:(NSUInteger)length | |
| 469 | - tag:(long)tag; | |
| 470 | - | |
| 471 | -/** | |
| 472 | - * Reads the given number of bytes. | |
| 473 | - * | |
| 474 | - * If the timeout value is negative, the read operation will not use a timeout. | |
| 475 | - * | |
| 476 | - * If the length is 0, this method does nothing and the delegate is not called. | |
| 477 | -**/ | |
| 478 | -- (void)readDataToLength:(NSUInteger)length withTimeout:(NSTimeInterval)timeout tag:(long)tag; | |
| 479 | - | |
| 480 | -/** | |
| 481 | - * Reads the given number of bytes. | |
| 482 | - * The bytes will be appended to the given byte buffer starting at the given offset. | |
| 483 | - * The given buffer will automatically be increased in size if needed. | |
| 484 | - * | |
| 485 | - * If the timeout value is negative, the read operation will not use a timeout. | |
| 486 | - * If the buffer if nil, a buffer will automatically be created for you. | |
| 487 | - * | |
| 488 | - * If the length is 0, this method does nothing and the delegate is not called. | |
| 489 | - * If the bufferOffset is greater than the length of the given buffer, | |
| 490 | - * the method will do nothing, and the delegate will not be called. | |
| 491 | - * | |
| 492 | - * If you pass a buffer, you must not alter it in any way while AsyncSocket is using it. | |
| 493 | - * After completion, the data returned in socket:didReadData:withTag: will be a subset of the given buffer. | |
| 494 | - * That is, it will reference the bytes that were appended to the given buffer via | |
| 495 | - * the method [NSData dataWithBytesNoCopy:length:freeWhenDone:NO]. | |
| 496 | -**/ | |
| 497 | -- (void)readDataToLength:(NSUInteger)length | |
| 498 | - withTimeout:(NSTimeInterval)timeout | |
| 499 | - buffer:(nullable NSMutableData *)buffer | |
| 500 | - bufferOffset:(NSUInteger)offset | |
| 501 | - tag:(long)tag; | |
| 502 | - | |
| 503 | -/** | |
| 504 | - * Reads bytes until (and including) the passed "data" parameter, which acts as a separator. | |
| 505 | - * | |
| 506 | - * If the timeout value is negative, the read operation will not use a timeout. | |
| 507 | - * | |
| 508 | - * If you pass nil or zero-length data as the "data" parameter, | |
| 509 | - * the method will do nothing (except maybe print a warning), and the delegate will not be called. | |
| 510 | - * | |
| 511 | - * To read a line from the socket, use the line separator (e.g. CRLF for HTTP, see below) as the "data" parameter. | |
| 512 | - * If you're developing your own custom protocol, be sure your separator can not occur naturally as | |
| 513 | - * part of the data between separators. | |
| 514 | - * For example, imagine you want to send several small documents over a socket. | |
| 515 | - * Using CRLF as a separator is likely unwise, as a CRLF could easily exist within the documents. | |
| 516 | - * In this particular example, it would be better to use a protocol similar to HTTP with | |
| 517 | - * a header that includes the length of the document. | |
| 518 | - * Also be careful that your separator cannot occur naturally as part of the encoding for a character. | |
| 519 | - * | |
| 520 | - * The given data (separator) parameter should be immutable. | |
| 521 | - * For performance reasons, the socket will retain it, not copy it. | |
| 522 | - * So if it is immutable, don't modify it while the socket is using it. | |
| 523 | -**/ | |
| 524 | -- (void)readDataToData:(NSData *)data withTimeout:(NSTimeInterval)timeout tag:(long)tag; | |
| 525 | - | |
| 526 | -/** | |
| 527 | - * Reads bytes until (and including) the passed "data" parameter, which acts as a separator. | |
| 528 | - * The bytes will be appended to the given byte buffer starting at the given offset. | |
| 529 | - * The given buffer will automatically be increased in size if needed. | |
| 530 | - * | |
| 531 | - * If the timeout value is negative, the read operation will not use a timeout. | |
| 532 | - * If the buffer if nil, a buffer will automatically be created for you. | |
| 533 | - * | |
| 534 | - * If the bufferOffset is greater than the length of the given buffer, | |
| 535 | - * the method will do nothing (except maybe print a warning), and the delegate will not be called. | |
| 536 | - * | |
| 537 | - * If you pass a buffer, you must not alter it in any way while the socket is using it. | |
| 538 | - * After completion, the data returned in socket:didReadData:withTag: will be a subset of the given buffer. | |
| 539 | - * That is, it will reference the bytes that were appended to the given buffer via | |
| 540 | - * the method [NSData dataWithBytesNoCopy:length:freeWhenDone:NO]. | |
| 541 | - * | |
| 542 | - * To read a line from the socket, use the line separator (e.g. CRLF for HTTP, see below) as the "data" parameter. | |
| 543 | - * If you're developing your own custom protocol, be sure your separator can not occur naturally as | |
| 544 | - * part of the data between separators. | |
| 545 | - * For example, imagine you want to send several small documents over a socket. | |
| 546 | - * Using CRLF as a separator is likely unwise, as a CRLF could easily exist within the documents. | |
| 547 | - * In this particular example, it would be better to use a protocol similar to HTTP with | |
| 548 | - * a header that includes the length of the document. | |
| 549 | - * Also be careful that your separator cannot occur naturally as part of the encoding for a character. | |
| 550 | - * | |
| 551 | - * The given data (separator) parameter should be immutable. | |
| 552 | - * For performance reasons, the socket will retain it, not copy it. | |
| 553 | - * So if it is immutable, don't modify it while the socket is using it. | |
| 554 | -**/ | |
| 555 | -- (void)readDataToData:(NSData *)data | |
| 556 | - withTimeout:(NSTimeInterval)timeout | |
| 557 | - buffer:(nullable NSMutableData *)buffer | |
| 558 | - bufferOffset:(NSUInteger)offset | |
| 559 | - tag:(long)tag; | |
| 560 | - | |
| 561 | -/** | |
| 562 | - * Reads bytes until (and including) the passed "data" parameter, which acts as a separator. | |
| 563 | - * | |
| 564 | - * If the timeout value is negative, the read operation will not use a timeout. | |
| 565 | - * | |
| 566 | - * If maxLength is zero, no length restriction is enforced. | |
| 567 | - * Otherwise if maxLength bytes are read without completing the read, | |
| 568 | - * it is treated similarly to a timeout - the socket is closed with a GCDAsyncSocketReadMaxedOutError. | |
| 569 | - * The read will complete successfully if exactly maxLength bytes are read and the given data is found at the end. | |
| 570 | - * | |
| 571 | - * If you pass nil or zero-length data as the "data" parameter, | |
| 572 | - * the method will do nothing (except maybe print a warning), and the delegate will not be called. | |
| 573 | - * If you pass a maxLength parameter that is less than the length of the data parameter, | |
| 574 | - * the method will do nothing (except maybe print a warning), and the delegate will not be called. | |
| 575 | - * | |
| 576 | - * To read a line from the socket, use the line separator (e.g. CRLF for HTTP, see below) as the "data" parameter. | |
| 577 | - * If you're developing your own custom protocol, be sure your separator can not occur naturally as | |
| 578 | - * part of the data between separators. | |
| 579 | - * For example, imagine you want to send several small documents over a socket. | |
| 580 | - * Using CRLF as a separator is likely unwise, as a CRLF could easily exist within the documents. | |
| 581 | - * In this particular example, it would be better to use a protocol similar to HTTP with | |
| 582 | - * a header that includes the length of the document. | |
| 583 | - * Also be careful that your separator cannot occur naturally as part of the encoding for a character. | |
| 584 | - * | |
| 585 | - * The given data (separator) parameter should be immutable. | |
| 586 | - * For performance reasons, the socket will retain it, not copy it. | |
| 587 | - * So if it is immutable, don't modify it while the socket is using it. | |
| 588 | -**/ | |
| 589 | -- (void)readDataToData:(NSData *)data withTimeout:(NSTimeInterval)timeout maxLength:(NSUInteger)length tag:(long)tag; | |
| 590 | - | |
| 591 | -/** | |
| 592 | - * Reads bytes until (and including) the passed "data" parameter, which acts as a separator. | |
| 593 | - * The bytes will be appended to the given byte buffer starting at the given offset. | |
| 594 | - * The given buffer will automatically be increased in size if needed. | |
| 595 | - * | |
| 596 | - * If the timeout value is negative, the read operation will not use a timeout. | |
| 597 | - * If the buffer if nil, a buffer will automatically be created for you. | |
| 598 | - * | |
| 599 | - * If maxLength is zero, no length restriction is enforced. | |
| 600 | - * Otherwise if maxLength bytes are read without completing the read, | |
| 601 | - * it is treated similarly to a timeout - the socket is closed with a GCDAsyncSocketReadMaxedOutError. | |
| 602 | - * The read will complete successfully if exactly maxLength bytes are read and the given data is found at the end. | |
| 603 | - * | |
| 604 | - * If you pass a maxLength parameter that is less than the length of the data (separator) parameter, | |
| 605 | - * the method will do nothing (except maybe print a warning), and the delegate will not be called. | |
| 606 | - * If the bufferOffset is greater than the length of the given buffer, | |
| 607 | - * the method will do nothing (except maybe print a warning), and the delegate will not be called. | |
| 608 | - * | |
| 609 | - * If you pass a buffer, you must not alter it in any way while the socket is using it. | |
| 610 | - * After completion, the data returned in socket:didReadData:withTag: will be a subset of the given buffer. | |
| 611 | - * That is, it will reference the bytes that were appended to the given buffer via | |
| 612 | - * the method [NSData dataWithBytesNoCopy:length:freeWhenDone:NO]. | |
| 613 | - * | |
| 614 | - * To read a line from the socket, use the line separator (e.g. CRLF for HTTP, see below) as the "data" parameter. | |
| 615 | - * If you're developing your own custom protocol, be sure your separator can not occur naturally as | |
| 616 | - * part of the data between separators. | |
| 617 | - * For example, imagine you want to send several small documents over a socket. | |
| 618 | - * Using CRLF as a separator is likely unwise, as a CRLF could easily exist within the documents. | |
| 619 | - * In this particular example, it would be better to use a protocol similar to HTTP with | |
| 620 | - * a header that includes the length of the document. | |
| 621 | - * Also be careful that your separator cannot occur naturally as part of the encoding for a character. | |
| 622 | - * | |
| 623 | - * The given data (separator) parameter should be immutable. | |
| 624 | - * For performance reasons, the socket will retain it, not copy it. | |
| 625 | - * So if it is immutable, don't modify it while the socket is using it. | |
| 626 | -**/ | |
| 627 | -- (void)readDataToData:(NSData *)data | |
| 628 | - withTimeout:(NSTimeInterval)timeout | |
| 629 | - buffer:(nullable NSMutableData *)buffer | |
| 630 | - bufferOffset:(NSUInteger)offset | |
| 631 | - maxLength:(NSUInteger)length | |
| 632 | - tag:(long)tag; | |
| 633 | - | |
| 634 | -/** | |
| 635 | - * Returns progress of the current read, from 0.0 to 1.0, or NaN if no current read (use isnan() to check). | |
| 636 | - * The parameters "tag", "done" and "total" will be filled in if they aren't NULL. | |
| 637 | -**/ | |
| 638 | -- (float)progressOfReadReturningTag:(nullable long *)tagPtr bytesDone:(nullable NSUInteger *)donePtr total:(nullable NSUInteger *)totalPtr; | |
| 639 | - | |
| 640 | -#pragma mark Writing | |
| 641 | - | |
| 642 | -/** | |
| 643 | - * Writes data to the socket, and calls the delegate when finished. | |
| 644 | - * | |
| 645 | - * If you pass in nil or zero-length data, this method does nothing and the delegate will not be called. | |
| 646 | - * If the timeout value is negative, the write operation will not use a timeout. | |
| 647 | - * | |
| 648 | - * Thread-Safety Note: | |
| 649 | - * If the given data parameter is mutable (NSMutableData) then you MUST NOT alter the data while | |
| 650 | - * the socket is writing it. In other words, it's not safe to alter the data until after the delegate method | |
| 651 | - * socket:didWriteDataWithTag: is invoked signifying that this particular write operation has completed. | |
| 652 | - * This is due to the fact that GCDAsyncSocket does NOT copy the data. It simply retains it. | |
| 653 | - * This is for performance reasons. Often times, if NSMutableData is passed, it is because | |
| 654 | - * a request/response was built up in memory. Copying this data adds an unwanted/unneeded overhead. | |
| 655 | - * If you need to write data from an immutable buffer, and you need to alter the buffer before the socket | |
| 656 | - * completes writing the bytes (which is NOT immediately after this method returns, but rather at a later time | |
| 657 | - * when the delegate method notifies you), then you should first copy the bytes, and pass the copy to this method. | |
| 658 | -**/ | |
| 659 | -- (void)writeData:(NSData *)data withTimeout:(NSTimeInterval)timeout tag:(long)tag; | |
| 660 | - | |
| 661 | -/** | |
| 662 | - * Returns progress of the current write, from 0.0 to 1.0, or NaN if no current write (use isnan() to check). | |
| 663 | - * The parameters "tag", "done" and "total" will be filled in if they aren't NULL. | |
| 664 | -**/ | |
| 665 | -- (float)progressOfWriteReturningTag:(nullable long *)tagPtr bytesDone:(nullable NSUInteger *)donePtr total:(nullable NSUInteger *)totalPtr; | |
| 666 | - | |
| 667 | -#pragma mark Security | |
| 668 | - | |
| 669 | -/** | |
| 670 | - * Secures the connection using SSL/TLS. | |
| 671 | - * | |
| 672 | - * This method may be called at any time, and the TLS handshake will occur after all pending reads and writes | |
| 673 | - * are finished. This allows one the option of sending a protocol dependent StartTLS message, and queuing | |
| 674 | - * the upgrade to TLS at the same time, without having to wait for the write to finish. | |
| 675 | - * Any reads or writes scheduled after this method is called will occur over the secured connection. | |
| 676 | - * | |
| 677 | - * ==== The available TOP-LEVEL KEYS are: | |
| 678 | - * | |
| 679 | - * - GCDAsyncSocketManuallyEvaluateTrust | |
| 680 | - * The value must be of type NSNumber, encapsulating a BOOL value. | |
| 681 | - * If you set this to YES, then the underlying SecureTransport system will not evaluate the SecTrustRef of the peer. | |
| 682 | - * Instead it will pause at the moment evaulation would typically occur, | |
| 683 | - * and allow us to handle the security evaluation however we see fit. | |
| 684 | - * So GCDAsyncSocket will invoke the delegate method socket:shouldTrustPeer: passing the SecTrustRef. | |
| 685 | - * | |
| 686 | - * Note that if you set this option, then all other configuration keys are ignored. | |
| 687 | - * Evaluation will be completely up to you during the socket:didReceiveTrust:completionHandler: delegate method. | |
| 688 | - * | |
| 689 | - * For more information on trust evaluation see: | |
| 690 | - * Apple's Technical Note TN2232 - HTTPS Server Trust Evaluation | |
| 691 | - * https://developer.apple.com/library/ios/technotes/tn2232/_index.html | |
| 692 | - * | |
| 693 | - * If unspecified, the default value is NO. | |
| 694 | - * | |
| 695 | - * - GCDAsyncSocketUseCFStreamForTLS (iOS only) | |
| 696 | - * The value must be of type NSNumber, encapsulating a BOOL value. | |
| 697 | - * By default GCDAsyncSocket will use the SecureTransport layer to perform encryption. | |
| 698 | - * This gives us more control over the security protocol (many more configuration options), | |
| 699 | - * plus it allows us to optimize things like sys calls and buffer allocation. | |
| 700 | - * | |
| 701 | - * However, if you absolutely must, you can instruct GCDAsyncSocket to use the old-fashioned encryption | |
| 702 | - * technique by going through the CFStream instead. So instead of using SecureTransport, GCDAsyncSocket | |
| 703 | - * will instead setup a CFRead/CFWriteStream. And then set the kCFStreamPropertySSLSettings property | |
| 704 | - * (via CFReadStreamSetProperty / CFWriteStreamSetProperty) and will pass the given options to this method. | |
| 705 | - * | |
| 706 | - * Thus all the other keys in the given dictionary will be ignored by GCDAsyncSocket, | |
| 707 | - * and will passed directly CFReadStreamSetProperty / CFWriteStreamSetProperty. | |
| 708 | - * For more infomation on these keys, please see the documentation for kCFStreamPropertySSLSettings. | |
| 709 | - * | |
| 710 | - * If unspecified, the default value is NO. | |
| 711 | - * | |
| 712 | - * ==== The available CONFIGURATION KEYS are: | |
| 713 | - * | |
| 714 | - * - kCFStreamSSLPeerName | |
| 715 | - * The value must be of type NSString. | |
| 716 | - * It should match the name in the X.509 certificate given by the remote party. | |
| 717 | - * See Apple's documentation for SSLSetPeerDomainName. | |
| 718 | - * | |
| 719 | - * - kCFStreamSSLCertificates | |
| 720 | - * The value must be of type NSArray. | |
| 721 | - * See Apple's documentation for SSLSetCertificate. | |
| 722 | - * | |
| 723 | - * - kCFStreamSSLIsServer | |
| 724 | - * The value must be of type NSNumber, encapsulationg a BOOL value. | |
| 725 | - * See Apple's documentation for SSLCreateContext for iOS. | |
| 726 | - * This is optional for iOS. If not supplied, a NO value is the default. | |
| 727 | - * This is not needed for Mac OS X, and the value is ignored. | |
| 728 | - * | |
| 729 | - * - GCDAsyncSocketSSLPeerID | |
| 730 | - * The value must be of type NSData. | |
| 731 | - * You must set this value if you want to use TLS session resumption. | |
| 732 | - * See Apple's documentation for SSLSetPeerID. | |
| 733 | - * | |
| 734 | - * - GCDAsyncSocketSSLProtocolVersionMin | |
| 735 | - * - GCDAsyncSocketSSLProtocolVersionMax | |
| 736 | - * The value(s) must be of type NSNumber, encapsulting a SSLProtocol value. | |
| 737 | - * See Apple's documentation for SSLSetProtocolVersionMin & SSLSetProtocolVersionMax. | |
| 738 | - * See also the SSLProtocol typedef. | |
| 739 | - * | |
| 740 | - * - GCDAsyncSocketSSLSessionOptionFalseStart | |
| 741 | - * The value must be of type NSNumber, encapsulating a BOOL value. | |
| 742 | - * See Apple's documentation for kSSLSessionOptionFalseStart. | |
| 743 | - * | |
| 744 | - * - GCDAsyncSocketSSLSessionOptionSendOneByteRecord | |
| 745 | - * The value must be of type NSNumber, encapsulating a BOOL value. | |
| 746 | - * See Apple's documentation for kSSLSessionOptionSendOneByteRecord. | |
| 747 | - * | |
| 748 | - * - GCDAsyncSocketSSLCipherSuites | |
| 749 | - * The values must be of type NSArray. | |
| 750 | - * Each item within the array must be a NSNumber, encapsulating | |
| 751 | - * See Apple's documentation for SSLSetEnabledCiphers. | |
| 752 | - * See also the SSLCipherSuite typedef. | |
| 753 | - * | |
| 754 | - * - GCDAsyncSocketSSLDiffieHellmanParameters (Mac OS X only) | |
| 755 | - * The value must be of type NSData. | |
| 756 | - * See Apple's documentation for SSLSetDiffieHellmanParams. | |
| 757 | - * | |
| 758 | - * ==== The following UNAVAILABLE KEYS are: (with throw an exception) | |
| 759 | - * | |
| 760 | - * - kCFStreamSSLAllowsAnyRoot (UNAVAILABLE) | |
| 761 | - * You MUST use manual trust evaluation instead (see GCDAsyncSocketManuallyEvaluateTrust). | |
| 762 | - * Corresponding deprecated method: SSLSetAllowsAnyRoot | |
| 763 | - * | |
| 764 | - * - kCFStreamSSLAllowsExpiredRoots (UNAVAILABLE) | |
| 765 | - * You MUST use manual trust evaluation instead (see GCDAsyncSocketManuallyEvaluateTrust). | |
| 766 | - * Corresponding deprecated method: SSLSetAllowsExpiredRoots | |
| 767 | - * | |
| 768 | - * - kCFStreamSSLAllowsExpiredCertificates (UNAVAILABLE) | |
| 769 | - * You MUST use manual trust evaluation instead (see GCDAsyncSocketManuallyEvaluateTrust). | |
| 770 | - * Corresponding deprecated method: SSLSetAllowsExpiredCerts | |
| 771 | - * | |
| 772 | - * - kCFStreamSSLValidatesCertificateChain (UNAVAILABLE) | |
| 773 | - * You MUST use manual trust evaluation instead (see GCDAsyncSocketManuallyEvaluateTrust). | |
| 774 | - * Corresponding deprecated method: SSLSetEnableCertVerify | |
| 775 | - * | |
| 776 | - * - kCFStreamSSLLevel (UNAVAILABLE) | |
| 777 | - * You MUST use GCDAsyncSocketSSLProtocolVersionMin & GCDAsyncSocketSSLProtocolVersionMin instead. | |
| 778 | - * Corresponding deprecated method: SSLSetProtocolVersionEnabled | |
| 779 | - * | |
| 780 | - * | |
| 781 | - * Please refer to Apple's documentation for corresponding SSLFunctions. | |
| 782 | - * | |
| 783 | - * If you pass in nil or an empty dictionary, the default settings will be used. | |
| 784 | - * | |
| 785 | - * IMPORTANT SECURITY NOTE: | |
| 786 | - * The default settings will check to make sure the remote party's certificate is signed by a | |
| 787 | - * trusted 3rd party certificate agency (e.g. verisign) and that the certificate is not expired. | |
| 788 | - * However it will not verify the name on the certificate unless you | |
| 789 | - * give it a name to verify against via the kCFStreamSSLPeerName key. | |
| 790 | - * The security implications of this are important to understand. | |
| 791 | - * Imagine you are attempting to create a secure connection to MySecureServer.com, | |
| 792 | - * but your socket gets directed to MaliciousServer.com because of a hacked DNS server. | |
| 793 | - * If you simply use the default settings, and MaliciousServer.com has a valid certificate, | |
| 794 | - * the default settings will not detect any problems since the certificate is valid. | |
| 795 | - * To properly secure your connection in this particular scenario you | |
| 796 | - * should set the kCFStreamSSLPeerName property to "MySecureServer.com". | |
| 797 | - * | |
| 798 | - * You can also perform additional validation in socketDidSecure. | |
| 799 | -**/ | |
| 800 | -- (void)startTLS:(nullable NSDictionary <NSString*,NSObject*>*)tlsSettings; | |
| 801 | - | |
| 802 | -#pragma mark Advanced | |
| 803 | - | |
| 804 | -/** | |
| 805 | - * Traditionally sockets are not closed until the conversation is over. | |
| 806 | - * However, it is technically possible for the remote enpoint to close its write stream. | |
| 807 | - * Our socket would then be notified that there is no more data to be read, | |
| 808 | - * but our socket would still be writeable and the remote endpoint could continue to receive our data. | |
| 809 | - * | |
| 810 | - * The argument for this confusing functionality stems from the idea that a client could shut down its | |
| 811 | - * write stream after sending a request to the server, thus notifying the server there are to be no further requests. | |
| 812 | - * In practice, however, this technique did little to help server developers. | |
| 813 | - * | |
| 814 | - * To make matters worse, from a TCP perspective there is no way to tell the difference from a read stream close | |
| 815 | - * and a full socket close. They both result in the TCP stack receiving a FIN packet. The only way to tell | |
| 816 | - * is by continuing to write to the socket. If it was only a read stream close, then writes will continue to work. | |
| 817 | - * Otherwise an error will be occur shortly (when the remote end sends us a RST packet). | |
| 818 | - * | |
| 819 | - * In addition to the technical challenges and confusion, many high level socket/stream API's provide | |
| 820 | - * no support for dealing with the problem. If the read stream is closed, the API immediately declares the | |
| 821 | - * socket to be closed, and shuts down the write stream as well. In fact, this is what Apple's CFStream API does. | |
| 822 | - * It might sound like poor design at first, but in fact it simplifies development. | |
| 823 | - * | |
| 824 | - * The vast majority of the time if the read stream is closed it's because the remote endpoint closed its socket. | |
| 825 | - * Thus it actually makes sense to close the socket at this point. | |
| 826 | - * And in fact this is what most networking developers want and expect to happen. | |
| 827 | - * However, if you are writing a server that interacts with a plethora of clients, | |
| 828 | - * you might encounter a client that uses the discouraged technique of shutting down its write stream. | |
| 829 | - * If this is the case, you can set this property to NO, | |
| 830 | - * and make use of the socketDidCloseReadStream delegate method. | |
| 831 | - * | |
| 832 | - * The default value is YES. | |
| 833 | -**/ | |
| 834 | -@property (atomic, assign, readwrite) BOOL autoDisconnectOnClosedReadStream; | |
| 835 | - | |
| 836 | -/** | |
| 837 | - * GCDAsyncSocket maintains thread safety by using an internal serial dispatch_queue. | |
| 838 | - * In most cases, the instance creates this queue itself. | |
| 839 | - * However, to allow for maximum flexibility, the internal queue may be passed in the init method. | |
| 840 | - * This allows for some advanced options such as controlling socket priority via target queues. | |
| 841 | - * However, when one begins to use target queues like this, they open the door to some specific deadlock issues. | |
| 842 | - * | |
| 843 | - * For example, imagine there are 2 queues: | |
| 844 | - * dispatch_queue_t socketQueue; | |
| 845 | - * dispatch_queue_t socketTargetQueue; | |
| 846 | - * | |
| 847 | - * If you do this (pseudo-code): | |
| 848 | - * socketQueue.targetQueue = socketTargetQueue; | |
| 849 | - * | |
| 850 | - * Then all socketQueue operations will actually get run on the given socketTargetQueue. | |
| 851 | - * This is fine and works great in most situations. | |
| 852 | - * But if you run code directly from within the socketTargetQueue that accesses the socket, | |
| 853 | - * you could potentially get deadlock. Imagine the following code: | |
| 854 | - * | |
| 855 | - * - (BOOL)socketHasSomething | |
| 856 | - * { | |
| 857 | - * __block BOOL result = NO; | |
| 858 | - * dispatch_block_t block = ^{ | |
| 859 | - * result = [self someInternalMethodToBeRunOnlyOnSocketQueue]; | |
| 860 | - * } | |
| 861 | - * if (is_executing_on_queue(socketQueue)) | |
| 862 | - * block(); | |
| 863 | - * else | |
| 864 | - * dispatch_sync(socketQueue, block); | |
| 865 | - * | |
| 866 | - * return result; | |
| 867 | - * } | |
| 868 | - * | |
| 869 | - * What happens if you call this method from the socketTargetQueue? The result is deadlock. | |
| 870 | - * This is because the GCD API offers no mechanism to discover a queue's targetQueue. | |
| 871 | - * Thus we have no idea if our socketQueue is configured with a targetQueue. | |
| 872 | - * If we had this information, we could easily avoid deadlock. | |
| 873 | - * But, since these API's are missing or unfeasible, you'll have to explicitly set it. | |
| 874 | - * | |
| 875 | - * IF you pass a socketQueue via the init method, | |
| 876 | - * AND you've configured the passed socketQueue with a targetQueue, | |
| 877 | - * THEN you should pass the end queue in the target hierarchy. | |
| 878 | - * | |
| 879 | - * For example, consider the following queue hierarchy: | |
| 880 | - * socketQueue -> ipQueue -> moduleQueue | |
| 881 | - * | |
| 882 | - * This example demonstrates priority shaping within some server. | |
| 883 | - * All incoming client connections from the same IP address are executed on the same target queue. | |
| 884 | - * And all connections for a particular module are executed on the same target queue. | |
| 885 | - * Thus, the priority of all networking for the entire module can be changed on the fly. | |
| 886 | - * Additionally, networking traffic from a single IP cannot monopolize the module. | |
| 887 | - * | |
| 888 | - * Here's how you would accomplish something like that: | |
| 889 | - * - (dispatch_queue_t)newSocketQueueForConnectionFromAddress:(NSData *)address onSocket:(GCDAsyncSocket *)sock | |
| 890 | - * { | |
| 891 | - * dispatch_queue_t socketQueue = dispatch_queue_create("", NULL); | |
| 892 | - * dispatch_queue_t ipQueue = [self ipQueueForAddress:address]; | |
| 893 | - * | |
| 894 | - * dispatch_set_target_queue(socketQueue, ipQueue); | |
| 895 | - * dispatch_set_target_queue(iqQueue, moduleQueue); | |
| 896 | - * | |
| 897 | - * return socketQueue; | |
| 898 | - * } | |
| 899 | - * - (void)socket:(GCDAsyncSocket *)sock didAcceptNewSocket:(GCDAsyncSocket *)newSocket | |
| 900 | - * { | |
| 901 | - * [clientConnections addObject:newSocket]; | |
| 902 | - * [newSocket markSocketQueueTargetQueue:moduleQueue]; | |
| 903 | - * } | |
| 904 | - * | |
| 905 | - * Note: This workaround is ONLY needed if you intend to execute code directly on the ipQueue or moduleQueue. | |
| 906 | - * This is often NOT the case, as such queues are used solely for execution shaping. | |
| 907 | -**/ | |
| 908 | -- (void)markSocketQueueTargetQueue:(dispatch_queue_t)socketQueuesPreConfiguredTargetQueue; | |
| 909 | -- (void)unmarkSocketQueueTargetQueue:(dispatch_queue_t)socketQueuesPreviouslyConfiguredTargetQueue; | |
| 910 | - | |
| 911 | -/** | |
| 912 | - * It's not thread-safe to access certain variables from outside the socket's internal queue. | |
| 913 | - * | |
| 914 | - * For example, the socket file descriptor. | |
| 915 | - * File descriptors are simply integers which reference an index in the per-process file table. | |
| 916 | - * However, when one requests a new file descriptor (by opening a file or socket), | |
| 917 | - * the file descriptor returned is guaranteed to be the lowest numbered unused descriptor. | |
| 918 | - * So if we're not careful, the following could be possible: | |
| 919 | - * | |
| 920 | - * - Thread A invokes a method which returns the socket's file descriptor. | |
| 921 | - * - The socket is closed via the socket's internal queue on thread B. | |
| 922 | - * - Thread C opens a file, and subsequently receives the file descriptor that was previously the socket's FD. | |
| 923 | - * - Thread A is now accessing/altering the file instead of the socket. | |
| 924 | - * | |
| 925 | - * In addition to this, other variables are not actually objects, | |
| 926 | - * and thus cannot be retained/released or even autoreleased. | |
| 927 | - * An example is the sslContext, of type SSLContextRef, which is actually a malloc'd struct. | |
| 928 | - * | |
| 929 | - * Although there are internal variables that make it difficult to maintain thread-safety, | |
| 930 | - * it is important to provide access to these variables | |
| 931 | - * to ensure this class can be used in a wide array of environments. | |
| 932 | - * This method helps to accomplish this by invoking the current block on the socket's internal queue. | |
| 933 | - * The methods below can be invoked from within the block to access | |
| 934 | - * those generally thread-unsafe internal variables in a thread-safe manner. | |
| 935 | - * The given block will be invoked synchronously on the socket's internal queue. | |
| 936 | - * | |
| 937 | - * If you save references to any protected variables and use them outside the block, you do so at your own peril. | |
| 938 | -**/ | |
| 939 | -- (void)performBlock:(dispatch_block_t)block; | |
| 940 | - | |
| 941 | -/** | |
| 942 | - * These methods are only available from within the context of a performBlock: invocation. | |
| 943 | - * See the documentation for the performBlock: method above. | |
| 944 | - * | |
| 945 | - * Provides access to the socket's file descriptor(s). | |
| 946 | - * If the socket is a server socket (is accepting incoming connections), | |
| 947 | - * it might actually have multiple internal socket file descriptors - one for IPv4 and one for IPv6. | |
| 948 | -**/ | |
| 949 | -- (int)socketFD; | |
| 950 | -- (int)socket4FD; | |
| 951 | -- (int)socket6FD; | |
| 952 | - | |
| 953 | -#if TARGET_OS_IPHONE | |
| 954 | - | |
| 955 | -/** | |
| 956 | - * These methods are only available from within the context of a performBlock: invocation. | |
| 957 | - * See the documentation for the performBlock: method above. | |
| 958 | - * | |
| 959 | - * Provides access to the socket's internal CFReadStream/CFWriteStream. | |
| 960 | - * | |
| 961 | - * These streams are only used as workarounds for specific iOS shortcomings: | |
| 962 | - * | |
| 963 | - * - Apple has decided to keep the SecureTransport framework private is iOS. | |
| 964 | - * This means the only supplied way to do SSL/TLS is via CFStream or some other API layered on top of it. | |
| 965 | - * Thus, in order to provide SSL/TLS support on iOS we are forced to rely on CFStream, | |
| 966 | - * instead of the preferred and faster and more powerful SecureTransport. | |
| 967 | - * | |
| 968 | - * - If a socket doesn't have backgrounding enabled, and that socket is closed while the app is backgrounded, | |
| 969 | - * Apple only bothers to notify us via the CFStream API. | |
| 970 | - * The faster and more powerful GCD API isn't notified properly in this case. | |
| 971 | - * | |
| 972 | - * See also: (BOOL)enableBackgroundingOnSocket | |
| 973 | -**/ | |
| 974 | -- (nullable CFReadStreamRef)readStream; | |
| 975 | -- (nullable CFWriteStreamRef)writeStream; | |
| 976 | - | |
| 977 | -/** | |
| 978 | - * This method is only available from within the context of a performBlock: invocation. | |
| 979 | - * See the documentation for the performBlock: method above. | |
| 980 | - * | |
| 981 | - * Configures the socket to allow it to operate when the iOS application has been backgrounded. | |
| 982 | - * In other words, this method creates a read & write stream, and invokes: | |
| 983 | - * | |
| 984 | - * CFReadStreamSetProperty(readStream, kCFStreamNetworkServiceType, kCFStreamNetworkServiceTypeVoIP); | |
| 985 | - * CFWriteStreamSetProperty(writeStream, kCFStreamNetworkServiceType, kCFStreamNetworkServiceTypeVoIP); | |
| 986 | - * | |
| 987 | - * Returns YES if successful, NO otherwise. | |
| 988 | - * | |
| 989 | - * Note: Apple does not officially support backgrounding server sockets. | |
| 990 | - * That is, if your socket is accepting incoming connections, Apple does not officially support | |
| 991 | - * allowing iOS applications to accept incoming connections while an app is backgrounded. | |
| 992 | - * | |
| 993 | - * Example usage: | |
| 994 | - * | |
| 995 | - * - (void)socket:(GCDAsyncSocket *)sock didConnectToHost:(NSString *)host port:(uint16_t)port | |
| 996 | - * { | |
| 997 | - * [asyncSocket performBlock:^{ | |
| 998 | - * [asyncSocket enableBackgroundingOnSocket]; | |
| 999 | - * }]; | |
| 1000 | - * } | |
| 1001 | -**/ | |
| 1002 | -- (BOOL)enableBackgroundingOnSocket; | |
| 1003 | - | |
| 1004 | -#endif | |
| 1005 | - | |
| 1006 | -/** | |
| 1007 | - * This method is only available from within the context of a performBlock: invocation. | |
| 1008 | - * See the documentation for the performBlock: method above. | |
| 1009 | - * | |
| 1010 | - * Provides access to the socket's SSLContext, if SSL/TLS has been started on the socket. | |
| 1011 | -**/ | |
| 1012 | -- (nullable SSLContextRef)sslContext; | |
| 1013 | - | |
| 1014 | -#pragma mark Utilities | |
| 1015 | - | |
| 1016 | -/** | |
| 1017 | - * The address lookup utility used by the class. | |
| 1018 | - * This method is synchronous, so it's recommended you use it on a background thread/queue. | |
| 1019 | - * | |
| 1020 | - * The special strings "localhost" and "loopback" return the loopback address for IPv4 and IPv6. | |
| 1021 | - * | |
| 1022 | - * @returns | |
| 1023 | - * A mutable array with all IPv4 and IPv6 addresses returned by getaddrinfo. | |
| 1024 | - * The addresses are specifically for TCP connections. | |
| 1025 | - * You can filter the addresses, if needed, using the other utility methods provided by the class. | |
| 1026 | -**/ | |
| 1027 | -+ (nullable NSMutableArray *)lookupHost:(NSString *)host port:(uint16_t)port error:(NSError **)errPtr; | |
| 1028 | - | |
| 1029 | -/** | |
| 1030 | - * Extracting host and port information from raw address data. | |
| 1031 | -**/ | |
| 1032 | - | |
| 1033 | -+ (nullable NSString *)hostFromAddress:(NSData *)address; | |
| 1034 | -+ (uint16_t)portFromAddress:(NSData *)address; | |
| 1035 | - | |
| 1036 | -+ (BOOL)isIPv4Address:(NSData *)address; | |
| 1037 | -+ (BOOL)isIPv6Address:(NSData *)address; | |
| 1038 | - | |
| 1039 | -+ (BOOL)getHost:( NSString * __nullable * __nullable)hostPtr port:(nullable uint16_t *)portPtr fromAddress:(NSData *)address; | |
| 1040 | - | |
| 1041 | -+ (BOOL)getHost:(NSString * __nullable * __nullable)hostPtr port:(nullable uint16_t *)portPtr family:(nullable sa_family_t *)afPtr fromAddress:(NSData *)address; | |
| 1042 | - | |
| 1043 | -/** | |
| 1044 | - * A few common line separators, for use with the readDataToData:... methods. | |
| 1045 | -**/ | |
| 1046 | -+ (NSData *)CRLFData; // 0x0D0A | |
| 1047 | -+ (NSData *)CRData; // 0x0D | |
| 1048 | -+ (NSData *)LFData; // 0x0A | |
| 1049 | -+ (NSData *)ZeroData; // 0x00 | |
| 1050 | - | |
| 1051 | -@end | |
| 1052 | - | |
| 1053 | -//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | |
| 1054 | -#pragma mark - | |
| 1055 | -//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | |
| 1056 | - | |
| 1057 | -@protocol GCDAsyncSocketDelegate <NSObject> | |
| 1058 | -@optional | |
| 1059 | - | |
| 1060 | -/** | |
| 1061 | - * This method is called immediately prior to socket:didAcceptNewSocket:. | |
| 1062 | - * It optionally allows a listening socket to specify the socketQueue for a new accepted socket. | |
| 1063 | - * If this method is not implemented, or returns NULL, the new accepted socket will create its own default queue. | |
| 1064 | - * | |
| 1065 | - * Since you cannot autorelease a dispatch_queue, | |
| 1066 | - * this method uses the "new" prefix in its name to specify that the returned queue has been retained. | |
| 1067 | - * | |
| 1068 | - * Thus you could do something like this in the implementation: | |
| 1069 | - * return dispatch_queue_create("MyQueue", NULL); | |
| 1070 | - * | |
| 1071 | - * If you are placing multiple sockets on the same queue, | |
| 1072 | - * then care should be taken to increment the retain count each time this method is invoked. | |
| 1073 | - * | |
| 1074 | - * For example, your implementation might look something like this: | |
| 1075 | - * dispatch_retain(myExistingQueue); | |
| 1076 | - * return myExistingQueue; | |
| 1077 | -**/ | |
| 1078 | -- (nullable dispatch_queue_t)newSocketQueueForConnectionFromAddress:(NSData *)address onSocket:(GCDAsyncSocket *)sock; | |
| 1079 | - | |
| 1080 | -/** | |
| 1081 | - * Called when a socket accepts a connection. | |
| 1082 | - * Another socket is automatically spawned to handle it. | |
| 1083 | - * | |
| 1084 | - * You must retain the newSocket if you wish to handle the connection. | |
| 1085 | - * Otherwise the newSocket instance will be released and the spawned connection will be closed. | |
| 1086 | - * | |
| 1087 | - * By default the new socket will have the same delegate and delegateQueue. | |
| 1088 | - * You may, of course, change this at any time. | |
| 1089 | -**/ | |
| 1090 | -- (void)socket:(GCDAsyncSocket *)sock didAcceptNewSocket:(GCDAsyncSocket *)newSocket; | |
| 1091 | - | |
| 1092 | -/** | |
| 1093 | - * Called when a socket connects and is ready for reading and writing. | |
| 1094 | - * The host parameter will be an IP address, not a DNS name. | |
| 1095 | -**/ | |
| 1096 | -- (void)socket:(GCDAsyncSocket *)sock didConnectToHost:(NSString *)host port:(uint16_t)port; | |
| 1097 | - | |
| 1098 | -/** | |
| 1099 | - * Called when a socket connects and is ready for reading and writing. | |
| 1100 | - * The host parameter will be an IP address, not a DNS name. | |
| 1101 | - **/ | |
| 1102 | -- (void)socket:(GCDAsyncSocket *)sock didConnectToUrl:(NSURL *)url; | |
| 1103 | - | |
| 1104 | -/** | |
| 1105 | - * Called when a socket has completed reading the requested data into memory. | |
| 1106 | - * Not called if there is an error. | |
| 1107 | -**/ | |
| 1108 | -- (void)socket:(GCDAsyncSocket *)sock didReadData:(NSData *)data withTag:(long)tag; | |
| 1109 | - | |
| 1110 | -/** | |
| 1111 | - * Called when a socket has read in data, but has not yet completed the read. | |
| 1112 | - * This would occur if using readToData: or readToLength: methods. | |
| 1113 | - * It may be used to for things such as updating progress bars. | |
| 1114 | -**/ | |
| 1115 | -- (void)socket:(GCDAsyncSocket *)sock didReadPartialDataOfLength:(NSUInteger)partialLength tag:(long)tag; | |
| 1116 | - | |
| 1117 | -/** | |
| 1118 | - * Called when a socket has completed writing the requested data. Not called if there is an error. | |
| 1119 | -**/ | |
| 1120 | -- (void)socket:(GCDAsyncSocket *)sock didWriteDataWithTag:(long)tag; | |
| 1121 | - | |
| 1122 | -/** | |
| 1123 | - * Called when a socket has written some data, but has not yet completed the entire write. | |
| 1124 | - * It may be used to for things such as updating progress bars. | |
| 1125 | -**/ | |
| 1126 | -- (void)socket:(GCDAsyncSocket *)sock didWritePartialDataOfLength:(NSUInteger)partialLength tag:(long)tag; | |
| 1127 | - | |
| 1128 | -/** | |
| 1129 | - * Called if a read operation has reached its timeout without completing. | |
| 1130 | - * This method allows you to optionally extend the timeout. | |
| 1131 | - * If you return a positive time interval (> 0) the read's timeout will be extended by the given amount. | |
| 1132 | - * If you don't implement this method, or return a non-positive time interval (<= 0) the read will timeout as usual. | |
| 1133 | - * | |
| 1134 | - * The elapsed parameter is the sum of the original timeout, plus any additions previously added via this method. | |
| 1135 | - * The length parameter is the number of bytes that have been read so far for the read operation. | |
| 1136 | - * | |
| 1137 | - * Note that this method may be called multiple times for a single read if you return positive numbers. | |
| 1138 | -**/ | |
| 1139 | -- (NSTimeInterval)socket:(GCDAsyncSocket *)sock shouldTimeoutReadWithTag:(long)tag | |
| 1140 | - elapsed:(NSTimeInterval)elapsed | |
| 1141 | - bytesDone:(NSUInteger)length; | |
| 1142 | - | |
| 1143 | -/** | |
| 1144 | - * Called if a write operation has reached its timeout without completing. | |
| 1145 | - * This method allows you to optionally extend the timeout. | |
| 1146 | - * If you return a positive time interval (> 0) the write's timeout will be extended by the given amount. | |
| 1147 | - * If you don't implement this method, or return a non-positive time interval (<= 0) the write will timeout as usual. | |
| 1148 | - * | |
| 1149 | - * The elapsed parameter is the sum of the original timeout, plus any additions previously added via this method. | |
| 1150 | - * The length parameter is the number of bytes that have been written so far for the write operation. | |
| 1151 | - * | |
| 1152 | - * Note that this method may be called multiple times for a single write if you return positive numbers. | |
| 1153 | -**/ | |
| 1154 | -- (NSTimeInterval)socket:(GCDAsyncSocket *)sock shouldTimeoutWriteWithTag:(long)tag | |
| 1155 | - elapsed:(NSTimeInterval)elapsed | |
| 1156 | - bytesDone:(NSUInteger)length; | |
| 1157 | - | |
| 1158 | -/** | |
| 1159 | - * Conditionally called if the read stream closes, but the write stream may still be writeable. | |
| 1160 | - * | |
| 1161 | - * This delegate method is only called if autoDisconnectOnClosedReadStream has been set to NO. | |
| 1162 | - * See the discussion on the autoDisconnectOnClosedReadStream method for more information. | |
| 1163 | -**/ | |
| 1164 | -- (void)socketDidCloseReadStream:(GCDAsyncSocket *)sock; | |
| 1165 | - | |
| 1166 | -/** | |
| 1167 | - * Called when a socket disconnects with or without error. | |
| 1168 | - * | |
| 1169 | - * If you call the disconnect method, and the socket wasn't already disconnected, | |
| 1170 | - * then an invocation of this delegate method will be enqueued on the delegateQueue | |
| 1171 | - * before the disconnect method returns. | |
| 1172 | - * | |
| 1173 | - * Note: If the GCDAsyncSocket instance is deallocated while it is still connected, | |
| 1174 | - * and the delegate is not also deallocated, then this method will be invoked, | |
| 1175 | - * but the sock parameter will be nil. (It must necessarily be nil since it is no longer available.) | |
| 1176 | - * This is a generally rare, but is possible if one writes code like this: | |
| 1177 | - * | |
| 1178 | - * asyncSocket = nil; // I'm implicitly disconnecting the socket | |
| 1179 | - * | |
| 1180 | - * In this case it may preferrable to nil the delegate beforehand, like this: | |
| 1181 | - * | |
| 1182 | - * asyncSocket.delegate = nil; // Don't invoke my delegate method | |
| 1183 | - * asyncSocket = nil; // I'm implicitly disconnecting the socket | |
| 1184 | - * | |
| 1185 | - * Of course, this depends on how your state machine is configured. | |
| 1186 | -**/ | |
| 1187 | -- (void)socketDidDisconnect:(GCDAsyncSocket *)sock withError:(nullable NSError *)err; | |
| 1188 | - | |
| 1189 | -/** | |
| 1190 | - * Called after the socket has successfully completed SSL/TLS negotiation. | |
| 1191 | - * This method is not called unless you use the provided startTLS method. | |
| 1192 | - * | |
| 1193 | - * If a SSL/TLS negotiation fails (invalid certificate, etc) then the socket will immediately close, | |
| 1194 | - * and the socketDidDisconnect:withError: delegate method will be called with the specific SSL error code. | |
| 1195 | -**/ | |
| 1196 | -- (void)socketDidSecure:(GCDAsyncSocket *)sock; | |
| 1197 | - | |
| 1198 | -/** | |
| 1199 | - * Allows a socket delegate to hook into the TLS handshake and manually validate the peer it's connecting to. | |
| 1200 | - * | |
| 1201 | - * This is only called if startTLS is invoked with options that include: | |
| 1202 | - * - GCDAsyncSocketManuallyEvaluateTrust == YES | |
| 1203 | - * | |
| 1204 | - * Typically the delegate will use SecTrustEvaluate (and related functions) to properly validate the peer. | |
| 1205 | - * | |
| 1206 | - * Note from Apple's documentation: | |
| 1207 | - * Because [SecTrustEvaluate] might look on the network for certificates in the certificate chain, | |
| 1208 | - * [it] might block while attempting network access. You should never call it from your main thread; | |
| 1209 | - * call it only from within a function running on a dispatch queue or on a separate thread. | |
| 1210 | - * | |
| 1211 | - * Thus this method uses a completionHandler block rather than a normal return value. | |
| 1212 | - * The completionHandler block is thread-safe, and may be invoked from a background queue/thread. | |
| 1213 | - * It is safe to invoke the completionHandler block even if the socket has been closed. | |
| 1214 | -**/ | |
| 1215 | -- (void)socket:(GCDAsyncSocket *)sock didReceiveTrust:(SecTrustRef)trust | |
| 1216 | - completionHandler:(void (^)(BOOL shouldTrustPeer))completionHandler; | |
| 1217 | - | |
| 1218 | -@end | |
| 1219 | -NS_ASSUME_NONNULL_END |
Example/build/Debug-iphoneos/CocoaAsyncSocket/CocoaAsyncSocket.framework/Headers/GCDAsyncUdpSocket.h deleted
100644 → 0
| 1 | -// | |
| 2 | -// GCDAsyncUdpSocket | |
| 3 | -// | |
| 4 | -// This class is in the public domain. | |
| 5 | -// Originally created by Robbie Hanson of Deusty LLC. | |
| 6 | -// Updated and maintained by Deusty LLC and the Apple development community. | |
| 7 | -// | |
| 8 | -// https://github.com/robbiehanson/CocoaAsyncSocket | |
| 9 | -// | |
| 10 | - | |
| 11 | -#import <Foundation/Foundation.h> | |
| 12 | -#import <dispatch/dispatch.h> | |
| 13 | -#import <TargetConditionals.h> | |
| 14 | -#import <Availability.h> | |
| 15 | - | |
| 16 | -NS_ASSUME_NONNULL_BEGIN | |
| 17 | -extern NSString *const GCDAsyncUdpSocketException; | |
| 18 | -extern NSString *const GCDAsyncUdpSocketErrorDomain; | |
| 19 | - | |
| 20 | -extern NSString *const GCDAsyncUdpSocketQueueName; | |
| 21 | -extern NSString *const GCDAsyncUdpSocketThreadName; | |
| 22 | - | |
| 23 | -typedef NS_ENUM(NSInteger, GCDAsyncUdpSocketError) { | |
| 24 | - GCDAsyncUdpSocketNoError = 0, // Never used | |
| 25 | - GCDAsyncUdpSocketBadConfigError, // Invalid configuration | |
| 26 | - GCDAsyncUdpSocketBadParamError, // Invalid parameter was passed | |
| 27 | - GCDAsyncUdpSocketSendTimeoutError, // A send operation timed out | |
| 28 | - GCDAsyncUdpSocketClosedError, // The socket was closed | |
| 29 | - GCDAsyncUdpSocketOtherError, // Description provided in userInfo | |
| 30 | -}; | |
| 31 | - | |
| 32 | -//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | |
| 33 | -#pragma mark - | |
| 34 | -//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | |
| 35 | - | |
| 36 | -@class GCDAsyncUdpSocket; | |
| 37 | - | |
| 38 | -@protocol GCDAsyncUdpSocketDelegate <NSObject> | |
| 39 | -@optional | |
| 40 | - | |
| 41 | -/** | |
| 42 | - * By design, UDP is a connectionless protocol, and connecting is not needed. | |
| 43 | - * However, you may optionally choose to connect to a particular host for reasons | |
| 44 | - * outlined in the documentation for the various connect methods listed above. | |
| 45 | - * | |
| 46 | - * This method is called if one of the connect methods are invoked, and the connection is successful. | |
| 47 | -**/ | |
| 48 | -- (void)udpSocket:(GCDAsyncUdpSocket *)sock didConnectToAddress:(NSData *)address; | |
| 49 | - | |
| 50 | -/** | |
| 51 | - * By design, UDP is a connectionless protocol, and connecting is not needed. | |
| 52 | - * However, you may optionally choose to connect to a particular host for reasons | |
| 53 | - * outlined in the documentation for the various connect methods listed above. | |
| 54 | - * | |
| 55 | - * This method is called if one of the connect methods are invoked, and the connection fails. | |
| 56 | - * This may happen, for example, if a domain name is given for the host and the domain name is unable to be resolved. | |
| 57 | -**/ | |
| 58 | -- (void)udpSocket:(GCDAsyncUdpSocket *)sock didNotConnect:(NSError * _Nullable)error; | |
| 59 | - | |
| 60 | -/** | |
| 61 | - * Called when the datagram with the given tag has been sent. | |
| 62 | -**/ | |
| 63 | -- (void)udpSocket:(GCDAsyncUdpSocket *)sock didSendDataWithTag:(long)tag; | |
| 64 | - | |
| 65 | -/** | |
| 66 | - * Called if an error occurs while trying to send a datagram. | |
| 67 | - * This could be due to a timeout, or something more serious such as the data being too large to fit in a sigle packet. | |
| 68 | -**/ | |
| 69 | -- (void)udpSocket:(GCDAsyncUdpSocket *)sock didNotSendDataWithTag:(long)tag dueToError:(NSError * _Nullable)error; | |
| 70 | - | |
| 71 | -/** | |
| 72 | - * Called when the socket has received the requested datagram. | |
| 73 | -**/ | |
| 74 | -- (void)udpSocket:(GCDAsyncUdpSocket *)sock didReceiveData:(NSData *)data | |
| 75 | - fromAddress:(NSData *)address | |
| 76 | - withFilterContext:(nullable id)filterContext; | |
| 77 | - | |
| 78 | -/** | |
| 79 | - * Called when the socket is closed. | |
| 80 | -**/ | |
| 81 | -- (void)udpSocketDidClose:(GCDAsyncUdpSocket *)sock withError:(NSError * _Nullable)error; | |
| 82 | - | |
| 83 | -@end | |
| 84 | - | |
| 85 | -/** | |
| 86 | - * You may optionally set a receive filter for the socket. | |
| 87 | - * A filter can provide several useful features: | |
| 88 | - * | |
| 89 | - * 1. Many times udp packets need to be parsed. | |
| 90 | - * Since the filter can run in its own independent queue, you can parallelize this parsing quite easily. | |
| 91 | - * The end result is a parallel socket io, datagram parsing, and packet processing. | |
| 92 | - * | |
| 93 | - * 2. Many times udp packets are discarded because they are duplicate/unneeded/unsolicited. | |
| 94 | - * The filter can prevent such packets from arriving at the delegate. | |
| 95 | - * And because the filter can run in its own independent queue, this doesn't slow down the delegate. | |
| 96 | - * | |
| 97 | - * - Since the udp protocol does not guarantee delivery, udp packets may be lost. | |
| 98 | - * Many protocols built atop udp thus provide various resend/re-request algorithms. | |
| 99 | - * This sometimes results in duplicate packets arriving. | |
| 100 | - * A filter may allow you to architect the duplicate detection code to run in parallel to normal processing. | |
| 101 | - * | |
| 102 | - * - Since the udp socket may be connectionless, its possible for unsolicited packets to arrive. | |
| 103 | - * Such packets need to be ignored. | |
| 104 | - * | |
| 105 | - * 3. Sometimes traffic shapers are needed to simulate real world environments. | |
| 106 | - * A filter allows you to write custom code to simulate such environments. | |
| 107 | - * The ability to code this yourself is especially helpful when your simulated environment | |
| 108 | - * is more complicated than simple traffic shaping (e.g. simulating a cone port restricted router), | |
| 109 | - * or the system tools to handle this aren't available (e.g. on a mobile device). | |
| 110 | - * | |
| 111 | - * @param data - The packet that was received. | |
| 112 | - * @param address - The address the data was received from. | |
| 113 | - * See utilities section for methods to extract info from address. | |
| 114 | - * @param context - Out parameter you may optionally set, which will then be passed to the delegate method. | |
| 115 | - * For example, filter block can parse the data and then, | |
| 116 | - * pass the parsed data to the delegate. | |
| 117 | - * | |
| 118 | - * @returns - YES if the received packet should be passed onto the delegate. | |
| 119 | - * NO if the received packet should be discarded, and not reported to the delegete. | |
| 120 | - * | |
| 121 | - * Example: | |
| 122 | - * | |
| 123 | - * GCDAsyncUdpSocketReceiveFilterBlock filter = ^BOOL (NSData *data, NSData *address, id *context) { | |
| 124 | - * | |
| 125 | - * MyProtocolMessage *msg = [MyProtocol parseMessage:data]; | |
| 126 | - * | |
| 127 | - * *context = response; | |
| 128 | - * return (response != nil); | |
| 129 | - * }; | |
| 130 | - * [udpSocket setReceiveFilter:filter withQueue:myParsingQueue]; | |
| 131 | - * | |
| 132 | -**/ | |
| 133 | -typedef BOOL (^GCDAsyncUdpSocketReceiveFilterBlock)(NSData *data, NSData *address, id __nullable * __nonnull context); | |
| 134 | - | |
| 135 | -/** | |
| 136 | - * You may optionally set a send filter for the socket. | |
| 137 | - * A filter can provide several interesting possibilities: | |
| 138 | - * | |
| 139 | - * 1. Optional caching of resolved addresses for domain names. | |
| 140 | - * The cache could later be consulted, resulting in fewer system calls to getaddrinfo. | |
| 141 | - * | |
| 142 | - * 2. Reusable modules of code for bandwidth monitoring. | |
| 143 | - * | |
| 144 | - * 3. Sometimes traffic shapers are needed to simulate real world environments. | |
| 145 | - * A filter allows you to write custom code to simulate such environments. | |
| 146 | - * The ability to code this yourself is especially helpful when your simulated environment | |
| 147 | - * is more complicated than simple traffic shaping (e.g. simulating a cone port restricted router), | |
| 148 | - * or the system tools to handle this aren't available (e.g. on a mobile device). | |
| 149 | - * | |
| 150 | - * @param data - The packet that was received. | |
| 151 | - * @param address - The address the data was received from. | |
| 152 | - * See utilities section for methods to extract info from address. | |
| 153 | - * @param tag - The tag that was passed in the send method. | |
| 154 | - * | |
| 155 | - * @returns - YES if the packet should actually be sent over the socket. | |
| 156 | - * NO if the packet should be silently dropped (not sent over the socket). | |
| 157 | - * | |
| 158 | - * Regardless of the return value, the delegate will be informed that the packet was successfully sent. | |
| 159 | - * | |
| 160 | -**/ | |
| 161 | -typedef BOOL (^GCDAsyncUdpSocketSendFilterBlock)(NSData *data, NSData *address, long tag); | |
| 162 | - | |
| 163 | - | |
| 164 | -@interface GCDAsyncUdpSocket : NSObject | |
| 165 | - | |
| 166 | -/** | |
| 167 | - * GCDAsyncUdpSocket uses the standard delegate paradigm, | |
| 168 | - * but executes all delegate callbacks on a given delegate dispatch queue. | |
| 169 | - * This allows for maximum concurrency, while at the same time providing easy thread safety. | |
| 170 | - * | |
| 171 | - * You MUST set a delegate AND delegate dispatch queue before attempting to | |
| 172 | - * use the socket, or you will get an error. | |
| 173 | - * | |
| 174 | - * The socket queue is optional. | |
| 175 | - * If you pass NULL, GCDAsyncSocket will automatically create its own socket queue. | |
| 176 | - * If you choose to provide a socket queue, the socket queue must not be a concurrent queue, | |
| 177 | - * then please see the discussion for the method markSocketQueueTargetQueue. | |
| 178 | - * | |
| 179 | - * The delegate queue and socket queue can optionally be the same. | |
| 180 | -**/ | |
| 181 | -- (instancetype)init; | |
| 182 | -- (instancetype)initWithSocketQueue:(nullable dispatch_queue_t)sq; | |
| 183 | -- (instancetype)initWithDelegate:(nullable id <GCDAsyncUdpSocketDelegate>)aDelegate delegateQueue:(nullable dispatch_queue_t)dq; | |
| 184 | -- (instancetype)initWithDelegate:(nullable id <GCDAsyncUdpSocketDelegate>)aDelegate delegateQueue:(nullable dispatch_queue_t)dq socketQueue:(nullable dispatch_queue_t)sq; | |
| 185 | - | |
| 186 | -#pragma mark Configuration | |
| 187 | - | |
| 188 | -- (nullable id <GCDAsyncUdpSocketDelegate>)delegate; | |
| 189 | -- (void)setDelegate:(nullable id <GCDAsyncUdpSocketDelegate>)delegate; | |
| 190 | -- (void)synchronouslySetDelegate:(nullable id <GCDAsyncUdpSocketDelegate>)delegate; | |
| 191 | - | |
| 192 | -- (nullable dispatch_queue_t)delegateQueue; | |
| 193 | -- (void)setDelegateQueue:(nullable dispatch_queue_t)delegateQueue; | |
| 194 | -- (void)synchronouslySetDelegateQueue:(nullable dispatch_queue_t)delegateQueue; | |
| 195 | - | |
| 196 | -- (void)getDelegate:(id <GCDAsyncUdpSocketDelegate> __nullable * __nullable)delegatePtr delegateQueue:(dispatch_queue_t __nullable * __nullable)delegateQueuePtr; | |
| 197 | -- (void)setDelegate:(nullable id <GCDAsyncUdpSocketDelegate>)delegate delegateQueue:(nullable dispatch_queue_t)delegateQueue; | |
| 198 | -- (void)synchronouslySetDelegate:(nullable id <GCDAsyncUdpSocketDelegate>)delegate delegateQueue:(nullable dispatch_queue_t)delegateQueue; | |
| 199 | - | |
| 200 | -/** | |
| 201 | - * By default, both IPv4 and IPv6 are enabled. | |
| 202 | - * | |
| 203 | - * This means GCDAsyncUdpSocket automatically supports both protocols, | |
| 204 | - * and can send to IPv4 or IPv6 addresses, | |
| 205 | - * as well as receive over IPv4 and IPv6. | |
| 206 | - * | |
| 207 | - * For operations that require DNS resolution, GCDAsyncUdpSocket supports both IPv4 and IPv6. | |
| 208 | - * If a DNS lookup returns only IPv4 results, GCDAsyncUdpSocket will automatically use IPv4. | |
| 209 | - * If a DNS lookup returns only IPv6 results, GCDAsyncUdpSocket will automatically use IPv6. | |
| 210 | - * If a DNS lookup returns both IPv4 and IPv6 results, then the protocol used depends on the configured preference. | |
| 211 | - * If IPv4 is preferred, then IPv4 is used. | |
| 212 | - * If IPv6 is preferred, then IPv6 is used. | |
| 213 | - * If neutral, then the first IP version in the resolved array will be used. | |
| 214 | - * | |
| 215 | - * Starting with Mac OS X 10.7 Lion and iOS 5, the default IP preference is neutral. | |
| 216 | - * On prior systems the default IP preference is IPv4. | |
| 217 | - **/ | |
| 218 | -- (BOOL)isIPv4Enabled; | |
| 219 | -- (void)setIPv4Enabled:(BOOL)flag; | |
| 220 | - | |
| 221 | -- (BOOL)isIPv6Enabled; | |
| 222 | -- (void)setIPv6Enabled:(BOOL)flag; | |
| 223 | - | |
| 224 | -- (BOOL)isIPv4Preferred; | |
| 225 | -- (BOOL)isIPv6Preferred; | |
| 226 | -- (BOOL)isIPVersionNeutral; | |
| 227 | - | |
| 228 | -- (void)setPreferIPv4; | |
| 229 | -- (void)setPreferIPv6; | |
| 230 | -- (void)setIPVersionNeutral; | |
| 231 | - | |
| 232 | -/** | |
| 233 | - * Gets/Sets the maximum size of the buffer that will be allocated for receive operations. | |
| 234 | - * The default maximum size is 65535 bytes. | |
| 235 | - * | |
| 236 | - * The theoretical maximum size of any IPv4 UDP packet is UINT16_MAX = 65535. | |
| 237 | - * The theoretical maximum size of any IPv6 UDP packet is UINT32_MAX = 4294967295. | |
| 238 | - * | |
| 239 | - * Since the OS/GCD notifies us of the size of each received UDP packet, | |
| 240 | - * the actual allocated buffer size for each packet is exact. | |
| 241 | - * And in practice the size of UDP packets is generally much smaller than the max. | |
| 242 | - * Indeed most protocols will send and receive packets of only a few bytes, | |
| 243 | - * or will set a limit on the size of packets to prevent fragmentation in the IP layer. | |
| 244 | - * | |
| 245 | - * If you set the buffer size too small, the sockets API in the OS will silently discard | |
| 246 | - * any extra data, and you will not be notified of the error. | |
| 247 | -**/ | |
| 248 | -- (uint16_t)maxReceiveIPv4BufferSize; | |
| 249 | -- (void)setMaxReceiveIPv4BufferSize:(uint16_t)max; | |
| 250 | - | |
| 251 | -- (uint32_t)maxReceiveIPv6BufferSize; | |
| 252 | -- (void)setMaxReceiveIPv6BufferSize:(uint32_t)max; | |
| 253 | - | |
| 254 | -/** | |
| 255 | - * Gets/Sets the maximum size of the buffer that will be allocated for send operations. | |
| 256 | - * The default maximum size is 65535 bytes. | |
| 257 | - * | |
| 258 | - * Given that a typical link MTU is 1500 bytes, a large UDP datagram will have to be | |
| 259 | - * fragmented, and that’s both expensive and risky (if one fragment goes missing, the | |
| 260 | - * entire datagram is lost). You are much better off sending a large number of smaller | |
| 261 | - * UDP datagrams, preferably using a path MTU algorithm to avoid fragmentation. | |
| 262 | - * | |
| 263 | - * You must set it before the sockt is created otherwise it won't work. | |
| 264 | - * | |
| 265 | - **/ | |
| 266 | -- (uint16_t)maxSendBufferSize; | |
| 267 | -- (void)setMaxSendBufferSize:(uint16_t)max; | |
| 268 | - | |
| 269 | -/** | |
| 270 | - * User data allows you to associate arbitrary information with the socket. | |
| 271 | - * This data is not used internally in any way. | |
| 272 | -**/ | |
| 273 | -- (nullable id)userData; | |
| 274 | -- (void)setUserData:(nullable id)arbitraryUserData; | |
| 275 | - | |
| 276 | -#pragma mark Diagnostics | |
| 277 | - | |
| 278 | -/** | |
| 279 | - * Returns the local address info for the socket. | |
| 280 | - * | |
| 281 | - * The localAddress method returns a sockaddr structure wrapped in a NSData object. | |
| 282 | - * The localHost method returns the human readable IP address as a string. | |
| 283 | - * | |
| 284 | - * Note: Address info may not be available until after the socket has been binded, connected | |
| 285 | - * or until after data has been sent. | |
| 286 | -**/ | |
| 287 | -- (nullable NSData *)localAddress; | |
| 288 | -- (nullable NSString *)localHost; | |
| 289 | -- (uint16_t)localPort; | |
| 290 | - | |
| 291 | -- (nullable NSData *)localAddress_IPv4; | |
| 292 | -- (nullable NSString *)localHost_IPv4; | |
| 293 | -- (uint16_t)localPort_IPv4; | |
| 294 | - | |
| 295 | -- (nullable NSData *)localAddress_IPv6; | |
| 296 | -- (nullable NSString *)localHost_IPv6; | |
| 297 | -- (uint16_t)localPort_IPv6; | |
| 298 | - | |
| 299 | -/** | |
| 300 | - * Returns the remote address info for the socket. | |
| 301 | - * | |
| 302 | - * The connectedAddress method returns a sockaddr structure wrapped in a NSData object. | |
| 303 | - * The connectedHost method returns the human readable IP address as a string. | |
| 304 | - * | |
| 305 | - * Note: Since UDP is connectionless by design, connected address info | |
| 306 | - * will not be available unless the socket is explicitly connected to a remote host/port. | |
| 307 | - * If the socket is not connected, these methods will return nil / 0. | |
| 308 | -**/ | |
| 309 | -- (nullable NSData *)connectedAddress; | |
| 310 | -- (nullable NSString *)connectedHost; | |
| 311 | -- (uint16_t)connectedPort; | |
| 312 | - | |
| 313 | -/** | |
| 314 | - * Returns whether or not this socket has been connected to a single host. | |
| 315 | - * By design, UDP is a connectionless protocol, and connecting is not needed. | |
| 316 | - * If connected, the socket will only be able to send/receive data to/from the connected host. | |
| 317 | -**/ | |
| 318 | -- (BOOL)isConnected; | |
| 319 | - | |
| 320 | -/** | |
| 321 | - * Returns whether or not this socket has been closed. | |
| 322 | - * The only way a socket can be closed is if you explicitly call one of the close methods. | |
| 323 | -**/ | |
| 324 | -- (BOOL)isClosed; | |
| 325 | - | |
| 326 | -/** | |
| 327 | - * Returns whether or not this socket is IPv4. | |
| 328 | - * | |
| 329 | - * By default this will be true, unless: | |
| 330 | - * - IPv4 is disabled (via setIPv4Enabled:) | |
| 331 | - * - The socket is explicitly bound to an IPv6 address | |
| 332 | - * - The socket is connected to an IPv6 address | |
| 333 | -**/ | |
| 334 | -- (BOOL)isIPv4; | |
| 335 | - | |
| 336 | -/** | |
| 337 | - * Returns whether or not this socket is IPv6. | |
| 338 | - * | |
| 339 | - * By default this will be true, unless: | |
| 340 | - * - IPv6 is disabled (via setIPv6Enabled:) | |
| 341 | - * - The socket is explicitly bound to an IPv4 address | |
| 342 | - * _ The socket is connected to an IPv4 address | |
| 343 | - * | |
| 344 | - * This method will also return false on platforms that do not support IPv6. | |
| 345 | - * Note: The iPhone does not currently support IPv6. | |
| 346 | -**/ | |
| 347 | -- (BOOL)isIPv6; | |
| 348 | - | |
| 349 | -#pragma mark Binding | |
| 350 | - | |
| 351 | -/** | |
| 352 | - * Binds the UDP socket to the given port. | |
| 353 | - * Binding should be done for server sockets that receive data prior to sending it. | |
| 354 | - * Client sockets can skip binding, | |
| 355 | - * as the OS will automatically assign the socket an available port when it starts sending data. | |
| 356 | - * | |
| 357 | - * You may optionally pass a port number of zero to immediately bind the socket, | |
| 358 | - * yet still allow the OS to automatically assign an available port. | |
| 359 | - * | |
| 360 | - * You cannot bind a socket after its been connected. | |
| 361 | - * You can only bind a socket once. | |
| 362 | - * You can still connect a socket (if desired) after binding. | |
| 363 | - * | |
| 364 | - * On success, returns YES. | |
| 365 | - * Otherwise returns NO, and sets errPtr. If you don't care about the error, you can pass NULL for errPtr. | |
| 366 | -**/ | |
| 367 | -- (BOOL)bindToPort:(uint16_t)port error:(NSError **)errPtr; | |
| 368 | - | |
| 369 | -/** | |
| 370 | - * Binds the UDP socket to the given port and optional interface. | |
| 371 | - * Binding should be done for server sockets that receive data prior to sending it. | |
| 372 | - * Client sockets can skip binding, | |
| 373 | - * as the OS will automatically assign the socket an available port when it starts sending data. | |
| 374 | - * | |
| 375 | - * You may optionally pass a port number of zero to immediately bind the socket, | |
| 376 | - * yet still allow the OS to automatically assign an available port. | |
| 377 | - * | |
| 378 | - * The interface may be a name (e.g. "en1" or "lo0") or the corresponding IP address (e.g. "192.168.4.35"). | |
| 379 | - * You may also use the special strings "localhost" or "loopback" to specify that | |
| 380 | - * the socket only accept packets from the local machine. | |
| 381 | - * | |
| 382 | - * You cannot bind a socket after its been connected. | |
| 383 | - * You can only bind a socket once. | |
| 384 | - * You can still connect a socket (if desired) after binding. | |
| 385 | - * | |
| 386 | - * On success, returns YES. | |
| 387 | - * Otherwise returns NO, and sets errPtr. If you don't care about the error, you can pass NULL for errPtr. | |
| 388 | -**/ | |
| 389 | -- (BOOL)bindToPort:(uint16_t)port interface:(nullable NSString *)interface error:(NSError **)errPtr; | |
| 390 | - | |
| 391 | -/** | |
| 392 | - * Binds the UDP socket to the given address, specified as a sockaddr structure wrapped in a NSData object. | |
| 393 | - * | |
| 394 | - * If you have an existing struct sockaddr you can convert it to a NSData object like so: | |
| 395 | - * struct sockaddr sa -> NSData *dsa = [NSData dataWithBytes:&remoteAddr length:remoteAddr.sa_len]; | |
| 396 | - * struct sockaddr *sa -> NSData *dsa = [NSData dataWithBytes:remoteAddr length:remoteAddr->sa_len]; | |
| 397 | - * | |
| 398 | - * Binding should be done for server sockets that receive data prior to sending it. | |
| 399 | - * Client sockets can skip binding, | |
| 400 | - * as the OS will automatically assign the socket an available port when it starts sending data. | |
| 401 | - * | |
| 402 | - * You cannot bind a socket after its been connected. | |
| 403 | - * You can only bind a socket once. | |
| 404 | - * You can still connect a socket (if desired) after binding. | |
| 405 | - * | |
| 406 | - * On success, returns YES. | |
| 407 | - * Otherwise returns NO, and sets errPtr. If you don't care about the error, you can pass NULL for errPtr. | |
| 408 | -**/ | |
| 409 | -- (BOOL)bindToAddress:(NSData *)localAddr error:(NSError **)errPtr; | |
| 410 | - | |
| 411 | -#pragma mark Connecting | |
| 412 | - | |
| 413 | -/** | |
| 414 | - * Connects the UDP socket to the given host and port. | |
| 415 | - * By design, UDP is a connectionless protocol, and connecting is not needed. | |
| 416 | - * | |
| 417 | - * Choosing to connect to a specific host/port has the following effect: | |
| 418 | - * - You will only be able to send data to the connected host/port. | |
| 419 | - * - You will only be able to receive data from the connected host/port. | |
| 420 | - * - You will receive ICMP messages that come from the connected host/port, such as "connection refused". | |
| 421 | - * | |
| 422 | - * The actual process of connecting a UDP socket does not result in any communication on the socket. | |
| 423 | - * It simply changes the internal state of the socket. | |
| 424 | - * | |
| 425 | - * You cannot bind a socket after it has been connected. | |
| 426 | - * You can only connect a socket once. | |
| 427 | - * | |
| 428 | - * The host may be a domain name (e.g. "deusty.com") or an IP address string (e.g. "192.168.0.2"). | |
| 429 | - * | |
| 430 | - * This method is asynchronous as it requires a DNS lookup to resolve the given host name. | |
| 431 | - * If an obvious error is detected, this method immediately returns NO and sets errPtr. | |
| 432 | - * If you don't care about the error, you can pass nil for errPtr. | |
| 433 | - * Otherwise, this method returns YES and begins the asynchronous connection process. | |
| 434 | - * The result of the asynchronous connection process will be reported via the delegate methods. | |
| 435 | - **/ | |
| 436 | -- (BOOL)connectToHost:(NSString *)host onPort:(uint16_t)port error:(NSError **)errPtr; | |
| 437 | - | |
| 438 | -/** | |
| 439 | - * Connects the UDP socket to the given address, specified as a sockaddr structure wrapped in a NSData object. | |
| 440 | - * | |
| 441 | - * If you have an existing struct sockaddr you can convert it to a NSData object like so: | |
| 442 | - * struct sockaddr sa -> NSData *dsa = [NSData dataWithBytes:&remoteAddr length:remoteAddr.sa_len]; | |
| 443 | - * struct sockaddr *sa -> NSData *dsa = [NSData dataWithBytes:remoteAddr length:remoteAddr->sa_len]; | |
| 444 | - * | |
| 445 | - * By design, UDP is a connectionless protocol, and connecting is not needed. | |
| 446 | - * | |
| 447 | - * Choosing to connect to a specific address has the following effect: | |
| 448 | - * - You will only be able to send data to the connected address. | |
| 449 | - * - You will only be able to receive data from the connected address. | |
| 450 | - * - You will receive ICMP messages that come from the connected address, such as "connection refused". | |
| 451 | - * | |
| 452 | - * Connecting a UDP socket does not result in any communication on the socket. | |
| 453 | - * It simply changes the internal state of the socket. | |
| 454 | - * | |
| 455 | - * You cannot bind a socket after its been connected. | |
| 456 | - * You can only connect a socket once. | |
| 457 | - * | |
| 458 | - * On success, returns YES. | |
| 459 | - * Otherwise returns NO, and sets errPtr. If you don't care about the error, you can pass nil for errPtr. | |
| 460 | - * | |
| 461 | - * Note: Unlike the connectToHost:onPort:error: method, this method does not require a DNS lookup. | |
| 462 | - * Thus when this method returns, the connection has either failed or fully completed. | |
| 463 | - * In other words, this method is synchronous, unlike the asynchronous connectToHost::: method. | |
| 464 | - * However, for compatibility and simplification of delegate code, if this method returns YES | |
| 465 | - * then the corresponding delegate method (udpSocket:didConnectToHost:port:) is still invoked. | |
| 466 | -**/ | |
| 467 | -- (BOOL)connectToAddress:(NSData *)remoteAddr error:(NSError **)errPtr; | |
| 468 | - | |
| 469 | -#pragma mark Multicast | |
| 470 | - | |
| 471 | -/** | |
| 472 | - * Join multicast group. | |
| 473 | - * Group should be an IP address (eg @"225.228.0.1"). | |
| 474 | - * | |
| 475 | - * On success, returns YES. | |
| 476 | - * Otherwise returns NO, and sets errPtr. If you don't care about the error, you can pass nil for errPtr. | |
| 477 | -**/ | |
| 478 | -- (BOOL)joinMulticastGroup:(NSString *)group error:(NSError **)errPtr; | |
| 479 | - | |
| 480 | -/** | |
| 481 | - * Join multicast group. | |
| 482 | - * Group should be an IP address (eg @"225.228.0.1"). | |
| 483 | - * The interface may be a name (e.g. "en1" or "lo0") or the corresponding IP address (e.g. "192.168.4.35"). | |
| 484 | - * | |
| 485 | - * On success, returns YES. | |
| 486 | - * Otherwise returns NO, and sets errPtr. If you don't care about the error, you can pass nil for errPtr. | |
| 487 | -**/ | |
| 488 | -- (BOOL)joinMulticastGroup:(NSString *)group onInterface:(nullable NSString *)interface error:(NSError **)errPtr; | |
| 489 | - | |
| 490 | -- (BOOL)leaveMulticastGroup:(NSString *)group error:(NSError **)errPtr; | |
| 491 | -- (BOOL)leaveMulticastGroup:(NSString *)group onInterface:(nullable NSString *)interface error:(NSError **)errPtr; | |
| 492 | - | |
| 493 | -#pragma mark Reuse Port | |
| 494 | - | |
| 495 | -/** | |
| 496 | - * By default, only one socket can be bound to a given IP address + port at a time. | |
| 497 | - * To enable multiple processes to simultaneously bind to the same address+port, | |
| 498 | - * you need to enable this functionality in the socket. All processes that wish to | |
| 499 | - * use the address+port simultaneously must all enable reuse port on the socket | |
| 500 | - * bound to that port. | |
| 501 | - **/ | |
| 502 | -- (BOOL)enableReusePort:(BOOL)flag error:(NSError **)errPtr; | |
| 503 | - | |
| 504 | -#pragma mark Broadcast | |
| 505 | - | |
| 506 | -/** | |
| 507 | - * By default, the underlying socket in the OS will not allow you to send broadcast messages. | |
| 508 | - * In order to send broadcast messages, you need to enable this functionality in the socket. | |
| 509 | - * | |
| 510 | - * A broadcast is a UDP message to addresses like "192.168.255.255" or "255.255.255.255" that is | |
| 511 | - * delivered to every host on the network. | |
| 512 | - * The reason this is generally disabled by default (by the OS) is to prevent | |
| 513 | - * accidental broadcast messages from flooding the network. | |
| 514 | -**/ | |
| 515 | -- (BOOL)enableBroadcast:(BOOL)flag error:(NSError **)errPtr; | |
| 516 | - | |
| 517 | -#pragma mark Sending | |
| 518 | - | |
| 519 | -/** | |
| 520 | - * Asynchronously sends the given data, with the given timeout and tag. | |
| 521 | - * | |
| 522 | - * This method may only be used with a connected socket. | |
| 523 | - * Recall that connecting is optional for a UDP socket. | |
| 524 | - * For connected sockets, data can only be sent to the connected address. | |
| 525 | - * For non-connected sockets, the remote destination is specified for each packet. | |
| 526 | - * For more information about optionally connecting udp sockets, see the documentation for the connect methods above. | |
| 527 | - * | |
| 528 | - * @param data | |
| 529 | - * The data to send. | |
| 530 | - * If data is nil or zero-length, this method does nothing. | |
| 531 | - * If passing NSMutableData, please read the thread-safety notice below. | |
| 532 | - * | |
| 533 | - * @param timeout | |
| 534 | - * The timeout for the send opeartion. | |
| 535 | - * If the timeout value is negative, the send operation will not use a timeout. | |
| 536 | - * | |
| 537 | - * @param tag | |
| 538 | - * The tag is for your convenience. | |
| 539 | - * It is not sent or received over the socket in any manner what-so-ever. | |
| 540 | - * It is reported back as a parameter in the udpSocket:didSendDataWithTag: | |
| 541 | - * or udpSocket:didNotSendDataWithTag:dueToError: methods. | |
| 542 | - * You can use it as an array index, state id, type constant, etc. | |
| 543 | - * | |
| 544 | - * | |
| 545 | - * Thread-Safety Note: | |
| 546 | - * If the given data parameter is mutable (NSMutableData) then you MUST NOT alter the data while | |
| 547 | - * the socket is sending it. In other words, it's not safe to alter the data until after the delegate method | |
| 548 | - * udpSocket:didSendDataWithTag: or udpSocket:didNotSendDataWithTag:dueToError: is invoked signifying | |
| 549 | - * that this particular send operation has completed. | |
| 550 | - * This is due to the fact that GCDAsyncUdpSocket does NOT copy the data. | |
| 551 | - * It simply retains it for performance reasons. | |
| 552 | - * Often times, if NSMutableData is passed, it is because a request/response was built up in memory. | |
| 553 | - * Copying this data adds an unwanted/unneeded overhead. | |
| 554 | - * If you need to write data from an immutable buffer, and you need to alter the buffer before the socket | |
| 555 | - * completes sending the bytes (which is NOT immediately after this method returns, but rather at a later time | |
| 556 | - * when the delegate method notifies you), then you should first copy the bytes, and pass the copy to this method. | |
| 557 | -**/ | |
| 558 | -- (void)sendData:(NSData *)data withTimeout:(NSTimeInterval)timeout tag:(long)tag; | |
| 559 | - | |
| 560 | -/** | |
| 561 | - * Asynchronously sends the given data, with the given timeout and tag, to the given host and port. | |
| 562 | - * | |
| 563 | - * This method cannot be used with a connected socket. | |
| 564 | - * Recall that connecting is optional for a UDP socket. | |
| 565 | - * For connected sockets, data can only be sent to the connected address. | |
| 566 | - * For non-connected sockets, the remote destination is specified for each packet. | |
| 567 | - * For more information about optionally connecting udp sockets, see the documentation for the connect methods above. | |
| 568 | - * | |
| 569 | - * @param data | |
| 570 | - * The data to send. | |
| 571 | - * If data is nil or zero-length, this method does nothing. | |
| 572 | - * If passing NSMutableData, please read the thread-safety notice below. | |
| 573 | - * | |
| 574 | - * @param host | |
| 575 | - * The destination to send the udp packet to. | |
| 576 | - * May be specified as a domain name (e.g. "deusty.com") or an IP address string (e.g. "192.168.0.2"). | |
| 577 | - * You may also use the convenience strings of "loopback" or "localhost". | |
| 578 | - * | |
| 579 | - * @param port | |
| 580 | - * The port of the host to send to. | |
| 581 | - * | |
| 582 | - * @param timeout | |
| 583 | - * The timeout for the send opeartion. | |
| 584 | - * If the timeout value is negative, the send operation will not use a timeout. | |
| 585 | - * | |
| 586 | - * @param tag | |
| 587 | - * The tag is for your convenience. | |
| 588 | - * It is not sent or received over the socket in any manner what-so-ever. | |
| 589 | - * It is reported back as a parameter in the udpSocket:didSendDataWithTag: | |
| 590 | - * or udpSocket:didNotSendDataWithTag:dueToError: methods. | |
| 591 | - * You can use it as an array index, state id, type constant, etc. | |
| 592 | - * | |
| 593 | - * | |
| 594 | - * Thread-Safety Note: | |
| 595 | - * If the given data parameter is mutable (NSMutableData) then you MUST NOT alter the data while | |
| 596 | - * the socket is sending it. In other words, it's not safe to alter the data until after the delegate method | |
| 597 | - * udpSocket:didSendDataWithTag: or udpSocket:didNotSendDataWithTag:dueToError: is invoked signifying | |
| 598 | - * that this particular send operation has completed. | |
| 599 | - * This is due to the fact that GCDAsyncUdpSocket does NOT copy the data. | |
| 600 | - * It simply retains it for performance reasons. | |
| 601 | - * Often times, if NSMutableData is passed, it is because a request/response was built up in memory. | |
| 602 | - * Copying this data adds an unwanted/unneeded overhead. | |
| 603 | - * If you need to write data from an immutable buffer, and you need to alter the buffer before the socket | |
| 604 | - * completes sending the bytes (which is NOT immediately after this method returns, but rather at a later time | |
| 605 | - * when the delegate method notifies you), then you should first copy the bytes, and pass the copy to this method. | |
| 606 | -**/ | |
| 607 | -- (void)sendData:(NSData *)data | |
| 608 | - toHost:(NSString *)host | |
| 609 | - port:(uint16_t)port | |
| 610 | - withTimeout:(NSTimeInterval)timeout | |
| 611 | - tag:(long)tag; | |
| 612 | - | |
| 613 | -/** | |
| 614 | - * Asynchronously sends the given data, with the given timeout and tag, to the given address. | |
| 615 | - * | |
| 616 | - * This method cannot be used with a connected socket. | |
| 617 | - * Recall that connecting is optional for a UDP socket. | |
| 618 | - * For connected sockets, data can only be sent to the connected address. | |
| 619 | - * For non-connected sockets, the remote destination is specified for each packet. | |
| 620 | - * For more information about optionally connecting udp sockets, see the documentation for the connect methods above. | |
| 621 | - * | |
| 622 | - * @param data | |
| 623 | - * The data to send. | |
| 624 | - * If data is nil or zero-length, this method does nothing. | |
| 625 | - * If passing NSMutableData, please read the thread-safety notice below. | |
| 626 | - * | |
| 627 | - * @param remoteAddr | |
| 628 | - * The address to send the data to (specified as a sockaddr structure wrapped in a NSData object). | |
| 629 | - * | |
| 630 | - * @param timeout | |
| 631 | - * The timeout for the send opeartion. | |
| 632 | - * If the timeout value is negative, the send operation will not use a timeout. | |
| 633 | - * | |
| 634 | - * @param tag | |
| 635 | - * The tag is for your convenience. | |
| 636 | - * It is not sent or received over the socket in any manner what-so-ever. | |
| 637 | - * It is reported back as a parameter in the udpSocket:didSendDataWithTag: | |
| 638 | - * or udpSocket:didNotSendDataWithTag:dueToError: methods. | |
| 639 | - * You can use it as an array index, state id, type constant, etc. | |
| 640 | - * | |
| 641 | - * | |
| 642 | - * Thread-Safety Note: | |
| 643 | - * If the given data parameter is mutable (NSMutableData) then you MUST NOT alter the data while | |
| 644 | - * the socket is sending it. In other words, it's not safe to alter the data until after the delegate method | |
| 645 | - * udpSocket:didSendDataWithTag: or udpSocket:didNotSendDataWithTag:dueToError: is invoked signifying | |
| 646 | - * that this particular send operation has completed. | |
| 647 | - * This is due to the fact that GCDAsyncUdpSocket does NOT copy the data. | |
| 648 | - * It simply retains it for performance reasons. | |
| 649 | - * Often times, if NSMutableData is passed, it is because a request/response was built up in memory. | |
| 650 | - * Copying this data adds an unwanted/unneeded overhead. | |
| 651 | - * If you need to write data from an immutable buffer, and you need to alter the buffer before the socket | |
| 652 | - * completes sending the bytes (which is NOT immediately after this method returns, but rather at a later time | |
| 653 | - * when the delegate method notifies you), then you should first copy the bytes, and pass the copy to this method. | |
| 654 | -**/ | |
| 655 | -- (void)sendData:(NSData *)data toAddress:(NSData *)remoteAddr withTimeout:(NSTimeInterval)timeout tag:(long)tag; | |
| 656 | - | |
| 657 | -/** | |
| 658 | - * You may optionally set a send filter for the socket. | |
| 659 | - * A filter can provide several interesting possibilities: | |
| 660 | - * | |
| 661 | - * 1. Optional caching of resolved addresses for domain names. | |
| 662 | - * The cache could later be consulted, resulting in fewer system calls to getaddrinfo. | |
| 663 | - * | |
| 664 | - * 2. Reusable modules of code for bandwidth monitoring. | |
| 665 | - * | |
| 666 | - * 3. Sometimes traffic shapers are needed to simulate real world environments. | |
| 667 | - * A filter allows you to write custom code to simulate such environments. | |
| 668 | - * The ability to code this yourself is especially helpful when your simulated environment | |
| 669 | - * is more complicated than simple traffic shaping (e.g. simulating a cone port restricted router), | |
| 670 | - * or the system tools to handle this aren't available (e.g. on a mobile device). | |
| 671 | - * | |
| 672 | - * For more information about GCDAsyncUdpSocketSendFilterBlock, see the documentation for its typedef. | |
| 673 | - * To remove a previously set filter, invoke this method and pass a nil filterBlock and NULL filterQueue. | |
| 674 | - * | |
| 675 | - * Note: This method invokes setSendFilter:withQueue:isAsynchronous: (documented below), | |
| 676 | - * passing YES for the isAsynchronous parameter. | |
| 677 | -**/ | |
| 678 | -- (void)setSendFilter:(nullable GCDAsyncUdpSocketSendFilterBlock)filterBlock withQueue:(nullable dispatch_queue_t)filterQueue; | |
| 679 | - | |
| 680 | -/** | |
| 681 | - * The receive filter can be run via dispatch_async or dispatch_sync. | |
| 682 | - * Most typical situations call for asynchronous operation. | |
| 683 | - * | |
| 684 | - * However, there are a few situations in which synchronous operation is preferred. | |
| 685 | - * Such is the case when the filter is extremely minimal and fast. | |
| 686 | - * This is because dispatch_sync is faster than dispatch_async. | |
| 687 | - * | |
| 688 | - * If you choose synchronous operation, be aware of possible deadlock conditions. | |
| 689 | - * Since the socket queue is executing your block via dispatch_sync, | |
| 690 | - * then you cannot perform any tasks which may invoke dispatch_sync on the socket queue. | |
| 691 | - * For example, you can't query properties on the socket. | |
| 692 | -**/ | |
| 693 | -- (void)setSendFilter:(nullable GCDAsyncUdpSocketSendFilterBlock)filterBlock | |
| 694 | - withQueue:(nullable dispatch_queue_t)filterQueue | |
| 695 | - isAsynchronous:(BOOL)isAsynchronous; | |
| 696 | - | |
| 697 | -#pragma mark Receiving | |
| 698 | - | |
| 699 | -/** | |
| 700 | - * There are two modes of operation for receiving packets: one-at-a-time & continuous. | |
| 701 | - * | |
| 702 | - * In one-at-a-time mode, you call receiveOnce everytime your delegate is ready to process an incoming udp packet. | |
| 703 | - * Receiving packets one-at-a-time may be better suited for implementing certain state machine code, | |
| 704 | - * where your state machine may not always be ready to process incoming packets. | |
| 705 | - * | |
| 706 | - * In continuous mode, the delegate is invoked immediately everytime incoming udp packets are received. | |
| 707 | - * Receiving packets continuously is better suited to real-time streaming applications. | |
| 708 | - * | |
| 709 | - * You may switch back and forth between one-at-a-time mode and continuous mode. | |
| 710 | - * If the socket is currently in continuous mode, calling this method will switch it to one-at-a-time mode. | |
| 711 | - * | |
| 712 | - * When a packet is received (and not filtered by the optional receive filter), | |
| 713 | - * the delegate method (udpSocket:didReceiveData:fromAddress:withFilterContext:) is invoked. | |
| 714 | - * | |
| 715 | - * If the socket is able to begin receiving packets, this method returns YES. | |
| 716 | - * Otherwise it returns NO, and sets the errPtr with appropriate error information. | |
| 717 | - * | |
| 718 | - * An example error: | |
| 719 | - * You created a udp socket to act as a server, and immediately called receive. | |
| 720 | - * You forgot to first bind the socket to a port number, and received a error with a message like: | |
| 721 | - * "Must bind socket before you can receive data." | |
| 722 | -**/ | |
| 723 | -- (BOOL)receiveOnce:(NSError **)errPtr; | |
| 724 | - | |
| 725 | -/** | |
| 726 | - * There are two modes of operation for receiving packets: one-at-a-time & continuous. | |
| 727 | - * | |
| 728 | - * In one-at-a-time mode, you call receiveOnce everytime your delegate is ready to process an incoming udp packet. | |
| 729 | - * Receiving packets one-at-a-time may be better suited for implementing certain state machine code, | |
| 730 | - * where your state machine may not always be ready to process incoming packets. | |
| 731 | - * | |
| 732 | - * In continuous mode, the delegate is invoked immediately everytime incoming udp packets are received. | |
| 733 | - * Receiving packets continuously is better suited to real-time streaming applications. | |
| 734 | - * | |
| 735 | - * You may switch back and forth between one-at-a-time mode and continuous mode. | |
| 736 | - * If the socket is currently in one-at-a-time mode, calling this method will switch it to continuous mode. | |
| 737 | - * | |
| 738 | - * For every received packet (not filtered by the optional receive filter), | |
| 739 | - * the delegate method (udpSocket:didReceiveData:fromAddress:withFilterContext:) is invoked. | |
| 740 | - * | |
| 741 | - * If the socket is able to begin receiving packets, this method returns YES. | |
| 742 | - * Otherwise it returns NO, and sets the errPtr with appropriate error information. | |
| 743 | - * | |
| 744 | - * An example error: | |
| 745 | - * You created a udp socket to act as a server, and immediately called receive. | |
| 746 | - * You forgot to first bind the socket to a port number, and received a error with a message like: | |
| 747 | - * "Must bind socket before you can receive data." | |
| 748 | -**/ | |
| 749 | -- (BOOL)beginReceiving:(NSError **)errPtr; | |
| 750 | - | |
| 751 | -/** | |
| 752 | - * If the socket is currently receiving (beginReceiving has been called), this method pauses the receiving. | |
| 753 | - * That is, it won't read any more packets from the underlying OS socket until beginReceiving is called again. | |
| 754 | - * | |
| 755 | - * Important Note: | |
| 756 | - * GCDAsyncUdpSocket may be running in parallel with your code. | |
| 757 | - * That is, your delegate is likely running on a separate thread/dispatch_queue. | |
| 758 | - * When you invoke this method, GCDAsyncUdpSocket may have already dispatched delegate methods to be invoked. | |
| 759 | - * Thus, if those delegate methods have already been dispatch_async'd, | |
| 760 | - * your didReceive delegate method may still be invoked after this method has been called. | |
| 761 | - * You should be aware of this, and program defensively. | |
| 762 | -**/ | |
| 763 | -- (void)pauseReceiving; | |
| 764 | - | |
| 765 | -/** | |
| 766 | - * You may optionally set a receive filter for the socket. | |
| 767 | - * This receive filter may be set to run in its own queue (independent of delegate queue). | |
| 768 | - * | |
| 769 | - * A filter can provide several useful features. | |
| 770 | - * | |
| 771 | - * 1. Many times udp packets need to be parsed. | |
| 772 | - * Since the filter can run in its own independent queue, you can parallelize this parsing quite easily. | |
| 773 | - * The end result is a parallel socket io, datagram parsing, and packet processing. | |
| 774 | - * | |
| 775 | - * 2. Many times udp packets are discarded because they are duplicate/unneeded/unsolicited. | |
| 776 | - * The filter can prevent such packets from arriving at the delegate. | |
| 777 | - * And because the filter can run in its own independent queue, this doesn't slow down the delegate. | |
| 778 | - * | |
| 779 | - * - Since the udp protocol does not guarantee delivery, udp packets may be lost. | |
| 780 | - * Many protocols built atop udp thus provide various resend/re-request algorithms. | |
| 781 | - * This sometimes results in duplicate packets arriving. | |
| 782 | - * A filter may allow you to architect the duplicate detection code to run in parallel to normal processing. | |
| 783 | - * | |
| 784 | - * - Since the udp socket may be connectionless, its possible for unsolicited packets to arrive. | |
| 785 | - * Such packets need to be ignored. | |
| 786 | - * | |
| 787 | - * 3. Sometimes traffic shapers are needed to simulate real world environments. | |
| 788 | - * A filter allows you to write custom code to simulate such environments. | |
| 789 | - * The ability to code this yourself is especially helpful when your simulated environment | |
| 790 | - * is more complicated than simple traffic shaping (e.g. simulating a cone port restricted router), | |
| 791 | - * or the system tools to handle this aren't available (e.g. on a mobile device). | |
| 792 | - * | |
| 793 | - * Example: | |
| 794 | - * | |
| 795 | - * GCDAsyncUdpSocketReceiveFilterBlock filter = ^BOOL (NSData *data, NSData *address, id *context) { | |
| 796 | - * | |
| 797 | - * MyProtocolMessage *msg = [MyProtocol parseMessage:data]; | |
| 798 | - * | |
| 799 | - * *context = response; | |
| 800 | - * return (response != nil); | |
| 801 | - * }; | |
| 802 | - * [udpSocket setReceiveFilter:filter withQueue:myParsingQueue]; | |
| 803 | - * | |
| 804 | - * For more information about GCDAsyncUdpSocketReceiveFilterBlock, see the documentation for its typedef. | |
| 805 | - * To remove a previously set filter, invoke this method and pass a nil filterBlock and NULL filterQueue. | |
| 806 | - * | |
| 807 | - * Note: This method invokes setReceiveFilter:withQueue:isAsynchronous: (documented below), | |
| 808 | - * passing YES for the isAsynchronous parameter. | |
| 809 | -**/ | |
| 810 | -- (void)setReceiveFilter:(nullable GCDAsyncUdpSocketReceiveFilterBlock)filterBlock withQueue:(nullable dispatch_queue_t)filterQueue; | |
| 811 | - | |
| 812 | -/** | |
| 813 | - * The receive filter can be run via dispatch_async or dispatch_sync. | |
| 814 | - * Most typical situations call for asynchronous operation. | |
| 815 | - * | |
| 816 | - * However, there are a few situations in which synchronous operation is preferred. | |
| 817 | - * Such is the case when the filter is extremely minimal and fast. | |
| 818 | - * This is because dispatch_sync is faster than dispatch_async. | |
| 819 | - * | |
| 820 | - * If you choose synchronous operation, be aware of possible deadlock conditions. | |
| 821 | - * Since the socket queue is executing your block via dispatch_sync, | |
| 822 | - * then you cannot perform any tasks which may invoke dispatch_sync on the socket queue. | |
| 823 | - * For example, you can't query properties on the socket. | |
| 824 | -**/ | |
| 825 | -- (void)setReceiveFilter:(nullable GCDAsyncUdpSocketReceiveFilterBlock)filterBlock | |
| 826 | - withQueue:(nullable dispatch_queue_t)filterQueue | |
| 827 | - isAsynchronous:(BOOL)isAsynchronous; | |
| 828 | - | |
| 829 | -#pragma mark Closing | |
| 830 | - | |
| 831 | -/** | |
| 832 | - * Immediately closes the underlying socket. | |
| 833 | - * Any pending send operations are discarded. | |
| 834 | - * | |
| 835 | - * The GCDAsyncUdpSocket instance may optionally be used again. | |
| 836 | - * (it will setup/configure/use another unnderlying BSD socket). | |
| 837 | -**/ | |
| 838 | -- (void)close; | |
| 839 | - | |
| 840 | -/** | |
| 841 | - * Closes the underlying socket after all pending send operations have been sent. | |
| 842 | - * | |
| 843 | - * The GCDAsyncUdpSocket instance may optionally be used again. | |
| 844 | - * (it will setup/configure/use another unnderlying BSD socket). | |
| 845 | -**/ | |
| 846 | -- (void)closeAfterSending; | |
| 847 | - | |
| 848 | -#pragma mark Advanced | |
| 849 | -/** | |
| 850 | - * GCDAsyncSocket maintains thread safety by using an internal serial dispatch_queue. | |
| 851 | - * In most cases, the instance creates this queue itself. | |
| 852 | - * However, to allow for maximum flexibility, the internal queue may be passed in the init method. | |
| 853 | - * This allows for some advanced options such as controlling socket priority via target queues. | |
| 854 | - * However, when one begins to use target queues like this, they open the door to some specific deadlock issues. | |
| 855 | - * | |
| 856 | - * For example, imagine there are 2 queues: | |
| 857 | - * dispatch_queue_t socketQueue; | |
| 858 | - * dispatch_queue_t socketTargetQueue; | |
| 859 | - * | |
| 860 | - * If you do this (pseudo-code): | |
| 861 | - * socketQueue.targetQueue = socketTargetQueue; | |
| 862 | - * | |
| 863 | - * Then all socketQueue operations will actually get run on the given socketTargetQueue. | |
| 864 | - * This is fine and works great in most situations. | |
| 865 | - * But if you run code directly from within the socketTargetQueue that accesses the socket, | |
| 866 | - * you could potentially get deadlock. Imagine the following code: | |
| 867 | - * | |
| 868 | - * - (BOOL)socketHasSomething | |
| 869 | - * { | |
| 870 | - * __block BOOL result = NO; | |
| 871 | - * dispatch_block_t block = ^{ | |
| 872 | - * result = [self someInternalMethodToBeRunOnlyOnSocketQueue]; | |
| 873 | - * } | |
| 874 | - * if (is_executing_on_queue(socketQueue)) | |
| 875 | - * block(); | |
| 876 | - * else | |
| 877 | - * dispatch_sync(socketQueue, block); | |
| 878 | - * | |
| 879 | - * return result; | |
| 880 | - * } | |
| 881 | - * | |
| 882 | - * What happens if you call this method from the socketTargetQueue? The result is deadlock. | |
| 883 | - * This is because the GCD API offers no mechanism to discover a queue's targetQueue. | |
| 884 | - * Thus we have no idea if our socketQueue is configured with a targetQueue. | |
| 885 | - * If we had this information, we could easily avoid deadlock. | |
| 886 | - * But, since these API's are missing or unfeasible, you'll have to explicitly set it. | |
| 887 | - * | |
| 888 | - * IF you pass a socketQueue via the init method, | |
| 889 | - * AND you've configured the passed socketQueue with a targetQueue, | |
| 890 | - * THEN you should pass the end queue in the target hierarchy. | |
| 891 | - * | |
| 892 | - * For example, consider the following queue hierarchy: | |
| 893 | - * socketQueue -> ipQueue -> moduleQueue | |
| 894 | - * | |
| 895 | - * This example demonstrates priority shaping within some server. | |
| 896 | - * All incoming client connections from the same IP address are executed on the same target queue. | |
| 897 | - * And all connections for a particular module are executed on the same target queue. | |
| 898 | - * Thus, the priority of all networking for the entire module can be changed on the fly. | |
| 899 | - * Additionally, networking traffic from a single IP cannot monopolize the module. | |
| 900 | - * | |
| 901 | - * Here's how you would accomplish something like that: | |
| 902 | - * - (dispatch_queue_t)newSocketQueueForConnectionFromAddress:(NSData *)address onSocket:(GCDAsyncSocket *)sock | |
| 903 | - * { | |
| 904 | - * dispatch_queue_t socketQueue = dispatch_queue_create("", NULL); | |
| 905 | - * dispatch_queue_t ipQueue = [self ipQueueForAddress:address]; | |
| 906 | - * | |
| 907 | - * dispatch_set_target_queue(socketQueue, ipQueue); | |
| 908 | - * dispatch_set_target_queue(iqQueue, moduleQueue); | |
| 909 | - * | |
| 910 | - * return socketQueue; | |
| 911 | - * } | |
| 912 | - * - (void)socket:(GCDAsyncSocket *)sock didAcceptNewSocket:(GCDAsyncSocket *)newSocket | |
| 913 | - * { | |
| 914 | - * [clientConnections addObject:newSocket]; | |
| 915 | - * [newSocket markSocketQueueTargetQueue:moduleQueue]; | |
| 916 | - * } | |
| 917 | - * | |
| 918 | - * Note: This workaround is ONLY needed if you intend to execute code directly on the ipQueue or moduleQueue. | |
| 919 | - * This is often NOT the case, as such queues are used solely for execution shaping. | |
| 920 | - **/ | |
| 921 | -- (void)markSocketQueueTargetQueue:(dispatch_queue_t)socketQueuesPreConfiguredTargetQueue; | |
| 922 | -- (void)unmarkSocketQueueTargetQueue:(dispatch_queue_t)socketQueuesPreviouslyConfiguredTargetQueue; | |
| 923 | - | |
| 924 | -/** | |
| 925 | - * It's not thread-safe to access certain variables from outside the socket's internal queue. | |
| 926 | - * | |
| 927 | - * For example, the socket file descriptor. | |
| 928 | - * File descriptors are simply integers which reference an index in the per-process file table. | |
| 929 | - * However, when one requests a new file descriptor (by opening a file or socket), | |
| 930 | - * the file descriptor returned is guaranteed to be the lowest numbered unused descriptor. | |
| 931 | - * So if we're not careful, the following could be possible: | |
| 932 | - * | |
| 933 | - * - Thread A invokes a method which returns the socket's file descriptor. | |
| 934 | - * - The socket is closed via the socket's internal queue on thread B. | |
| 935 | - * - Thread C opens a file, and subsequently receives the file descriptor that was previously the socket's FD. | |
| 936 | - * - Thread A is now accessing/altering the file instead of the socket. | |
| 937 | - * | |
| 938 | - * In addition to this, other variables are not actually objects, | |
| 939 | - * and thus cannot be retained/released or even autoreleased. | |
| 940 | - * An example is the sslContext, of type SSLContextRef, which is actually a malloc'd struct. | |
| 941 | - * | |
| 942 | - * Although there are internal variables that make it difficult to maintain thread-safety, | |
| 943 | - * it is important to provide access to these variables | |
| 944 | - * to ensure this class can be used in a wide array of environments. | |
| 945 | - * This method helps to accomplish this by invoking the current block on the socket's internal queue. | |
| 946 | - * The methods below can be invoked from within the block to access | |
| 947 | - * those generally thread-unsafe internal variables in a thread-safe manner. | |
| 948 | - * The given block will be invoked synchronously on the socket's internal queue. | |
| 949 | - * | |
| 950 | - * If you save references to any protected variables and use them outside the block, you do so at your own peril. | |
| 951 | -**/ | |
| 952 | -- (void)performBlock:(dispatch_block_t)block; | |
| 953 | - | |
| 954 | -/** | |
| 955 | - * These methods are only available from within the context of a performBlock: invocation. | |
| 956 | - * See the documentation for the performBlock: method above. | |
| 957 | - * | |
| 958 | - * Provides access to the socket's file descriptor(s). | |
| 959 | - * If the socket isn't connected, or explicity bound to a particular interface, | |
| 960 | - * it might actually have multiple internal socket file descriptors - one for IPv4 and one for IPv6. | |
| 961 | -**/ | |
| 962 | -- (int)socketFD; | |
| 963 | -- (int)socket4FD; | |
| 964 | -- (int)socket6FD; | |
| 965 | - | |
| 966 | -#if TARGET_OS_IPHONE | |
| 967 | - | |
| 968 | -/** | |
| 969 | - * These methods are only available from within the context of a performBlock: invocation. | |
| 970 | - * See the documentation for the performBlock: method above. | |
| 971 | - * | |
| 972 | - * Returns (creating if necessary) a CFReadStream/CFWriteStream for the internal socket. | |
| 973 | - * | |
| 974 | - * Generally GCDAsyncUdpSocket doesn't use CFStream. (It uses the faster GCD API's.) | |
| 975 | - * However, if you need one for any reason, | |
| 976 | - * these methods are a convenient way to get access to a safe instance of one. | |
| 977 | -**/ | |
| 978 | -- (nullable CFReadStreamRef)readStream; | |
| 979 | -- (nullable CFWriteStreamRef)writeStream; | |
| 980 | - | |
| 981 | -/** | |
| 982 | - * This method is only available from within the context of a performBlock: invocation. | |
| 983 | - * See the documentation for the performBlock: method above. | |
| 984 | - * | |
| 985 | - * Configures the socket to allow it to operate when the iOS application has been backgrounded. | |
| 986 | - * In other words, this method creates a read & write stream, and invokes: | |
| 987 | - * | |
| 988 | - * CFReadStreamSetProperty(readStream, kCFStreamNetworkServiceType, kCFStreamNetworkServiceTypeVoIP); | |
| 989 | - * CFWriteStreamSetProperty(writeStream, kCFStreamNetworkServiceType, kCFStreamNetworkServiceTypeVoIP); | |
| 990 | - * | |
| 991 | - * Returns YES if successful, NO otherwise. | |
| 992 | - * | |
| 993 | - * Example usage: | |
| 994 | - * | |
| 995 | - * [asyncUdpSocket performBlock:^{ | |
| 996 | - * [asyncUdpSocket enableBackgroundingOnSocket]; | |
| 997 | - * }]; | |
| 998 | - * | |
| 999 | - * | |
| 1000 | - * NOTE : Apple doesn't currently support backgrounding UDP sockets. (Only TCP for now). | |
| 1001 | -**/ | |
| 1002 | -//- (BOOL)enableBackgroundingOnSockets; | |
| 1003 | - | |
| 1004 | -#endif | |
| 1005 | - | |
| 1006 | -#pragma mark Utilities | |
| 1007 | - | |
| 1008 | -/** | |
| 1009 | - * Extracting host/port/family information from raw address data. | |
| 1010 | -**/ | |
| 1011 | - | |
| 1012 | -+ (nullable NSString *)hostFromAddress:(NSData *)address; | |
| 1013 | -+ (uint16_t)portFromAddress:(NSData *)address; | |
| 1014 | -+ (int)familyFromAddress:(NSData *)address; | |
| 1015 | - | |
| 1016 | -+ (BOOL)isIPv4Address:(NSData *)address; | |
| 1017 | -+ (BOOL)isIPv6Address:(NSData *)address; | |
| 1018 | - | |
| 1019 | -+ (BOOL)getHost:(NSString * __nullable * __nullable)hostPtr port:(uint16_t * __nullable)portPtr fromAddress:(NSData *)address; | |
| 1020 | -+ (BOOL)getHost:(NSString * __nullable * __nullable)hostPtr port:(uint16_t * __nullable)portPtr family:(int * __nullable)afPtr fromAddress:(NSData *)address; | |
| 1021 | - | |
| 1022 | -@end | |
| 1023 | - | |
| 1024 | -NS_ASSUME_NONNULL_END |
Example/build/Debug-iphoneos/CocoaAsyncSocket/CocoaAsyncSocket.framework/Info.plist deleted
100644 → 0
No preview for this file type
Example/build/Debug-iphoneos/CocoaAsyncSocket/CocoaAsyncSocket.framework/Modules/module.modulemap deleted
100644 → 0
Example/build/Debug-iphoneos/CocoaLumberjack/CocoaLumberjack.framework/CocoaLumberjack deleted
100755 → 0
No preview for this file type
Example/build/Debug-iphoneos/CocoaLumberjack/CocoaLumberjack.framework/Headers/CLIColor.h deleted
100644 → 0
| 1 | -// Software License Agreement (BSD License) | |
| 2 | -// | |
| 3 | -// Copyright (c) 2010-2019, Deusty, LLC | |
| 4 | -// All rights reserved. | |
| 5 | -// | |
| 6 | -// Redistribution and use of this software in source and binary forms, | |
| 7 | -// with or without modification, are permitted provided that the following conditions are met: | |
| 8 | -// | |
| 9 | -// * Redistributions of source code must retain the above copyright notice, | |
| 10 | -// this list of conditions and the following disclaimer. | |
| 11 | -// | |
| 12 | -// * Neither the name of Deusty nor the names of its contributors may be used | |
| 13 | -// to endorse or promote products derived from this software without specific | |
| 14 | -// prior written permission of Deusty, LLC. | |
| 15 | - | |
| 16 | -#if TARGET_OS_OSX | |
| 17 | - | |
| 18 | -#import <Foundation/Foundation.h> | |
| 19 | -#import <QuartzCore/QuartzCore.h> | |
| 20 | - | |
| 21 | -/** | |
| 22 | - * This class represents an NSColor replacement for CLI projects that don't link with AppKit | |
| 23 | - **/ | |
| 24 | -@interface CLIColor : NSObject | |
| 25 | - | |
| 26 | -/** | |
| 27 | - * Convenience method for creating a `CLIColor` instance from RGBA params | |
| 28 | - * | |
| 29 | - * @param red red channel, between 0 and 1 | |
| 30 | - * @param green green channel, between 0 and 1 | |
| 31 | - * @param blue blue channel, between 0 and 1 | |
| 32 | - * @param alpha alpha channel, between 0 and 1 | |
| 33 | - */ | |
| 34 | -+ (CLIColor *)colorWithCalibratedRed:(CGFloat)red green:(CGFloat)green blue:(CGFloat)blue alpha:(CGFloat)alpha; | |
| 35 | - | |
| 36 | -/** | |
| 37 | - * Get the RGBA components from a `CLIColor` | |
| 38 | - * | |
| 39 | - * @param red red channel, between 0 and 1 | |
| 40 | - * @param green green channel, between 0 and 1 | |
| 41 | - * @param blue blue channel, between 0 and 1 | |
| 42 | - * @param alpha alpha channel, between 0 and 1 | |
| 43 | - */ | |
| 44 | -- (void)getRed:(CGFloat *)red green:(CGFloat *)green blue:(CGFloat *)blue alpha:(CGFloat *)alpha NS_SWIFT_NAME(get(red:green:blue:alpha:)); | |
| 45 | - | |
| 46 | -@end | |
| 47 | - | |
| 48 | -#endif |
Example/build/Debug-iphoneos/CocoaLumberjack/CocoaLumberjack.framework/Headers/CocoaLumberjack-umbrella.h deleted
100644 → 0
| 1 | -#ifdef __OBJC__ | |
| 2 | -#import <UIKit/UIKit.h> | |
| 3 | -#else | |
| 4 | -#ifndef FOUNDATION_EXPORT | |
| 5 | -#if defined(__cplusplus) | |
| 6 | -#define FOUNDATION_EXPORT extern "C" | |
| 7 | -#else | |
| 8 | -#define FOUNDATION_EXPORT extern | |
| 9 | -#endif | |
| 10 | -#endif | |
| 11 | -#endif | |
| 12 | - | |
| 13 | -#import "CocoaLumberjack.h" | |
| 14 | -#import "DDAbstractDatabaseLogger.h" | |
| 15 | -#import "DDASLLogCapture.h" | |
| 16 | -#import "DDASLLogger.h" | |
| 17 | -#import "DDAssertMacros.h" | |
| 18 | -#import "DDFileLogger.h" | |
| 19 | -#import "DDLegacyMacros.h" | |
| 20 | -#import "DDLog+LOGV.h" | |
| 21 | -#import "DDLog.h" | |
| 22 | -#import "DDLoggerNames.h" | |
| 23 | -#import "DDLogMacros.h" | |
| 24 | -#import "DDOSLogger.h" | |
| 25 | -#import "DDTTYLogger.h" | |
| 26 | -#import "DDContextFilterLogFormatter.h" | |
| 27 | -#import "DDDispatchQueueLogFormatter.h" | |
| 28 | -#import "DDFileLogger+Buffering.h" | |
| 29 | -#import "DDMultiFormatter.h" | |
| 30 | -#import "CLIColor.h" | |
| 31 | - | |
| 32 | -FOUNDATION_EXPORT double CocoaLumberjackVersionNumber; | |
| 33 | -FOUNDATION_EXPORT const unsigned char CocoaLumberjackVersionString[]; | |
| 34 | - |
Example/build/Debug-iphoneos/CocoaLumberjack/CocoaLumberjack.framework/Headers/CocoaLumberjack.h deleted
100644 → 0
| 1 | -// Software License Agreement (BSD License) | |
| 2 | -// | |
| 3 | -// Copyright (c) 2010-2019, Deusty, LLC | |
| 4 | -// All rights reserved. | |
| 5 | -// | |
| 6 | -// Redistribution and use of this software in source and binary forms, | |
| 7 | -// with or without modification, are permitted provided that the following conditions are met: | |
| 8 | -// | |
| 9 | -// * Redistributions of source code must retain the above copyright notice, | |
| 10 | -// this list of conditions and the following disclaimer. | |
| 11 | -// | |
| 12 | -// * Neither the name of Deusty nor the names of its contributors may be used | |
| 13 | -// to endorse or promote products derived from this software without specific | |
| 14 | -// prior written permission of Deusty, LLC. | |
| 15 | - | |
| 16 | -/** | |
| 17 | - * Welcome to CocoaLumberjack! | |
| 18 | - * | |
| 19 | - * The project page has a wealth of documentation if you have any questions. | |
| 20 | - * https://github.com/CocoaLumberjack/CocoaLumberjack | |
| 21 | - * | |
| 22 | - * If you're new to the project you may wish to read "Getting Started" at: | |
| 23 | - * Documentation/GettingStarted.md | |
| 24 | - * | |
| 25 | - * Otherwise, here is a quick refresher. | |
| 26 | - * There are three steps to using the macros: | |
| 27 | - * | |
| 28 | - * Step 1: | |
| 29 | - * Import the header in your implementation or prefix file: | |
| 30 | - * | |
| 31 | - * #import <CocoaLumberjack/CocoaLumberjack.h> | |
| 32 | - * | |
| 33 | - * Step 2: | |
| 34 | - * Define your logging level in your implementation file: | |
| 35 | - * | |
| 36 | - * // Log levels: off, error, warn, info, verbose | |
| 37 | - * static const DDLogLevel ddLogLevel = DDLogLevelVerbose; | |
| 38 | - * | |
| 39 | - * Step 2 [3rd party frameworks]: | |
| 40 | - * | |
| 41 | - * Define your LOG_LEVEL_DEF to a different variable/function than ddLogLevel: | |
| 42 | - * | |
| 43 | - * // #undef LOG_LEVEL_DEF // Undefine first only if needed | |
| 44 | - * #define LOG_LEVEL_DEF myLibLogLevel | |
| 45 | - * | |
| 46 | - * Define your logging level in your implementation file: | |
| 47 | - * | |
| 48 | - * // Log levels: off, error, warn, info, verbose | |
| 49 | - * static const DDLogLevel myLibLogLevel = DDLogLevelVerbose; | |
| 50 | - * | |
| 51 | - * Step 3: | |
| 52 | - * Replace your NSLog statements with DDLog statements according to the severity of the message. | |
| 53 | - * | |
| 54 | - * NSLog(@"Fatal error, no dohickey found!"); -> DDLogError(@"Fatal error, no dohickey found!"); | |
| 55 | - * | |
| 56 | - * DDLog works exactly the same as NSLog. | |
| 57 | - * This means you can pass it multiple variables just like NSLog. | |
| 58 | - **/ | |
| 59 | - | |
| 60 | -#import <Foundation/Foundation.h> | |
| 61 | - | |
| 62 | -//! Project version number for CocoaLumberjack. | |
| 63 | -FOUNDATION_EXPORT double CocoaLumberjackVersionNumber; | |
| 64 | - | |
| 65 | -//! Project version string for CocoaLumberjack. | |
| 66 | -FOUNDATION_EXPORT const unsigned char CocoaLumberjackVersionString[]; | |
| 67 | - | |
| 68 | -// Disable legacy macros | |
| 69 | -#ifndef DD_LEGACY_MACROS | |
| 70 | - #define DD_LEGACY_MACROS 0 | |
| 71 | -#endif | |
| 72 | - | |
| 73 | -// Core | |
| 74 | -#import <CocoaLumberjack/DDLog.h> | |
| 75 | - | |
| 76 | -// Main macros | |
| 77 | -#import <CocoaLumberjack/DDLogMacros.h> | |
| 78 | -#import <CocoaLumberjack/DDAssertMacros.h> | |
| 79 | - | |
| 80 | -// Capture ASL | |
| 81 | -#import <CocoaLumberjack/DDASLLogCapture.h> | |
| 82 | - | |
| 83 | -// Loggers | |
| 84 | -#import <CocoaLumberjack/DDLoggerNames.h> | |
| 85 | - | |
| 86 | -#import <CocoaLumberjack/DDTTYLogger.h> | |
| 87 | -#import <CocoaLumberjack/DDASLLogger.h> | |
| 88 | -#import <CocoaLumberjack/DDFileLogger.h> | |
| 89 | -#import <CocoaLumberjack/DDOSLogger.h> | |
| 90 | - | |
| 91 | -// Extensions | |
| 92 | -#import <CocoaLumberjack/DDContextFilterLogFormatter.h> | |
| 93 | -#import <CocoaLumberjack/DDDispatchQueueLogFormatter.h> | |
| 94 | -#import <CocoaLumberjack/DDMultiFormatter.h> | |
| 95 | -#import <CocoaLumberjack/DDFileLogger+Buffering.h> | |
| 96 | - | |
| 97 | -// CLI | |
| 98 | -#import <CocoaLumberjack/CLIColor.h> | |
| 99 | - | |
| 100 | -// etc | |
| 101 | -#import <CocoaLumberjack/DDAbstractDatabaseLogger.h> | |
| 102 | -#import <CocoaLumberjack/DDLog+LOGV.h> | |
| 103 | -#import <CocoaLumberjack/DDLegacyMacros.h> |
Example/build/Debug-iphoneos/CocoaLumberjack/CocoaLumberjack.framework/Headers/DDASLLogCapture.h deleted
100644 → 0
| 1 | -// Software License Agreement (BSD License) | |
| 2 | -// | |
| 3 | -// Copyright (c) 2010-2019, Deusty, LLC | |
| 4 | -// All rights reserved. | |
| 5 | -// | |
| 6 | -// Redistribution and use of this software in source and binary forms, | |
| 7 | -// with or without modification, are permitted provided that the following conditions are met: | |
| 8 | -// | |
| 9 | -// * Redistributions of source code must retain the above copyright notice, | |
| 10 | -// this list of conditions and the following disclaimer. | |
| 11 | -// | |
| 12 | -// * Neither the name of Deusty nor the names of its contributors may be used | |
| 13 | -// to endorse or promote products derived from this software without specific | |
| 14 | -// prior written permission of Deusty, LLC. | |
| 15 | - | |
| 16 | -#import <CocoaLumberjack/DDASLLogger.h> | |
| 17 | - | |
| 18 | -@protocol DDLogger; | |
| 19 | - | |
| 20 | -/** | |
| 21 | - * This class provides the ability to capture the ASL (Apple System Logs) | |
| 22 | - */ | |
| 23 | -API_DEPRECATED("Use DDOSLogger instead", macosx(10.4,10.12), ios(2.0,10.0), watchos(2.0,3.0), tvos(9.0,10.0)) | |
| 24 | -@interface DDASLLogCapture : NSObject | |
| 25 | - | |
| 26 | -/** | |
| 27 | - * Start capturing logs | |
| 28 | - */ | |
| 29 | -+ (void)start; | |
| 30 | - | |
| 31 | -/** | |
| 32 | - * Stop capturing logs | |
| 33 | - */ | |
| 34 | -+ (void)stop; | |
| 35 | - | |
| 36 | -/** | |
| 37 | - * The current capture level. | |
| 38 | - * @note Default log level: DDLogLevelVerbose (i.e. capture all ASL messages). | |
| 39 | - */ | |
| 40 | -@property (class) DDLogLevel captureLevel; | |
| 41 | - | |
| 42 | -@end |
Example/build/Debug-iphoneos/CocoaLumberjack/CocoaLumberjack.framework/Headers/DDASLLogger.h deleted
100644 → 0
| 1 | -// Software License Agreement (BSD License) | |
| 2 | -// | |
| 3 | -// Copyright (c) 2010-2019, Deusty, LLC | |
| 4 | -// All rights reserved. | |
| 5 | -// | |
| 6 | -// Redistribution and use of this software in source and binary forms, | |
| 7 | -// with or without modification, are permitted provided that the following conditions are met: | |
| 8 | -// | |
| 9 | -// * Redistributions of source code must retain the above copyright notice, | |
| 10 | -// this list of conditions and the following disclaimer. | |
| 11 | -// | |
| 12 | -// * Neither the name of Deusty nor the names of its contributors may be used | |
| 13 | -// to endorse or promote products derived from this software without specific | |
| 14 | -// prior written permission of Deusty, LLC. | |
| 15 | - | |
| 16 | -#import <Foundation/Foundation.h> | |
| 17 | - | |
| 18 | -// Disable legacy macros | |
| 19 | -#ifndef DD_LEGACY_MACROS | |
| 20 | - #define DD_LEGACY_MACROS 0 | |
| 21 | -#endif | |
| 22 | - | |
| 23 | -#import <CocoaLumberjack/DDLog.h> | |
| 24 | - | |
| 25 | -// Custom key set on messages sent to ASL | |
| 26 | -extern const char* const kDDASLKeyDDLog; | |
| 27 | - | |
| 28 | -// Value set for kDDASLKeyDDLog | |
| 29 | -extern const char* const kDDASLDDLogValue; | |
| 30 | - | |
| 31 | -/** | |
| 32 | - * This class provides a logger for the Apple System Log facility. | |
| 33 | - * | |
| 34 | - * As described in the "Getting Started" page, | |
| 35 | - * the traditional NSLog() function directs its output to two places: | |
| 36 | - * | |
| 37 | - * - Apple System Log | |
| 38 | - * - StdErr (if stderr is a TTY) so log statements show up in Xcode console | |
| 39 | - * | |
| 40 | - * To duplicate NSLog() functionality you can simply add this logger and a tty logger. | |
| 41 | - * However, if you instead choose to use file logging (for faster performance), | |
| 42 | - * you may choose to use a file logger and a tty logger. | |
| 43 | - **/ | |
| 44 | -API_DEPRECATED("Use DDOSLogger instead", macosx(10.4,10.12), ios(2.0,10.0), watchos(2.0,3.0), tvos(9.0,10.0)) | |
| 45 | -@interface DDASLLogger : DDAbstractLogger <DDLogger> | |
| 46 | - | |
| 47 | -/** | |
| 48 | - * Singleton method | |
| 49 | - * | |
| 50 | - * @return the shared instance | |
| 51 | - */ | |
| 52 | -@property (class, readonly, strong) DDASLLogger *sharedInstance; | |
| 53 | - | |
| 54 | -// Inherited from DDAbstractLogger | |
| 55 | - | |
| 56 | -// - (id <DDLogFormatter>)logFormatter; | |
| 57 | -// - (void)setLogFormatter:(id <DDLogFormatter>)formatter; | |
| 58 | - | |
| 59 | -@end |
Example/build/Debug-iphoneos/CocoaLumberjack/CocoaLumberjack.framework/Headers/DDAbstractDatabaseLogger.h deleted
100644 → 0
| 1 | -// Software License Agreement (BSD License) | |
| 2 | -// | |
| 3 | -// Copyright (c) 2010-2019, Deusty, LLC | |
| 4 | -// All rights reserved. | |
| 5 | -// | |
| 6 | -// Redistribution and use of this software in source and binary forms, | |
| 7 | -// with or without modification, are permitted provided that the following conditions are met: | |
| 8 | -// | |
| 9 | -// * Redistributions of source code must retain the above copyright notice, | |
| 10 | -// this list of conditions and the following disclaimer. | |
| 11 | -// | |
| 12 | -// * Neither the name of Deusty nor the names of its contributors may be used | |
| 13 | -// to endorse or promote products derived from this software without specific | |
| 14 | -// prior written permission of Deusty, LLC. | |
| 15 | - | |
| 16 | -// Disable legacy macros | |
| 17 | -#ifndef DD_LEGACY_MACROS | |
| 18 | - #define DD_LEGACY_MACROS 0 | |
| 19 | -#endif | |
| 20 | - | |
| 21 | -#import <CocoaLumberjack/DDLog.h> | |
| 22 | - | |
| 23 | -/** | |
| 24 | - * This class provides an abstract implementation of a database logger. | |
| 25 | - * | |
| 26 | - * That is, it provides the base implementation for a database logger to build atop of. | |
| 27 | - * All that is needed for a concrete database logger is to extend this class | |
| 28 | - * and override the methods in the implementation file that are prefixed with "db_". | |
| 29 | - **/ | |
| 30 | -@interface DDAbstractDatabaseLogger : DDAbstractLogger { | |
| 31 | - | |
| 32 | -@protected | |
| 33 | - NSUInteger _saveThreshold; | |
| 34 | - NSTimeInterval _saveInterval; | |
| 35 | - NSTimeInterval _maxAge; | |
| 36 | - NSTimeInterval _deleteInterval; | |
| 37 | - BOOL _deleteOnEverySave; | |
| 38 | - | |
| 39 | - BOOL _saveTimerSuspended; | |
| 40 | - NSUInteger _unsavedCount; | |
| 41 | - dispatch_time_t _unsavedTime; | |
| 42 | - dispatch_source_t _saveTimer; | |
| 43 | - dispatch_time_t _lastDeleteTime; | |
| 44 | - dispatch_source_t _deleteTimer; | |
| 45 | -} | |
| 46 | - | |
| 47 | -/** | |
| 48 | - * Specifies how often to save the data to disk. | |
| 49 | - * Since saving is an expensive operation (disk io) it is not done after every log statement. | |
| 50 | - * These properties allow you to configure how/when the logger saves to disk. | |
| 51 | - * | |
| 52 | - * A save is done when either (whichever happens first): | |
| 53 | - * | |
| 54 | - * - The number of unsaved log entries reaches saveThreshold | |
| 55 | - * - The amount of time since the oldest unsaved log entry was created reaches saveInterval | |
| 56 | - * | |
| 57 | - * You can optionally disable the saveThreshold by setting it to zero. | |
| 58 | - * If you disable the saveThreshold you are entirely dependent on the saveInterval. | |
| 59 | - * | |
| 60 | - * You can optionally disable the saveInterval by setting it to zero (or a negative value). | |
| 61 | - * If you disable the saveInterval you are entirely dependent on the saveThreshold. | |
| 62 | - * | |
| 63 | - * It's not wise to disable both saveThreshold and saveInterval. | |
| 64 | - * | |
| 65 | - * The default saveThreshold is 500. | |
| 66 | - * The default saveInterval is 60 seconds. | |
| 67 | - **/ | |
| 68 | -@property (assign, readwrite) NSUInteger saveThreshold; | |
| 69 | - | |
| 70 | -/** | |
| 71 | - * See the description for the `saveThreshold` property | |
| 72 | - */ | |
| 73 | -@property (assign, readwrite) NSTimeInterval saveInterval; | |
| 74 | - | |
| 75 | -/** | |
| 76 | - * It is likely you don't want the log entries to persist forever. | |
| 77 | - * Doing so would allow the database to grow infinitely large over time. | |
| 78 | - * | |
| 79 | - * The maxAge property provides a way to specify how old a log statement can get | |
| 80 | - * before it should get deleted from the database. | |
| 81 | - * | |
| 82 | - * The deleteInterval specifies how often to sweep for old log entries. | |
| 83 | - * Since deleting is an expensive operation (disk io) is is done on a fixed interval. | |
| 84 | - * | |
| 85 | - * An alternative to the deleteInterval is the deleteOnEverySave option. | |
| 86 | - * This specifies that old log entries should be deleted during every save operation. | |
| 87 | - * | |
| 88 | - * You can optionally disable the maxAge by setting it to zero (or a negative value). | |
| 89 | - * If you disable the maxAge then old log statements are not deleted. | |
| 90 | - * | |
| 91 | - * You can optionally disable the deleteInterval by setting it to zero (or a negative value). | |
| 92 | - * | |
| 93 | - * If you disable both deleteInterval and deleteOnEverySave then old log statements are not deleted. | |
| 94 | - * | |
| 95 | - * It's not wise to enable both deleteInterval and deleteOnEverySave. | |
| 96 | - * | |
| 97 | - * The default maxAge is 7 days. | |
| 98 | - * The default deleteInterval is 5 minutes. | |
| 99 | - * The default deleteOnEverySave is NO. | |
| 100 | - **/ | |
| 101 | -@property (assign, readwrite) NSTimeInterval maxAge; | |
| 102 | - | |
| 103 | -/** | |
| 104 | - * See the description for the `maxAge` property | |
| 105 | - */ | |
| 106 | -@property (assign, readwrite) NSTimeInterval deleteInterval; | |
| 107 | - | |
| 108 | -/** | |
| 109 | - * See the description for the `maxAge` property | |
| 110 | - */ | |
| 111 | -@property (assign, readwrite) BOOL deleteOnEverySave; | |
| 112 | - | |
| 113 | -/** | |
| 114 | - * Forces a save of any pending log entries (flushes log entries to disk). | |
| 115 | - **/ | |
| 116 | -- (void)savePendingLogEntries; | |
| 117 | - | |
| 118 | -/** | |
| 119 | - * Removes any log entries that are older than maxAge. | |
| 120 | - **/ | |
| 121 | -- (void)deleteOldLogEntries; | |
| 122 | - | |
| 123 | -@end |
Example/build/Debug-iphoneos/CocoaLumberjack/CocoaLumberjack.framework/Headers/DDAssertMacros.h deleted
100644 → 0
| 1 | -// Software License Agreement (BSD License) | |
| 2 | -// | |
| 3 | -// Copyright (c) 2010-2019, Deusty, LLC | |
| 4 | -// All rights reserved. | |
| 5 | -// | |
| 6 | -// Redistribution and use of this software in source and binary forms, | |
| 7 | -// with or without modification, are permitted provided that the following conditions are met: | |
| 8 | -// | |
| 9 | -// * Redistributions of source code must retain the above copyright notice, | |
| 10 | -// this list of conditions and the following disclaimer. | |
| 11 | -// | |
| 12 | -// * Neither the name of Deusty nor the names of its contributors may be used | |
| 13 | -// to endorse or promote products derived from this software without specific | |
| 14 | -// prior written permission of Deusty, LLC. | |
| 15 | - | |
| 16 | -/** | |
| 17 | - * NSAssert replacement that will output a log message even when assertions are disabled. | |
| 18 | - **/ | |
| 19 | -#define DDAssert(condition, frmt, ...) \ | |
| 20 | - if (!(condition)) { \ | |
| 21 | - NSString *description = [NSString stringWithFormat:frmt, ## __VA_ARGS__]; \ | |
| 22 | - DDLogError(@"%@", description); \ | |
| 23 | - NSAssert(NO, @"%@", description); \ | |
| 24 | - } | |
| 25 | -#define DDAssertCondition(condition) DDAssert(condition, @"Condition not satisfied: %s", #condition) | |
| 26 | - |
Example/build/Debug-iphoneos/CocoaLumberjack/CocoaLumberjack.framework/Headers/DDContextFilterLogFormatter.h deleted
100644 → 0
| 1 | -// Software License Agreement (BSD License) | |
| 2 | -// | |
| 3 | -// Copyright (c) 2010-2019, Deusty, LLC | |
| 4 | -// All rights reserved. | |
| 5 | -// | |
| 6 | -// Redistribution and use of this software in source and binary forms, | |
| 7 | -// with or without modification, are permitted provided that the following conditions are met: | |
| 8 | -// | |
| 9 | -// * Redistributions of source code must retain the above copyright notice, | |
| 10 | -// this list of conditions and the following disclaimer. | |
| 11 | -// | |
| 12 | -// * Neither the name of Deusty nor the names of its contributors may be used | |
| 13 | -// to endorse or promote products derived from this software without specific | |
| 14 | -// prior written permission of Deusty, LLC. | |
| 15 | - | |
| 16 | -#import <Foundation/Foundation.h> | |
| 17 | - | |
| 18 | -// Disable legacy macros | |
| 19 | -#ifndef DD_LEGACY_MACROS | |
| 20 | - #define DD_LEGACY_MACROS 0 | |
| 21 | -#endif | |
| 22 | - | |
| 23 | -#import <CocoaLumberjack/DDLog.h> | |
| 24 | - | |
| 25 | -/** | |
| 26 | - * This class provides a log formatter that filters log statements from a logging context not on the whitelist. | |
| 27 | - * | |
| 28 | - * A log formatter can be added to any logger to format and/or filter its output. | |
| 29 | - * You can learn more about log formatters here: | |
| 30 | - * Documentation/CustomFormatters.md | |
| 31 | - * | |
| 32 | - * You can learn more about logging context's here: | |
| 33 | - * Documentation/CustomContext.md | |
| 34 | - * | |
| 35 | - * But here's a quick overview / refresher: | |
| 36 | - * | |
| 37 | - * Every log statement has a logging context. | |
| 38 | - * These come from the underlying logging macros defined in DDLog.h. | |
| 39 | - * The default logging context is zero. | |
| 40 | - * You can define multiple logging context's for use in your application. | |
| 41 | - * For example, logically separate parts of your app each have a different logging context. | |
| 42 | - * Also 3rd party frameworks that make use of Lumberjack generally use their own dedicated logging context. | |
| 43 | - **/ | |
| 44 | -@interface DDContextWhitelistFilterLogFormatter : NSObject <DDLogFormatter> | |
| 45 | - | |
| 46 | -/** | |
| 47 | - * Designated default initializer | |
| 48 | - */ | |
| 49 | -- (instancetype)init NS_DESIGNATED_INITIALIZER; | |
| 50 | - | |
| 51 | -/** | |
| 52 | - * Add a context to the whitelist | |
| 53 | - * | |
| 54 | - * @param loggingContext the context | |
| 55 | - */ | |
| 56 | -- (void)addToWhitelist:(NSInteger)loggingContext; | |
| 57 | - | |
| 58 | -/** | |
| 59 | - * Remove context from whitelist | |
| 60 | - * | |
| 61 | - * @param loggingContext the context | |
| 62 | - */ | |
| 63 | -- (void)removeFromWhitelist:(NSInteger)loggingContext; | |
| 64 | - | |
| 65 | -/** | |
| 66 | - * Return the whitelist | |
| 67 | - */ | |
| 68 | -@property (readonly, copy) NSArray<NSNumber *> *whitelist; | |
| 69 | - | |
| 70 | -/** | |
| 71 | - * Check if a context is on the whitelist | |
| 72 | - * | |
| 73 | - * @param loggingContext the context | |
| 74 | - */ | |
| 75 | -- (BOOL)isOnWhitelist:(NSInteger)loggingContext; | |
| 76 | - | |
| 77 | -@end | |
| 78 | - | |
| 79 | -//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | |
| 80 | -#pragma mark - | |
| 81 | -//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | |
| 82 | - | |
| 83 | -/** | |
| 84 | - * This class provides a log formatter that filters log statements from a logging context on the blacklist. | |
| 85 | - **/ | |
| 86 | -@interface DDContextBlacklistFilterLogFormatter : NSObject <DDLogFormatter> | |
| 87 | - | |
| 88 | -- (instancetype)init NS_DESIGNATED_INITIALIZER; | |
| 89 | - | |
| 90 | -/** | |
| 91 | - * Add a context to the blacklist | |
| 92 | - * | |
| 93 | - * @param loggingContext the context | |
| 94 | - */ | |
| 95 | -- (void)addToBlacklist:(NSInteger)loggingContext; | |
| 96 | - | |
| 97 | -/** | |
| 98 | - * Remove context from blacklist | |
| 99 | - * | |
| 100 | - * @param loggingContext the context | |
| 101 | - */ | |
| 102 | -- (void)removeFromBlacklist:(NSInteger)loggingContext; | |
| 103 | - | |
| 104 | -/** | |
| 105 | - * Return the blacklist | |
| 106 | - */ | |
| 107 | -@property (readonly, copy) NSArray<NSNumber *> *blacklist; | |
| 108 | - | |
| 109 | - | |
| 110 | -/** | |
| 111 | - * Check if a context is on the blacklist | |
| 112 | - * | |
| 113 | - * @param loggingContext the context | |
| 114 | - */ | |
| 115 | -- (BOOL)isOnBlacklist:(NSInteger)loggingContext; | |
| 116 | - | |
| 117 | -@end |
Example/build/Debug-iphoneos/CocoaLumberjack/CocoaLumberjack.framework/Headers/DDDispatchQueueLogFormatter.h deleted
100644 → 0
| 1 | -// Software License Agreement (BSD License) | |
| 2 | -// | |
| 3 | -// Copyright (c) 2010-2019, Deusty, LLC | |
| 4 | -// All rights reserved. | |
| 5 | -// | |
| 6 | -// Redistribution and use of this software in source and binary forms, | |
| 7 | -// with or without modification, are permitted provided that the following conditions are met: | |
| 8 | -// | |
| 9 | -// * Redistributions of source code must retain the above copyright notice, | |
| 10 | -// this list of conditions and the following disclaimer. | |
| 11 | -// | |
| 12 | -// * Neither the name of Deusty nor the names of its contributors may be used | |
| 13 | -// to endorse or promote products derived from this software without specific | |
| 14 | -// prior written permission of Deusty, LLC. | |
| 15 | - | |
| 16 | -#import <Foundation/Foundation.h> | |
| 17 | - | |
| 18 | -// Disable legacy macros | |
| 19 | -#ifndef DD_LEGACY_MACROS | |
| 20 | - #define DD_LEGACY_MACROS 0 | |
| 21 | -#endif | |
| 22 | - | |
| 23 | -#import <CocoaLumberjack/DDLog.h> | |
| 24 | - | |
| 25 | -/** | |
| 26 | - * Log formatter mode | |
| 27 | - */ | |
| 28 | -typedef NS_ENUM(NSUInteger, DDDispatchQueueLogFormatterMode){ | |
| 29 | - /** | |
| 30 | - * This is the default option, means the formatter can be reused between multiple loggers and therefore is thread-safe. | |
| 31 | - * There is, of course, a performance cost for the thread-safety | |
| 32 | - */ | |
| 33 | - DDDispatchQueueLogFormatterModeShareble = 0, | |
| 34 | - /** | |
| 35 | - * If the formatter will only be used by a single logger, then the thread-safety can be removed | |
| 36 | - * @note: there is an assert checking if the formatter is added to multiple loggers and the mode is non-shareble | |
| 37 | - */ | |
| 38 | - DDDispatchQueueLogFormatterModeNonShareble, | |
| 39 | -}; | |
| 40 | - | |
| 41 | - | |
| 42 | -/** | |
| 43 | - * This class provides a log formatter that prints the dispatch_queue label instead of the mach_thread_id. | |
| 44 | - * | |
| 45 | - * A log formatter can be added to any logger to format and/or filter its output. | |
| 46 | - * You can learn more about log formatters here: | |
| 47 | - * Documentation/CustomFormatters.md | |
| 48 | - * | |
| 49 | - * A typical `NSLog` (or `DDTTYLogger`) prints detailed info as `[<process_id>:<thread_id>]`. | |
| 50 | - * For example: | |
| 51 | - * | |
| 52 | - * `2011-10-17 20:21:45.435 AppName[19928:5207] Your log message here` | |
| 53 | - * | |
| 54 | - * Where: | |
| 55 | - * `- 19928 = process id` | |
| 56 | - * `- 5207 = thread id (mach_thread_id printed in hex)` | |
| 57 | - * | |
| 58 | - * When using grand central dispatch (GCD), this information is less useful. | |
| 59 | - * This is because a single serial dispatch queue may be run on any thread from an internally managed thread pool. | |
| 60 | - * For example: | |
| 61 | - * | |
| 62 | - * `2011-10-17 20:32:31.111 AppName[19954:4d07] Message from my_serial_dispatch_queue` | |
| 63 | - * `2011-10-17 20:32:31.112 AppName[19954:5207] Message from my_serial_dispatch_queue` | |
| 64 | - * `2011-10-17 20:32:31.113 AppName[19954:2c55] Message from my_serial_dispatch_queue` | |
| 65 | - * | |
| 66 | - * This formatter allows you to replace the standard `[box:info]` with the dispatch_queue name. | |
| 67 | - * For example: | |
| 68 | - * | |
| 69 | - * `2011-10-17 20:32:31.111 AppName[img-scaling] Message from my_serial_dispatch_queue` | |
| 70 | - * `2011-10-17 20:32:31.112 AppName[img-scaling] Message from my_serial_dispatch_queue` | |
| 71 | - * `2011-10-17 20:32:31.113 AppName[img-scaling] Message from my_serial_dispatch_queue` | |
| 72 | - * | |
| 73 | - * If the dispatch_queue doesn't have a set name, then it falls back to the thread name. | |
| 74 | - * If the current thread doesn't have a set name, then it falls back to the mach_thread_id in hex (like normal). | |
| 75 | - * | |
| 76 | - * Note: If manually creating your own background threads (via `NSThread/alloc/init` or `NSThread/detachNeThread`), | |
| 77 | - * you can use `[[NSThread currentThread] setName:(NSString *)]`. | |
| 78 | - **/ | |
| 79 | -@interface DDDispatchQueueLogFormatter : NSObject <DDLogFormatter> | |
| 80 | - | |
| 81 | -/** | |
| 82 | - * Standard init method. | |
| 83 | - * Configure using properties as desired. | |
| 84 | - **/ | |
| 85 | -- (instancetype)init NS_DESIGNATED_INITIALIZER; | |
| 86 | - | |
| 87 | -/** | |
| 88 | - * Initializer with ability to set the queue mode | |
| 89 | - * | |
| 90 | - * @param mode choose between DDDispatchQueueLogFormatterModeShareble and DDDispatchQueueLogFormatterModeNonShareble, depending if the formatter is shared between several loggers or not | |
| 91 | - */ | |
| 92 | -- (instancetype)initWithMode:(DDDispatchQueueLogFormatterMode)mode; | |
| 93 | - | |
| 94 | -/** | |
| 95 | - * The minQueueLength restricts the minimum size of the [detail box]. | |
| 96 | - * If the minQueueLength is set to 0, there is no restriction. | |
| 97 | - * | |
| 98 | - * For example, say a dispatch_queue has a label of "diskIO": | |
| 99 | - * | |
| 100 | - * If the minQueueLength is 0: [diskIO] | |
| 101 | - * If the minQueueLength is 4: [diskIO] | |
| 102 | - * If the minQueueLength is 5: [diskIO] | |
| 103 | - * If the minQueueLength is 6: [diskIO] | |
| 104 | - * If the minQueueLength is 7: [diskIO ] | |
| 105 | - * If the minQueueLength is 8: [diskIO ] | |
| 106 | - * | |
| 107 | - * The default minQueueLength is 0 (no minimum, so [detail box] won't be padded). | |
| 108 | - * | |
| 109 | - * If you want every [detail box] to have the exact same width, | |
| 110 | - * set both minQueueLength and maxQueueLength to the same value. | |
| 111 | - **/ | |
| 112 | -@property (assign, atomic) NSUInteger minQueueLength; | |
| 113 | - | |
| 114 | -/** | |
| 115 | - * The maxQueueLength restricts the number of characters that will be inside the [detail box]. | |
| 116 | - * If the maxQueueLength is 0, there is no restriction. | |
| 117 | - * | |
| 118 | - * For example, say a dispatch_queue has a label of "diskIO": | |
| 119 | - * | |
| 120 | - * If the maxQueueLength is 0: [diskIO] | |
| 121 | - * If the maxQueueLength is 4: [disk] | |
| 122 | - * If the maxQueueLength is 5: [diskI] | |
| 123 | - * If the maxQueueLength is 6: [diskIO] | |
| 124 | - * If the maxQueueLength is 7: [diskIO] | |
| 125 | - * If the maxQueueLength is 8: [diskIO] | |
| 126 | - * | |
| 127 | - * The default maxQueueLength is 0 (no maximum, so [detail box] won't be truncated). | |
| 128 | - * | |
| 129 | - * If you want every [detail box] to have the exact same width, | |
| 130 | - * set both minQueueLength and maxQueueLength to the same value. | |
| 131 | - **/ | |
| 132 | -@property (assign, atomic) NSUInteger maxQueueLength; | |
| 133 | - | |
| 134 | -/** | |
| 135 | - * Sometimes queue labels have long names like "com.apple.main-queue", | |
| 136 | - * but you'd prefer something shorter like simply "main". | |
| 137 | - * | |
| 138 | - * This method allows you to set such preferred replacements. | |
| 139 | - * The above example is set by default. | |
| 140 | - * | |
| 141 | - * To remove/undo a previous replacement, invoke this method with nil for the 'shortLabel' parameter. | |
| 142 | - **/ | |
| 143 | -- (NSString *)replacementStringForQueueLabel:(NSString *)longLabel; | |
| 144 | - | |
| 145 | -/** | |
| 146 | - * See the `replacementStringForQueueLabel:` description | |
| 147 | - */ | |
| 148 | -- (void)setReplacementString:(NSString *)shortLabel forQueueLabel:(NSString *)longLabel; | |
| 149 | - | |
| 150 | -@end | |
| 151 | - | |
| 152 | -/** | |
| 153 | - * Category on `DDDispatchQueueLogFormatter` to make method declarations easier to extend/modify | |
| 154 | - **/ | |
| 155 | -@interface DDDispatchQueueLogFormatter (OverridableMethods) | |
| 156 | - | |
| 157 | -/** | |
| 158 | - * Date formatter default configuration | |
| 159 | - */ | |
| 160 | -- (void)configureDateFormatter:(NSDateFormatter *)dateFormatter; | |
| 161 | - | |
| 162 | -/** | |
| 163 | - * Formatter method to transfrom from date to string | |
| 164 | - */ | |
| 165 | -- (NSString *)stringFromDate:(NSDate *)date; | |
| 166 | - | |
| 167 | -/** | |
| 168 | - * Method to compute the queue thread label | |
| 169 | - */ | |
| 170 | -- (NSString *)queueThreadLabelForLogMessage:(DDLogMessage *)logMessage; | |
| 171 | - | |
| 172 | -/** | |
| 173 | - * The actual method that formats a message (transforms a `DDLogMessage` model into a printable string) | |
| 174 | - */ | |
| 175 | -- (NSString *)formatLogMessage:(DDLogMessage *)logMessage; | |
| 176 | - | |
| 177 | -@end | |
| 178 | - | |
| 179 | -#pragma mark - DDAtomicCounter | |
| 180 | - | |
| 181 | -@protocol DDAtomicCountable <NSObject> | |
| 182 | - | |
| 183 | -- (instancetype)initWithDefaultValue:(int32_t)defaultValue; | |
| 184 | -- (int32_t)increment; | |
| 185 | -- (int32_t)decrement; | |
| 186 | -- (int32_t)value; | |
| 187 | - | |
| 188 | -@end | |
| 189 | - | |
| 190 | -@interface DDAtomicCounter: NSObject<DDAtomicCountable> | |
| 191 | -@end |
Example/build/Debug-iphoneos/CocoaLumberjack/CocoaLumberjack.framework/Headers/DDFileLogger+Buffering.h deleted
100644 → 0
| 1 | -// Software License Agreement (BSD License) | |
| 2 | -// | |
| 3 | -// Copyright (c) 2010-2019, Deusty, LLC | |
| 4 | -// All rights reserved. | |
| 5 | -// | |
| 6 | -// Redistribution and use of this software in source and binary forms, | |
| 7 | -// with or without modification, are permitted provided that the following conditions are met: | |
| 8 | -// | |
| 9 | -// * Redistributions of source code must retain the above copyright notice, | |
| 10 | -// this list of conditions and the following disclaimer. | |
| 11 | -// | |
| 12 | -// * Neither the name of Deusty nor the names of its contributors may be used | |
| 13 | -// to endorse or promote products derived from this software without specific | |
| 14 | -// prior written permission of Deusty, LLC. | |
| 15 | - | |
| 16 | -#import <CocoaLumberjack/DDFileLogger.h> | |
| 17 | - | |
| 18 | -NS_ASSUME_NONNULL_BEGIN | |
| 19 | - | |
| 20 | -@interface DDFileLogger (Buffering) | |
| 21 | - | |
| 22 | -- (instancetype)wrapWithBuffer; | |
| 23 | -- (instancetype)unwrapFromBuffer; | |
| 24 | - | |
| 25 | -@end | |
| 26 | - | |
| 27 | -NS_ASSUME_NONNULL_END |
Example/build/Debug-iphoneos/CocoaLumberjack/CocoaLumberjack.framework/Headers/DDFileLogger.h deleted
100644 → 0
| 1 | -// Software License Agreement (BSD License) | |
| 2 | -// | |
| 3 | -// Copyright (c) 2010-2019, Deusty, LLC | |
| 4 | -// All rights reserved. | |
| 5 | -// | |
| 6 | -// Redistribution and use of this software in source and binary forms, | |
| 7 | -// with or without modification, are permitted provided that the following conditions are met: | |
| 8 | -// | |
| 9 | -// * Redistributions of source code must retain the above copyright notice, | |
| 10 | -// this list of conditions and the following disclaimer. | |
| 11 | -// | |
| 12 | -// * Neither the name of Deusty nor the names of its contributors may be used | |
| 13 | -// to endorse or promote products derived from this software without specific | |
| 14 | -// prior written permission of Deusty, LLC. | |
| 15 | - | |
| 16 | -// Disable legacy macros | |
| 17 | -#ifndef DD_LEGACY_MACROS | |
| 18 | - #define DD_LEGACY_MACROS 0 | |
| 19 | -#endif | |
| 20 | - | |
| 21 | -#import <CocoaLumberjack/DDLog.h> | |
| 22 | - | |
| 23 | -NS_ASSUME_NONNULL_BEGIN | |
| 24 | - | |
| 25 | -@class DDLogFileInfo; | |
| 26 | - | |
| 27 | -/** | |
| 28 | - * This class provides a logger to write log statements to a file. | |
| 29 | - **/ | |
| 30 | - | |
| 31 | - | |
| 32 | -// Default configuration and safety/sanity values. | |
| 33 | -// | |
| 34 | -// maximumFileSize -> kDDDefaultLogMaxFileSize | |
| 35 | -// rollingFrequency -> kDDDefaultLogRollingFrequency | |
| 36 | -// maximumNumberOfLogFiles -> kDDDefaultLogMaxNumLogFiles | |
| 37 | -// logFilesDiskQuota -> kDDDefaultLogFilesDiskQuota | |
| 38 | -// | |
| 39 | -// You should carefully consider the proper configuration values for your application. | |
| 40 | - | |
| 41 | -extern unsigned long long const kDDDefaultLogMaxFileSize; | |
| 42 | -extern NSTimeInterval const kDDDefaultLogRollingFrequency; | |
| 43 | -extern NSUInteger const kDDDefaultLogMaxNumLogFiles; | |
| 44 | -extern unsigned long long const kDDDefaultLogFilesDiskQuota; | |
| 45 | - | |
| 46 | - | |
| 47 | -//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | |
| 48 | -#pragma mark - | |
| 49 | -//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | |
| 50 | - | |
| 51 | -/** | |
| 52 | - * The LogFileManager protocol is designed to allow you to control all aspects of your log files. | |
| 53 | - * | |
| 54 | - * The primary purpose of this is to allow you to do something with the log files after they have been rolled. | |
| 55 | - * Perhaps you want to compress them to save disk space. | |
| 56 | - * Perhaps you want to upload them to an FTP server. | |
| 57 | - * Perhaps you want to run some analytics on the file. | |
| 58 | - * | |
| 59 | - * A default LogFileManager is, of course, provided. | |
| 60 | - * The default LogFileManager simply deletes old log files according to the maximumNumberOfLogFiles property. | |
| 61 | - * | |
| 62 | - * This protocol provides various methods to fetch the list of log files. | |
| 63 | - * | |
| 64 | - * There are two variants: sorted and unsorted. | |
| 65 | - * If sorting is not necessary, the unsorted variant is obviously faster. | |
| 66 | - * The sorted variant will return an array sorted by when the log files were created, | |
| 67 | - * with the most recently created log file at index 0, and the oldest log file at the end of the array. | |
| 68 | - * | |
| 69 | - * You can fetch only the log file paths (full path including name), log file names (name only), | |
| 70 | - * or an array of `DDLogFileInfo` objects. | |
| 71 | - * The `DDLogFileInfo` class is documented below, and provides a handy wrapper that | |
| 72 | - * gives you easy access to various file attributes such as the creation date or the file size. | |
| 73 | - */ | |
| 74 | -@protocol DDLogFileManager <NSObject> | |
| 75 | -@required | |
| 76 | - | |
| 77 | -// Public properties | |
| 78 | - | |
| 79 | -/** | |
| 80 | - * The maximum number of archived log files to keep on disk. | |
| 81 | - * For example, if this property is set to 3, | |
| 82 | - * then the LogFileManager will only keep 3 archived log files (plus the current active log file) on disk. | |
| 83 | - * Once the active log file is rolled/archived, then the oldest of the existing 3 rolled/archived log files is deleted. | |
| 84 | - * | |
| 85 | - * You may optionally disable this option by setting it to zero. | |
| 86 | - **/ | |
| 87 | -@property (readwrite, assign, atomic) NSUInteger maximumNumberOfLogFiles; | |
| 88 | - | |
| 89 | -/** | |
| 90 | - * The maximum space that logs can take. On rolling logfile all old log files that exceed logFilesDiskQuota will | |
| 91 | - * be deleted. | |
| 92 | - * | |
| 93 | - * You may optionally disable this option by setting it to zero. | |
| 94 | - **/ | |
| 95 | -@property (readwrite, assign, atomic) unsigned long long logFilesDiskQuota; | |
| 96 | - | |
| 97 | -// Public methods | |
| 98 | - | |
| 99 | -/** | |
| 100 | - * Returns the logs directory (path) | |
| 101 | - */ | |
| 102 | -@property (nonatomic, readonly, copy) NSString *logsDirectory; | |
| 103 | - | |
| 104 | -/** | |
| 105 | - * Returns an array of `NSString` objects, | |
| 106 | - * each of which is the filePath to an existing log file on disk. | |
| 107 | - **/ | |
| 108 | -@property (nonatomic, readonly, strong) NSArray<NSString *> *unsortedLogFilePaths; | |
| 109 | - | |
| 110 | -/** | |
| 111 | - * Returns an array of `NSString` objects, | |
| 112 | - * each of which is the fileName of an existing log file on disk. | |
| 113 | - **/ | |
| 114 | -@property (nonatomic, readonly, strong) NSArray<NSString *> *unsortedLogFileNames; | |
| 115 | - | |
| 116 | -/** | |
| 117 | - * Returns an array of `DDLogFileInfo` objects, | |
| 118 | - * each representing an existing log file on disk, | |
| 119 | - * and containing important information about the log file such as it's modification date and size. | |
| 120 | - **/ | |
| 121 | -@property (nonatomic, readonly, strong) NSArray<DDLogFileInfo *> *unsortedLogFileInfos; | |
| 122 | - | |
| 123 | -/** | |
| 124 | - * Just like the `unsortedLogFilePaths` method, but sorts the array. | |
| 125 | - * The items in the array are sorted by creation date. | |
| 126 | - * The first item in the array will be the most recently created log file. | |
| 127 | - **/ | |
| 128 | -@property (nonatomic, readonly, strong) NSArray<NSString *> *sortedLogFilePaths; | |
| 129 | - | |
| 130 | -/** | |
| 131 | - * Just like the `unsortedLogFileNames` method, but sorts the array. | |
| 132 | - * The items in the array are sorted by creation date. | |
| 133 | - * The first item in the array will be the most recently created log file. | |
| 134 | - **/ | |
| 135 | -@property (nonatomic, readonly, strong) NSArray<NSString *> *sortedLogFileNames; | |
| 136 | - | |
| 137 | -/** | |
| 138 | - * Just like the `unsortedLogFileInfos` method, but sorts the array. | |
| 139 | - * The items in the array are sorted by creation date. | |
| 140 | - * The first item in the array will be the most recently created log file. | |
| 141 | - **/ | |
| 142 | -@property (nonatomic, readonly, strong) NSArray<DDLogFileInfo *> *sortedLogFileInfos; | |
| 143 | - | |
| 144 | -// Private methods (only to be used by DDFileLogger) | |
| 145 | - | |
| 146 | -/** | |
| 147 | - * Generates a new unique log file path, and creates the corresponding log file. | |
| 148 | - * This method is executed directly on the file logger's internal queue. | |
| 149 | - * The file has to exist by the time the method returns. | |
| 150 | - **/ | |
| 151 | -- (NSString *)createNewLogFile; | |
| 152 | - | |
| 153 | -@optional | |
| 154 | - | |
| 155 | -// Notifications from DDFileLogger | |
| 156 | - | |
| 157 | -/** | |
| 158 | - * Called when a log file was archived. Executed on global queue with default priority. | |
| 159 | - */ | |
| 160 | -- (void)didArchiveLogFile:(NSString *)logFilePath NS_SWIFT_NAME(didArchiveLogFile(atPath:)); | |
| 161 | - | |
| 162 | -/** | |
| 163 | - * Called when the roll action was executed and the log was archived. | |
| 164 | - * Executed on global queue with default priority. | |
| 165 | - */ | |
| 166 | -- (void)didRollAndArchiveLogFile:(NSString *)logFilePath NS_SWIFT_NAME(didRollAndArchiveLogFile(atPath:)); | |
| 167 | - | |
| 168 | -@end | |
| 169 | - | |
| 170 | -//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | |
| 171 | -#pragma mark - | |
| 172 | -//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | |
| 173 | - | |
| 174 | -/** | |
| 175 | - * Default log file manager. | |
| 176 | - * | |
| 177 | - * All log files are placed inside the logsDirectory. | |
| 178 | - * If a specific logsDirectory isn't specified, the default directory is used. | |
| 179 | - * On Mac, this is in `~/Library/Logs/<Application Name>`. | |
| 180 | - * On iPhone, this is in `~/Library/Caches/Logs`. | |
| 181 | - * | |
| 182 | - * Log files are named `"<bundle identifier> <date> <time>.log"` | |
| 183 | - * Example: `com.organization.myapp 2013-12-03 17-14.log` | |
| 184 | - * | |
| 185 | - * Archived log files are automatically deleted according to the `maximumNumberOfLogFiles` property. | |
| 186 | - **/ | |
| 187 | -@interface DDLogFileManagerDefault : NSObject <DDLogFileManager> | |
| 188 | - | |
| 189 | -/** | |
| 190 | - * Default initializer | |
| 191 | - */ | |
| 192 | -- (instancetype)init; | |
| 193 | - | |
| 194 | -/** | |
| 195 | - * If logDirectory is not specified, then a folder called "Logs" is created in the app's cache directory. | |
| 196 | - * While running on the simulator, the "Logs" folder is located in the library temporary directory. | |
| 197 | - */ | |
| 198 | -- (instancetype)initWithLogsDirectory:(NSString * __nullable)logsDirectory NS_DESIGNATED_INITIALIZER; | |
| 199 | - | |
| 200 | -#if TARGET_OS_IPHONE | |
| 201 | -/* | |
| 202 | - * Calling this constructor you can override the default "automagically" chosen NSFileProtection level. | |
| 203 | - * Useful if you are writing a command line utility / CydiaSubstrate addon for iOS that has no NSBundle | |
| 204 | - * or like SpringBoard no BackgroundModes key in the NSBundle: | |
| 205 | - * iPhone:~ root# cycript -p SpringBoard | |
| 206 | - * cy# [NSBundle mainBundle] | |
| 207 | - * #"NSBundle </System/Library/CoreServices/SpringBoard.app> (loaded)" | |
| 208 | - * cy# [[NSBundle mainBundle] objectForInfoDictionaryKey:@"UIBackgroundModes"]; | |
| 209 | - * null | |
| 210 | - * cy# | |
| 211 | - **/ | |
| 212 | -- (instancetype)initWithLogsDirectory:(NSString * __nullable)logsDirectory | |
| 213 | - defaultFileProtectionLevel:(NSFileProtectionType)fileProtectionLevel; | |
| 214 | -#endif | |
| 215 | - | |
| 216 | -/* | |
| 217 | - * Methods to override. | |
| 218 | - * | |
| 219 | - * Log files are named `"<bundle identifier> <date> <time>.log"` | |
| 220 | - * Example: `com.organization.myapp 2013-12-03 17-14.log` | |
| 221 | - * | |
| 222 | - * If you wish to change default filename, you can override following two methods. | |
| 223 | - * - `newLogFileName` method would be called on new logfile creation. | |
| 224 | - * - `isLogFile:` method would be called to filter log files from all other files in logsDirectory. | |
| 225 | - * You have to parse given filename and return YES if it is logFile. | |
| 226 | - * | |
| 227 | - * **NOTE** | |
| 228 | - * `newLogFileName` returns filename. If appropriate file already exists, number would be added | |
| 229 | - * to filename before extension. You have to handle this case in isLogFile: method. | |
| 230 | - * | |
| 231 | - * Example: | |
| 232 | - * - newLogFileName returns `"com.organization.myapp 2013-12-03.log"`, | |
| 233 | - * file `"com.organization.myapp 2013-12-03.log"` would be created. | |
| 234 | - * - after some time `"com.organization.myapp 2013-12-03.log"` is archived | |
| 235 | - * - newLogFileName again returns `"com.organization.myapp 2013-12-03.log"`, | |
| 236 | - * file `"com.organization.myapp 2013-12-03 2.log"` would be created. | |
| 237 | - * - after some time `"com.organization.myapp 2013-12-03 1.log"` is archived | |
| 238 | - * - newLogFileName again returns `"com.organization.myapp 2013-12-03.log"`, | |
| 239 | - * file `"com.organization.myapp 2013-12-03 3.log"` would be created. | |
| 240 | - **/ | |
| 241 | - | |
| 242 | -/** | |
| 243 | - * Generates log file name with default format `"<bundle identifier> <date> <time>.log"` | |
| 244 | - * Example: `MobileSafari 2013-12-03 17-14.log` | |
| 245 | - * | |
| 246 | - * You can change it by overriding `newLogFileName` and `isLogFile:` methods. | |
| 247 | - **/ | |
| 248 | -@property (readonly, copy) NSString *newLogFileName; | |
| 249 | - | |
| 250 | -/** | |
| 251 | - * Default log file name is `"<bundle identifier> <date> <time>.log"`. | |
| 252 | - * Example: `MobileSafari 2013-12-03 17-14.log` | |
| 253 | - * | |
| 254 | - * You can change it by overriding `newLogFileName` and `isLogFile:` methods. | |
| 255 | - **/ | |
| 256 | -- (BOOL)isLogFile:(NSString *)fileName NS_SWIFT_NAME(isLogFile(withName:)); | |
| 257 | - | |
| 258 | -/** | |
| 259 | - * New log files are created empty by default in `createNewLogFile:` method | |
| 260 | - * | |
| 261 | - * If you wish to specify a common file header to use in your log files, | |
| 262 | - * you can set the initial log file contents by overriding `logFileHeader` | |
| 263 | - **/ | |
| 264 | -@property (readonly, copy, nullable) NSString *logFileHeader; | |
| 265 | - | |
| 266 | -/* Inherited from DDLogFileManager protocol: | |
| 267 | - | |
| 268 | - @property (readwrite, assign, atomic) NSUInteger maximumNumberOfLogFiles; | |
| 269 | - @property (readwrite, assign, atomic) NSUInteger logFilesDiskQuota; | |
| 270 | - | |
| 271 | - - (NSString *)logsDirectory; | |
| 272 | - | |
| 273 | - - (NSArray *)unsortedLogFilePaths; | |
| 274 | - - (NSArray *)unsortedLogFileNames; | |
| 275 | - - (NSArray *)unsortedLogFileInfos; | |
| 276 | - | |
| 277 | - - (NSArray *)sortedLogFilePaths; | |
| 278 | - - (NSArray *)sortedLogFileNames; | |
| 279 | - - (NSArray *)sortedLogFileInfos; | |
| 280 | - | |
| 281 | - */ | |
| 282 | - | |
| 283 | -@end | |
| 284 | - | |
| 285 | -//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | |
| 286 | -#pragma mark - | |
| 287 | -//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | |
| 288 | - | |
| 289 | -/** | |
| 290 | - * Most users will want file log messages to be prepended with the date and time. | |
| 291 | - * Rather than forcing the majority of users to write their own formatter, | |
| 292 | - * we will supply a logical default formatter. | |
| 293 | - * Users can easily replace this formatter with their own by invoking the `setLogFormatter:` method. | |
| 294 | - * It can also be removed by calling `setLogFormatter:`, and passing a nil parameter. | |
| 295 | - * | |
| 296 | - * In addition to the convenience of having a logical default formatter, | |
| 297 | - * it will also provide a template that makes it easy for developers to copy and change. | |
| 298 | - **/ | |
| 299 | -@interface DDLogFileFormatterDefault : NSObject <DDLogFormatter> | |
| 300 | - | |
| 301 | -/** | |
| 302 | - * Default initializer | |
| 303 | - */ | |
| 304 | -- (instancetype)init; | |
| 305 | - | |
| 306 | -/** | |
| 307 | - * Designated initializer, requires a date formatter | |
| 308 | - */ | |
| 309 | -- (instancetype)initWithDateFormatter:(NSDateFormatter * __nullable)dateFormatter NS_DESIGNATED_INITIALIZER; | |
| 310 | - | |
| 311 | -@end | |
| 312 | - | |
| 313 | -//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | |
| 314 | -#pragma mark - | |
| 315 | -//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | |
| 316 | - | |
| 317 | -/** | |
| 318 | - * The standard implementation for a file logger | |
| 319 | - */ | |
| 320 | -@interface DDFileLogger : DDAbstractLogger <DDLogger> | |
| 321 | - | |
| 322 | -/** | |
| 323 | - * Default initializer. | |
| 324 | - */ | |
| 325 | -- (instancetype)init; | |
| 326 | - | |
| 327 | -/** | |
| 328 | - * Designated initializer, requires a `DDLogFileManager` instance. | |
| 329 | - * A global queue w/ default priority is used to run callbacks. | |
| 330 | - * If needed, specify queue using `initWithLogFileManager:completionQueue:`. | |
| 331 | - */ | |
| 332 | -- (instancetype)initWithLogFileManager:(id <DDLogFileManager> __nullable)logFileManager; | |
| 333 | - | |
| 334 | -/** | |
| 335 | - * Designated initializer, requires a `DDLogFileManager` instance. | |
| 336 | - * The completionQueue is used to execute `didArchiveLogFile`, `didRollAndArchiveLogFile`, | |
| 337 | - * and the callback in `rollLog`. If nil, a global queue w/ default priority is used. | |
| 338 | - */ | |
| 339 | -- (instancetype)initWithLogFileManager:(id <DDLogFileManager> __nullable)logFileManager | |
| 340 | - completionQueue:(dispatch_queue_t __nullable)dispatchQueue NS_DESIGNATED_INITIALIZER; | |
| 341 | - | |
| 342 | -/** | |
| 343 | - * Called when the logger is about to write message. Call super before your implementation. | |
| 344 | - */ | |
| 345 | -- (void)willLogMessage NS_REQUIRES_SUPER; | |
| 346 | - | |
| 347 | -/** | |
| 348 | - * Called when the logger wrote message. Call super after your implementation. | |
| 349 | - */ | |
| 350 | -- (void)didLogMessage NS_REQUIRES_SUPER; | |
| 351 | - | |
| 352 | -/** | |
| 353 | - * Writes all in-memory log data to the permanent storage. Call super before your implementation. | |
| 354 | - * Don't call this method directly, instead use the `[DDLog flushLog]` to ensure all log messages are included in flush. | |
| 355 | - */ | |
| 356 | -- (void)flush NS_REQUIRES_SUPER; | |
| 357 | - | |
| 358 | -/** | |
| 359 | - * Called when the logger checks archive or not current log file. | |
| 360 | - * Override this method to extend standard behavior. By default returns NO. | |
| 361 | - * This is executed directly on the logger's internal queue, so keep processing light! | |
| 362 | - */ | |
| 363 | -- (BOOL)shouldArchiveRecentLogFileInfo:(DDLogFileInfo *)recentLogFileInfo; | |
| 364 | - | |
| 365 | -/** | |
| 366 | - * Log File Rolling: | |
| 367 | - * | |
| 368 | - * `maximumFileSize`: | |
| 369 | - * The approximate maximum size (in bytes) to allow log files to grow. | |
| 370 | - * If a log file is larger than this value after a log statement is appended, | |
| 371 | - * then the log file is rolled. | |
| 372 | - * | |
| 373 | - * `rollingFrequency` | |
| 374 | - * How often to roll the log file. | |
| 375 | - * The frequency is given as an `NSTimeInterval`, which is a double that specifies the interval in seconds. | |
| 376 | - * Once the log file gets to be this old, it is rolled. | |
| 377 | - * | |
| 378 | - * `doNotReuseLogFiles` | |
| 379 | - * When set, will always create a new log file at application launch. | |
| 380 | - * | |
| 381 | - * Both the `maximumFileSize` and the `rollingFrequency` are used to manage rolling. | |
| 382 | - * Whichever occurs first will cause the log file to be rolled. | |
| 383 | - * | |
| 384 | - * For example: | |
| 385 | - * The `rollingFrequency` is 24 hours, | |
| 386 | - * but the log file surpasses the `maximumFileSize` after only 20 hours. | |
| 387 | - * The log file will be rolled at that 20 hour mark. | |
| 388 | - * A new log file will be created, and the 24 hour timer will be restarted. | |
| 389 | - * | |
| 390 | - * You may optionally disable rolling due to filesize by setting `maximumFileSize` to zero. | |
| 391 | - * If you do so, rolling is based solely on `rollingFrequency`. | |
| 392 | - * | |
| 393 | - * You may optionally disable rolling due to time by setting `rollingFrequency` to zero (or any non-positive number). | |
| 394 | - * If you do so, rolling is based solely on `maximumFileSize`. | |
| 395 | - * | |
| 396 | - * If you disable both `maximumFileSize` and `rollingFrequency`, then the log file won't ever be rolled. | |
| 397 | - * This is strongly discouraged. | |
| 398 | - **/ | |
| 399 | -@property (readwrite, assign) unsigned long long maximumFileSize; | |
| 400 | - | |
| 401 | -/** | |
| 402 | - * See description for `maximumFileSize` | |
| 403 | - */ | |
| 404 | -@property (readwrite, assign) NSTimeInterval rollingFrequency; | |
| 405 | - | |
| 406 | -/** | |
| 407 | - * See description for `maximumFileSize` | |
| 408 | - */ | |
| 409 | -@property (readwrite, assign, atomic) BOOL doNotReuseLogFiles; | |
| 410 | - | |
| 411 | -/** | |
| 412 | - * The DDLogFileManager instance can be used to retrieve the list of log files, | |
| 413 | - * and configure the maximum number of archived log files to keep. | |
| 414 | - * | |
| 415 | - * @see DDLogFileManager.maximumNumberOfLogFiles | |
| 416 | - **/ | |
| 417 | -@property (strong, nonatomic, readonly) id <DDLogFileManager> logFileManager; | |
| 418 | - | |
| 419 | -/** | |
| 420 | - * When using a custom formatter you can set the `logMessage` method not to append | |
| 421 | - * `\n` character after each output. This allows for some greater flexibility with | |
| 422 | - * custom formatters. Default value is YES. | |
| 423 | - **/ | |
| 424 | -@property (nonatomic, readwrite, assign) BOOL automaticallyAppendNewlineForCustomFormatters; | |
| 425 | - | |
| 426 | -/** | |
| 427 | - * You can optionally force the current log file to be rolled with this method. | |
| 428 | - * CompletionBlock will be called on main queue. | |
| 429 | - */ | |
| 430 | -- (void)rollLogFileWithCompletionBlock:(void (^ __nullable)(void))completionBlock | |
| 431 | - NS_SWIFT_NAME(rollLogFile(withCompletion:)); | |
| 432 | - | |
| 433 | -/** | |
| 434 | - * Method is deprecated. | |
| 435 | - * @deprecated Use `rollLogFileWithCompletionBlock:` method instead. | |
| 436 | - */ | |
| 437 | -- (void)rollLogFile __attribute((deprecated)); | |
| 438 | - | |
| 439 | -// Inherited from DDAbstractLogger | |
| 440 | - | |
| 441 | -// - (id <DDLogFormatter>)logFormatter; | |
| 442 | -// - (void)setLogFormatter:(id <DDLogFormatter>)formatter; | |
| 443 | - | |
| 444 | -/** | |
| 445 | - * Returns the log file that should be used. | |
| 446 | - * If there is an existing log file that is suitable, | |
| 447 | - * within the constraints of `maximumFileSize` and `rollingFrequency`, then it is returned. | |
| 448 | - * | |
| 449 | - * Otherwise a new file is created and returned. | |
| 450 | - **/ | |
| 451 | -@property (nonatomic, readonly, strong) DDLogFileInfo *currentLogFileInfo; | |
| 452 | - | |
| 453 | -@end | |
| 454 | - | |
| 455 | -//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | |
| 456 | -#pragma mark - | |
| 457 | -//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | |
| 458 | - | |
| 459 | -/** | |
| 460 | - * `DDLogFileInfo` is a simple class that provides access to various file attributes. | |
| 461 | - * It provides good performance as it only fetches the information if requested, | |
| 462 | - * and it caches the information to prevent duplicate fetches. | |
| 463 | - * | |
| 464 | - * It was designed to provide quick snapshots of the current state of log files, | |
| 465 | - * and to help sort log files in an array. | |
| 466 | - * | |
| 467 | - * This class does not monitor the files, or update it's cached attribute values if the file changes on disk. | |
| 468 | - * This is not what the class was designed for. | |
| 469 | - * | |
| 470 | - * If you absolutely must get updated values, | |
| 471 | - * you can invoke the reset method which will clear the cache. | |
| 472 | - **/ | |
| 473 | -@interface DDLogFileInfo : NSObject | |
| 474 | - | |
| 475 | -@property (strong, nonatomic, readonly) NSString *filePath; | |
| 476 | -@property (strong, nonatomic, readonly) NSString *fileName; | |
| 477 | - | |
| 478 | -#if FOUNDATION_SWIFT_SDK_EPOCH_AT_LEAST(8) | |
| 479 | -@property (strong, nonatomic, readonly) NSDictionary<NSFileAttributeKey, id> *fileAttributes; | |
| 480 | -#else | |
| 481 | -@property (strong, nonatomic, readonly) NSDictionary<NSString *, id> *fileAttributes; | |
| 482 | -#endif | |
| 483 | - | |
| 484 | -@property (strong, nonatomic, readonly) NSDate *creationDate; | |
| 485 | -@property (strong, nonatomic, readonly) NSDate *modificationDate; | |
| 486 | - | |
| 487 | -@property (nonatomic, readonly) unsigned long long fileSize; | |
| 488 | - | |
| 489 | -@property (nonatomic, readonly) NSTimeInterval age; | |
| 490 | - | |
| 491 | -@property (nonatomic, readwrite) BOOL isArchived; | |
| 492 | - | |
| 493 | -+ (instancetype)logFileWithPath:(NSString *)filePath NS_SWIFT_UNAVAILABLE("Use init(filePath:)"); | |
| 494 | - | |
| 495 | -- (instancetype)init NS_UNAVAILABLE; | |
| 496 | -- (instancetype)initWithFilePath:(NSString *)filePath NS_DESIGNATED_INITIALIZER; | |
| 497 | - | |
| 498 | -- (void)reset; | |
| 499 | -- (void)renameFile:(NSString *)newFileName NS_SWIFT_NAME(renameFile(to:)); | |
| 500 | - | |
| 501 | -#if TARGET_IPHONE_SIMULATOR | |
| 502 | - | |
| 503 | -// So here's the situation. | |
| 504 | -// Extended attributes are perfect for what we're trying to do here (marking files as archived). | |
| 505 | -// This is exactly what extended attributes were designed for. | |
| 506 | -// | |
| 507 | -// But Apple screws us over on the simulator. | |
| 508 | -// Everytime you build-and-go, they copy the application into a new folder on the hard drive, | |
| 509 | -// and as part of the process they strip extended attributes from our log files. | |
| 510 | -// Normally, a copy of a file preserves extended attributes. | |
| 511 | -// So obviously Apple has gone to great lengths to piss us off. | |
| 512 | -// | |
| 513 | -// Thus we use a slightly different tactic for marking log files as archived in the simulator. | |
| 514 | -// That way it "just works" and there's no confusion when testing. | |
| 515 | -// | |
| 516 | -// The difference in method names is indicative of the difference in functionality. | |
| 517 | -// On the simulator we add an attribute by appending a filename extension. | |
| 518 | -// | |
| 519 | -// For example: | |
| 520 | -// "mylog.txt" -> "mylog.archived.txt" | |
| 521 | -// "mylog" -> "mylog.archived" | |
| 522 | - | |
| 523 | -- (BOOL)hasExtensionAttributeWithName:(NSString *)attrName; | |
| 524 | - | |
| 525 | -- (void)addExtensionAttributeWithName:(NSString *)attrName; | |
| 526 | -- (void)removeExtensionAttributeWithName:(NSString *)attrName; | |
| 527 | - | |
| 528 | -#else /* if TARGET_IPHONE_SIMULATOR */ | |
| 529 | - | |
| 530 | -// Normal use of extended attributes used everywhere else, | |
| 531 | -// such as on Macs and on iPhone devices. | |
| 532 | - | |
| 533 | -- (BOOL)hasExtendedAttributeWithName:(NSString *)attrName; | |
| 534 | - | |
| 535 | -- (void)addExtendedAttributeWithName:(NSString *)attrName; | |
| 536 | -- (void)removeExtendedAttributeWithName:(NSString *)attrName; | |
| 537 | - | |
| 538 | -#endif /* if TARGET_IPHONE_SIMULATOR */ | |
| 539 | - | |
| 540 | -- (NSComparisonResult)reverseCompareByCreationDate:(DDLogFileInfo *)another; | |
| 541 | -- (NSComparisonResult)reverseCompareByModificationDate:(DDLogFileInfo *)another; | |
| 542 | - | |
| 543 | -@end | |
| 544 | - | |
| 545 | -NS_ASSUME_NONNULL_END |
Example/build/Debug-iphoneos/CocoaLumberjack/CocoaLumberjack.framework/Headers/DDLegacyMacros.h deleted
100644 → 0
| 1 | -// Software License Agreement (BSD License) | |
| 2 | -// | |
| 3 | -// Copyright (c) 2010-2019, Deusty, LLC | |
| 4 | -// All rights reserved. | |
| 5 | -// | |
| 6 | -// Redistribution and use of this software in source and binary forms, | |
| 7 | -// with or without modification, are permitted provided that the following conditions are met: | |
| 8 | -// | |
| 9 | -// * Redistributions of source code must retain the above copyright notice, | |
| 10 | -// this list of conditions and the following disclaimer. | |
| 11 | -// | |
| 12 | -// * Neither the name of Deusty nor the names of its contributors may be used | |
| 13 | -// to endorse or promote products derived from this software without specific | |
| 14 | -// prior written permission of Deusty, LLC. | |
| 15 | - | |
| 16 | -/** | |
| 17 | - * Legacy macros used for 1.9.x backwards compatibility. | |
| 18 | - * | |
| 19 | - * Imported by default when importing a DDLog.h directly and DD_LEGACY_MACROS is not defined and set to 0. | |
| 20 | - **/ | |
| 21 | -#if DD_LEGACY_MACROS | |
| 22 | - | |
| 23 | -#warning CocoaLumberjack 1.9.x legacy macros enabled. \ | |
| 24 | -Disable legacy macros by importing CocoaLumberjack.h or DDLogMacros.h instead of DDLog.h or add `#define DD_LEGACY_MACROS 0` before importing DDLog.h. | |
| 25 | - | |
| 26 | -#ifndef LOG_LEVEL_DEF | |
| 27 | - #define LOG_LEVEL_DEF ddLogLevel | |
| 28 | -#endif | |
| 29 | - | |
| 30 | -#define LOG_FLAG_ERROR DDLogFlagError | |
| 31 | -#define LOG_FLAG_WARN DDLogFlagWarning | |
| 32 | -#define LOG_FLAG_INFO DDLogFlagInfo | |
| 33 | -#define LOG_FLAG_DEBUG DDLogFlagDebug | |
| 34 | -#define LOG_FLAG_VERBOSE DDLogFlagVerbose | |
| 35 | - | |
| 36 | -#define LOG_LEVEL_OFF DDLogLevelOff | |
| 37 | -#define LOG_LEVEL_ERROR DDLogLevelError | |
| 38 | -#define LOG_LEVEL_WARN DDLogLevelWarning | |
| 39 | -#define LOG_LEVEL_INFO DDLogLevelInfo | |
| 40 | -#define LOG_LEVEL_DEBUG DDLogLevelDebug | |
| 41 | -#define LOG_LEVEL_VERBOSE DDLogLevelVerbose | |
| 42 | -#define LOG_LEVEL_ALL DDLogLevelAll | |
| 43 | - | |
| 44 | -#define LOG_ASYNC_ENABLED YES | |
| 45 | - | |
| 46 | -#define LOG_ASYNC_ERROR ( NO && LOG_ASYNC_ENABLED) | |
| 47 | -#define LOG_ASYNC_WARN (YES && LOG_ASYNC_ENABLED) | |
| 48 | -#define LOG_ASYNC_INFO (YES && LOG_ASYNC_ENABLED) | |
| 49 | -#define LOG_ASYNC_DEBUG (YES && LOG_ASYNC_ENABLED) | |
| 50 | -#define LOG_ASYNC_VERBOSE (YES && LOG_ASYNC_ENABLED) | |
| 51 | - | |
| 52 | -#define LOG_MACRO(isAsynchronous, lvl, flg, ctx, atag, fnct, frmt, ...) \ | |
| 53 | - [DDLog log : isAsynchronous \ | |
| 54 | - level : lvl \ | |
| 55 | - flag : flg \ | |
| 56 | - context : ctx \ | |
| 57 | - file : __FILE__ \ | |
| 58 | - function : fnct \ | |
| 59 | - line : __LINE__ \ | |
| 60 | - tag : atag \ | |
| 61 | - format : (frmt), ## __VA_ARGS__] | |
| 62 | - | |
| 63 | -#define LOG_MAYBE(async, lvl, flg, ctx, fnct, frmt, ...) \ | |
| 64 | - do { if(lvl & flg) LOG_MACRO(async, lvl, flg, ctx, nil, fnct, frmt, ##__VA_ARGS__); } while(0) | |
| 65 | - | |
| 66 | -#define LOG_OBJC_MAYBE(async, lvl, flg, ctx, frmt, ...) \ | |
| 67 | - LOG_MAYBE(async, lvl, flg, ctx, __PRETTY_FUNCTION__, frmt, ## __VA_ARGS__) | |
| 68 | - | |
| 69 | -#define DDLogError(frmt, ...) LOG_OBJC_MAYBE(LOG_ASYNC_ERROR, LOG_LEVEL_DEF, LOG_FLAG_ERROR, 0, frmt, ##__VA_ARGS__) | |
| 70 | -#define DDLogWarn(frmt, ...) LOG_OBJC_MAYBE(LOG_ASYNC_WARN, LOG_LEVEL_DEF, LOG_FLAG_WARN, 0, frmt, ##__VA_ARGS__) | |
| 71 | -#define DDLogInfo(frmt, ...) LOG_OBJC_MAYBE(LOG_ASYNC_INFO, LOG_LEVEL_DEF, LOG_FLAG_INFO, 0, frmt, ##__VA_ARGS__) | |
| 72 | -#define DDLogDebug(frmt, ...) LOG_OBJC_MAYBE(LOG_ASYNC_DEBUG, LOG_LEVEL_DEF, LOG_FLAG_DEBUG, 0, frmt, ##__VA_ARGS__) | |
| 73 | -#define DDLogVerbose(frmt, ...) LOG_OBJC_MAYBE(LOG_ASYNC_VERBOSE, LOG_LEVEL_DEF, LOG_FLAG_VERBOSE, 0, frmt, ##__VA_ARGS__) | |
| 74 | - | |
| 75 | -#endif |