no message

This commit is contained in:
Peter 2015-05-23 23:52:08 +03:00
parent fa70b8bcbf
commit cbb1ee599a
20 changed files with 371 additions and 68 deletions

View File

@ -0,0 +1,10 @@
#import <Foundation/Foundation.h>
#import <SSignalKit/SSignalKit.h>
#import <MTProtoKit/MTContext.h>
@interface MTDiscoverConnectionSignals : NSObject
+ (SSignal *)discoverSchemeWithContext:(MTContext *)context addressList:(NSArray *)addressList preferMedia:(bool)preferMedia;
@end

View File

@ -0,0 +1,204 @@
#import "MTDiscoverConnectionSignals.h"
#import "MTTcpConnection.h"
#import "MTHttpWorker.h"
#import "MTTransportScheme.h"
#import "MTTcpTransport.h"
#import "MTHttpTransport.h"
#import <netinet/in.h>
#import <arpa/inet.h>
typedef struct {
uint8_t nonce[16];
} MTPayloadData;
@implementation MTDiscoverConnectionSignals
+ (NSData *)payloadData:(MTPayloadData *)outPayloadData;
{
uint8_t reqPqBytes[] = {
0, 0, 0, 0, 0, 0, 0, 0, // zero * 8
0, 0, 0, 0, 0, 0, 0, 0, // message id
20, 0, 0, 0, // message length
0x78, 0x97, 0x46, 0x60, // req_pq
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 // nonce
};
MTPayloadData payloadData;
arc4random_buf(&payloadData.nonce, 16);
if (outPayloadData)
*outPayloadData = payloadData;
arc4random_buf(reqPqBytes + 8, 8);
memcpy(reqPqBytes + 8 + 8 + 4 + 4, payloadData.nonce, 16);
return [[NSData alloc] initWithBytes:reqPqBytes length:sizeof(reqPqBytes)];
}
+ (bool)isResponseValid:(NSData *)data payloadData:(MTPayloadData)payloadData
{
if (data.length == 84)
{
uint8_t zero[] = { 0, 0, 0, 0, 0, 0, 0, 0 };
uint8_t length[] = { 0x40, 0, 0, 0 };
uint8_t resPq[] = { 0x63, 0x24, 0x16, 0x05 };
if (memcmp((uint8_t * const)data.bytes, zero, 8) == 0 && memcmp(((uint8_t * const)data.bytes) + 16, length, 4) == 0 && memcmp(((uint8_t * const)data.bytes) + 20, resPq, 4) == 0 && memcmp(((uint8_t * const)data.bytes) + 24, payloadData.nonce, 16) == 0)
{
return true;
}
}
return false;
}
+ (bool)isIpv6:(NSString *)ip
{
const char *utf8 = [ip UTF8String];
int success;
struct in6_addr dst6;
success = inet_pton(AF_INET6, utf8, &dst6);
return success == 1;
}
+ (SSignal *)tcpConnectionWithAddress:(MTDatacenterAddress *)address;
{
return [[SSignal alloc] initWithGenerator:^id<SDisposable>(SSubscriber *subscriber)
{
MTPayloadData payloadData;
NSData *data = [self payloadData:&payloadData];
MTTcpConnection *connection = [[MTTcpConnection alloc] initWithAddress:address interface:nil];
__weak MTTcpConnection *weakConnection = connection;
connection.connectionOpened = ^
{
__strong MTTcpConnection *strongConnection = weakConnection;
if (strongConnection != nil)
[strongConnection sendDatas:@[data] completion:nil requestQuickAck:false expectDataInResponse:true];
};
connection.connectionReceivedData = ^(NSData *data)
{
if ([self isResponseValid:data payloadData:payloadData])
[subscriber putCompletion];
else
[subscriber putError:nil];
};
connection.connectionClosed = ^
{
[subscriber putError:nil];
};
MTLog(@"trying tcp://%@:%d", address.ip, (int)address.port);
[connection start];
return [[SBlockDisposable alloc] initWithBlock:^
{
[connection stop];
}];
}];
}
+ (SSignal *)httpConnectionWithAddress:(MTDatacenterAddress *)address
{
return [[SSignal alloc] initWithGenerator:^id<SDisposable>(SSubscriber *subscriber)
{
MTPayloadData payloadData;
NSData *data = [self payloadData:&payloadData];
MTHttpWorkerBlockDelegate *delegate = [[MTHttpWorkerBlockDelegate alloc] init];
delegate.completedWithData = ^(NSData *data)
{
if ([self isResponseValid:data payloadData:payloadData])
[subscriber putCompletion];
else
[subscriber putError:nil];
};
delegate.failed = ^
{
[subscriber putError:nil];
};
MTLog(@"trying http://%@:%d", address.ip, (int)address.port);
MTHttpWorker *httpWorker = [[MTHttpWorker alloc] initWithDelegate:delegate address:address payloadData:data performsLongPolling:false];
return [[SBlockDisposable alloc] initWithBlock:^
{
[delegate description]; // keep reference
[httpWorker stop];
}];
}];
}
+ (SSignal *)discoverSchemeWithContext:(MTContext *)context addressList:(NSArray *)addressList preferMedia:(bool)preferMedia
{
NSMutableArray *bestAddressList = [[NSMutableArray alloc] init];
NSMutableArray *remainingAddressList = [[NSMutableArray alloc] init];
for (MTDatacenterAddress *address in addressList)
{
if (preferMedia == address.preferForMedia)
[bestAddressList addObject:address];
else
[remainingAddressList addObject:address];
}
NSMutableArray *bestTcp4Signals = [[NSMutableArray alloc] init];
NSMutableArray *bestTcp6Signals = [[NSMutableArray alloc] init];
NSMutableArray *bestHttpSignals = [[NSMutableArray alloc] init];
for (MTDatacenterAddress *address in bestAddressList)
{
MTTransportScheme *tcpTransportScheme = [[MTTransportScheme alloc] initWithTransportClass:[MTTcpTransport class] address:address];
MTTransportScheme *httpTransportScheme = [[MTTransportScheme alloc] initWithTransportClass:[MTHttpTransport class] address:address];
if ([self isIpv6:address.ip])
{
SSignal *signal = [[[[self tcpConnectionWithAddress:address] then:[SSignal single:tcpTransportScheme]] timeout:5.0 onQueue:[SQueue concurrentDefaultQueue] orSignal:[SSignal fail:nil]] catch:^SSignal *(__unused id error)
{
return [SSignal complete];
}];
[bestTcp6Signals addObject:signal];
}
else
{
SSignal *signal = [[[[self tcpConnectionWithAddress:address] then:[SSignal single:tcpTransportScheme]] timeout:5.0 onQueue:[SQueue concurrentDefaultQueue] orSignal:[SSignal fail:nil]] catch:^SSignal *(__unused id error)
{
return [SSignal complete];
}];
[bestTcp4Signals addObject:signal];
}
SSignal *signal = [[[[self httpConnectionWithAddress:address] then:[SSignal single:httpTransportScheme]] timeout:5.0 onQueue:[SQueue concurrentDefaultQueue] orSignal:[SSignal fail:nil]] catch:^SSignal *(__unused id error)
{
return [SSignal complete];
}];
[bestHttpSignals addObject:signal];
}
SSignal *repeatDelaySignal = [[SSignal complete] delay:1.0 onQueue:[SQueue concurrentDefaultQueue]];
SSignal *optimalDelaySignal = [[SSignal complete] delay:30.0 onQueue:[SQueue concurrentDefaultQueue]];
SSignal *firstTcp4Match = [[[[SSignal mergeSignals:bestTcp4Signals] then:repeatDelaySignal] restart] take:1];
SSignal *firstTcp6Match = [[[[SSignal mergeSignals:bestTcp6Signals] then:repeatDelaySignal] restart] take:1];
SSignal *firstHttpMatch = [[[[SSignal mergeSignals:bestHttpSignals] then:repeatDelaySignal] restart] take:1];
SSignal *optimalTcp4Match = [[[[SSignal mergeSignals:bestTcp4Signals] then:optimalDelaySignal] restart] take:1];
SSignal *optimalTcp6Match = [[[[SSignal mergeSignals:bestTcp6Signals] then:optimalDelaySignal] restart] take:1];
SSignal *anySignal = [[SSignal mergeSignals:@[firstTcp4Match, firstTcp6Match, firstHttpMatch]] take:1];
SSignal *optimalSignal = [[SSignal mergeSignals:@[optimalTcp4Match, optimalTcp6Match]] take:1];
SSignal *signal = [anySignal mapToSignal:^SSignal *(MTTransportScheme *scheme)
{
if (![scheme isOptimal])
return [[SSignal single:scheme] then:optimalSignal];
else
return [SSignal single:scheme];
}];
return signal;
}
@end

View File

@ -13,7 +13,7 @@
@property (nonatomic) int32_t apiId;
@property (nonatomic, strong, readonly) NSString *deviceModel;
@property (nonatomic, strong, readonly) NSString *systemVersion;
@property (nonatomic, strong, readonly) NSString *appVersion;
@property (nonatomic, strong) NSString *appVersion;
@property (nonatomic, strong, readonly) NSString *langCode;
@property (nonatomic, strong) NSNumber *layer;

View File

@ -30,6 +30,8 @@
#import <libkern/OSAtomic.h>
#import "MTDiscoverConnectionSignals.h"
@implementation MTContextBlockChangeListener
- (void)contextIsPasswordRequiredUpdated:(MTContext *)context datacenterId:(NSInteger)datacenterId
@ -68,6 +70,8 @@
volatile OSSpinLock _passwordEntryRequiredLock;
NSMutableDictionary *_passwordRequiredByDatacenterId;
NSMutableDictionary *_transportSchemeDisposableByDatacenterId;
}
@end
@ -602,15 +606,7 @@
if (result != nil && ![result isOptimal])
{
MTDiscoverTransportSchemeAction *action = _discoverDatacenterTransportSchemeActions[@(datacenterId)];
if (action == nil)
{
action = [[MTDiscoverTransportSchemeAction alloc] initWithContext:self datacenterId:datacenterId];
action.delegate = self;
_discoverDatacenterTransportSchemeActions[@(datacenterId)] = action;
}
[action discoverMoreOptimalSchemeThan:result];
[self transportSchemeForDatacenterWithIdRequired:datacenterId moreOptimalThan:result beginWithHttp:false];
}
} synchronous:true];
@ -672,10 +668,47 @@
}
- (void)transportSchemeForDatacenterWithIdRequired:(NSInteger)datacenterId
{
[self transportSchemeForDatacenterWithIdRequired:datacenterId moreOptimalThan:nil beginWithHttp:false];
}
- (void)transportSchemeForDatacenterWithIdRequired:(NSInteger)datacenterId moreOptimalThan:(MTTransportScheme *)suboptimalScheme beginWithHttp:(bool)beginWithHttp
{
[[MTContext contextQueue] dispatchOnQueue:^
{
MTDiscoverTransportSchemeAction *action = _discoverDatacenterTransportSchemeActions[@(datacenterId)];
if (_transportSchemeDisposableByDatacenterId == nil)
_transportSchemeDisposableByDatacenterId = [[NSMutableDictionary alloc] init];
id<SDisposable> disposable = _transportSchemeDisposableByDatacenterId[@(datacenterId)];
if (disposable == nil)
{
__weak MTContext *weakSelf = self;
MTDatacenterAddressSet *addressSet = [self addressSetForDatacenterWithId:datacenterId];
_transportSchemeDisposableByDatacenterId[@(datacenterId)] = [[[MTDiscoverConnectionSignals discoverSchemeWithContext:self addressList:addressSet.addressList preferMedia:false] onDispose:^
{
__strong MTContext *strongSelf = weakSelf;
if (strongSelf != nil)
{
[[MTContext contextQueue] dispatchOnQueue:^
{
[strongSelf->_transportSchemeDisposableByDatacenterId removeObjectForKey:@(datacenterId)];
}];
}
}] startWithNext:^(id next)
{
MTLog(@"scheme: %@", next);
__strong MTContext *strongSelf = weakSelf;
if (strongSelf != nil)
[strongSelf updateTransportSchemeForDatacenterWithId:datacenterId transportScheme:next];
} error:^(id error)
{
} completed:^
{
}];
}
/*MTDiscoverTransportSchemeAction *action = _discoverDatacenterTransportSchemeActions[@(datacenterId)];
if (action == nil)
{
action = [[MTDiscoverTransportSchemeAction alloc] initWithContext:self datacenterId:datacenterId];
@ -683,7 +716,15 @@
_discoverDatacenterTransportSchemeActions[@(datacenterId)] = action;
}
[action discoverScheme];
if (suboptimalScheme)
{
if (beginWithHttp)
[action invalidateScheme:suboptimalScheme beginWithHttp:true];
else
[action discoverMoreOptimalSchemeThan:suboptimalScheme];
}
else
[action discoverScheme];*/
}];
}
@ -694,15 +735,7 @@
[[MTContext contextQueue] dispatchOnQueue:^
{
MTDiscoverTransportSchemeAction *action = _discoverDatacenterTransportSchemeActions[@(datacenterId)];
if (action == nil)
{
action = [[MTDiscoverTransportSchemeAction alloc] initWithContext:self datacenterId:datacenterId];
action.delegate = self;
_discoverDatacenterTransportSchemeActions[@(datacenterId)] = action;
}
[action invalidateScheme:transportScheme beginWithHttp:isProbablyHttp];
[self transportSchemeForDatacenterWithIdRequired:datacenterId moreOptimalThan:transportScheme beginWithHttp:isProbablyHttp];
}];
}
@ -713,6 +746,15 @@
MTDiscoverTransportSchemeAction *action = _discoverDatacenterTransportSchemeActions[@(datacenterId)];
if (action != nil)
[action validateScheme:transportScheme];
if ([transportScheme isOptimal])
{
if (_transportSchemeDisposableByDatacenterId == nil)
_transportSchemeDisposableByDatacenterId = [[NSMutableDictionary alloc] init];
id<SDisposable> disposable = _transportSchemeDisposableByDatacenterId[@(datacenterId)];
[disposable dispose];
[_transportSchemeDisposableByDatacenterId removeObjectForKey:@(datacenterId)];
}
}];
}

View File

@ -13,8 +13,9 @@
@property (nonatomic, strong, readonly) NSString *host;
@property (nonatomic, strong, readonly) NSString *ip;
@property (nonatomic, readonly) uint16_t port;
@property (nonatomic, readonly) bool preferForMedia;
- (instancetype)initWithIp:(NSString *)ip port:(uint16_t)port;
- (instancetype)initWithIp:(NSString *)ip port:(uint16_t)port preferForMedia:(bool)preferForMedia;
- (BOOL)isEqualToAddress:(MTDatacenterAddress *)other;

View File

@ -10,13 +10,14 @@
@implementation MTDatacenterAddress
- (instancetype)initWithIp:(NSString *)ip port:(uint16_t)port
- (instancetype)initWithIp:(NSString *)ip port:(uint16_t)port preferForMedia:(bool)preferForMedia
{
self = [super init];
if (self != nil)
{
_ip = ip;
_port = port;
_preferForMedia = preferForMedia;
}
return self;
}
@ -29,6 +30,7 @@
_ip = [aDecoder decodeObjectForKey:@"ip"];
_host = [aDecoder decodeObjectForKey:@"host"];
_port = (uint16_t)[aDecoder decodeIntForKey:@"port"];
_preferForMedia = [aDecoder decodeBoolForKey:@"preferForMedia"];
}
return self;
}
@ -38,6 +40,7 @@
[aCoder encodeObject:_ip forKey:@"ip"];
[aCoder encodeObject:_host forKey:@"host"];
[aCoder encodeInt:_port forKey:@"port"];
[aCoder encodeBool:_preferForMedia forKey:@"preferForMedia"];
}
- (BOOL)isEqual:(id)object
@ -59,12 +62,15 @@
if (_port != other.port)
return false;
if (_preferForMedia != other.preferForMedia)
return false;
return true;
}
- (NSString *)description
{
return [[NSString alloc] initWithFormat:@"%@:%d", _ip == nil ? _host : _ip, (int)_port];
return [[NSString alloc] initWithFormat:@"%@:%d (media: %@)", _ip == nil ? _host : _ip, (int)_port, _preferForMedia ? @"yes" : @"no"];
}
@end

View File

@ -115,34 +115,6 @@ typedef enum {
}];
}
- (NSArray *)interfaceList
{
NSMutableArray *list = [[NSMutableArray alloc] init];
struct ifaddrs *addrs = NULL;
const struct ifaddrs *cursor = NULL;
bool success = getifaddrs(&addrs) == 0;
if (success)
{
cursor = addrs;
while (cursor != NULL)
{
if (cursor->ifa_addr->sa_family == AF_INET && (cursor->ifa_flags & IFF_LOOPBACK) == 0)
{
NSString *name = [NSString stringWithUTF8String:cursor->ifa_name];
if (name != nil)
[list addObject:name];
}
cursor = cursor->ifa_next;
}
freeifaddrs(addrs);
}
return list;
}
- (void)networkAvailabilityChanged:(MTNetworkAvailability *)networkAvailability networkIsAvailable:(bool)networkIsAvailable
{
[[MTDiscoverTransportSchemeAction discoverTransportSchemeQueue] dispatchOnQueue:^
@ -356,7 +328,7 @@ typedef enum {
NSMutableArray *httpAddresses = [[NSMutableArray alloc] init];
for (MTDatacenterAddress *address in [(MTContext *)_context addressSetForDatacenterWithId:_datacenterId].addressList)
{
MTDatacenterAddress *actualAddress = [[MTDatacenterAddress alloc] initWithIp:address.ip port:80];
MTDatacenterAddress *actualAddress = [[MTDatacenterAddress alloc] initWithIp:address.ip port:80 preferForMedia:false];
if (![httpAddresses containsObject:actualAddress])
{
[httpAddresses addObject:httpAddresses];

View File

@ -70,11 +70,6 @@ static inline uint32_t rotl32 ( uint32_t x, int8_t r )
return (x << r) | (x >> (32 - r));
}
static inline uint64_t rotl64 ( uint64_t x, int8_t r )
{
return (x << r) | (x >> (64 - r));
}
#define ROTL32(x,y) rotl32(x,y)
#define ROTL64(x,y) rotl64(x,y)

View File

@ -21,6 +21,14 @@
@end
@interface MTHttpWorkerBlockDelegate : NSObject <MTHttpWorkerDelegate>
@property (nonatomic, copy) void (^completedWithData)(NSData *);
@property (nonatomic, copy) void (^connected)();
@property (nonatomic, copy) void (^failed)();
@end
@interface MTHttpWorker : AFHTTPClient
@property (nonatomic, strong, readonly) id internalId;

View File

@ -17,6 +17,28 @@
MTInternalIdClass(MTHttpWorker)
@implementation MTHttpWorkerBlockDelegate
- (void)httpWorker:(MTHttpWorker *)__unused httpWorker completedWithData:(NSData *)data
{
if (_completedWithData)
_completedWithData(data);
}
- (void)httpWorkerConnected:(MTHttpWorker *)__unused httpWorker
{
if (_connected)
_connected();
}
- (void)httpWorkerFailed:(MTHttpWorker *)__unused httpWorker
{
if (_failed)
_failed();
}
@end
@interface MTHttpWorker ()
{
MTTimer *_timeoutTimer;

View File

@ -21,8 +21,8 @@
- (double)readDouble:(bool *)failed __attribute__((nonnull(1)));
- (NSData *)readData:(int)length;
- (NSData *)readData:(int)length failed:(bool *)failed __attribute__((nonnull(2)));
- (NSMutableData *)readMutableData:(int)length;
- (NSMutableData *)readMutableData:(int)length failed:(bool *)failed __attribute__((nonnull(2)));
- (NSMutableData *)readMutableData:(NSUInteger)length;
- (NSMutableData *)readMutableData:(NSUInteger)length failed:(bool *)failed __attribute__((nonnull(2)));
- (NSString *)readString;
- (NSString *)readString:(bool *)failed __attribute__((nonnull(1)));
- (NSData *)readBytes;

View File

@ -203,7 +203,7 @@ static inline int roundUpInput(int numToRound, int multiple)
return data;
}
- (NSMutableData *)readMutableData:(int)length
- (NSMutableData *)readMutableData:(NSUInteger)length
{
uint8_t *bytes = (uint8_t *)malloc(length);
NSInteger readLen = [_wrappedInputStream read:bytes maxLength:length];
@ -215,7 +215,7 @@ static inline int roundUpInput(int numToRound, int multiple)
return data;
}
- (NSMutableData *)readMutableData:(int)length failed:(bool *)failed
- (NSMutableData *)readMutableData:(NSUInteger)length failed:(bool *)failed
{
uint8_t *bytes = (uint8_t *)malloc(length);
NSInteger readLen = [_wrappedInputStream read:bytes maxLength:length];

View File

@ -37,6 +37,11 @@ static inline int roundUp(int numToRound, int multiple)
return self;
}
- (NSOutputStream *)wrappedOutputStream
{
return _wrappedOutputStream;
}
- (void)dealloc
{
[_wrappedOutputStream close];

View File

@ -34,6 +34,7 @@
@property (nonatomic) bool shouldStayConnected;
@property (nonatomic) bool useUnauthorizedMode;
@property (nonatomic) bool preferMediaAddresses;
@property (nonatomic) id requiredAuthToken;
@property (nonatomic) NSInteger authTokenMasterDatacenterId;

View File

@ -1953,7 +1953,10 @@ static const NSUInteger MTMaxUnacknowledgedMessageCount = 64;
shouldRequest = true;
if (shouldRequest)
{
[self requestMessageWithId:detailedInfoMessage.responseMessageId];
MTLog(@"[MTProto#%p will request message %" PRId64 "", self, detailedInfoMessage.responseMessageId);
}
else
{
[_sessionInfo scheduleMessageConfirmation:detailedInfoMessage.responseMessageId size:(NSInteger)detailedInfoMessage.responseLength];

View File

@ -33,6 +33,11 @@
@interface MTTcpConnection : NSObject
@property (nonatomic, weak) id<MTTcpConnectionDelegate> delegate;
@property (nonatomic, copy) void (^connectionOpened)();
@property (nonatomic, copy) void (^connectionClosed)();
@property (nonatomic, copy) void (^connectionReceivedData)(NSData *);
@property (nonatomic, strong, readonly) id internalId;
@property (nonatomic, strong, readonly) MTDatacenterAddress *address;
@property (nonatomic, strong, readonly) NSString *interface;

View File

@ -115,8 +115,10 @@ static const NSUInteger MTTcpProgressCalculationThreshold = 4096;
MTLog(@"[MTTcpConnection#%x connecting to %@:%d]", (int)self, _address.ip, (int)_address.port);
NSString *ip = _address.ip;
__autoreleasing NSError *error = nil;
if (![_socket connectToHost:_address.ip onPort:_address.port viaInterface:_interface withTimeout:12 error:&error] || error != nil)
if (![_socket connectToHost:ip onPort:_address.port viaInterface:_interface withTimeout:12 error:&error] || error != nil)
[self closeAndNotify];
else
[_socket readDataToLength:1 withTimeout:-1 tag:MTTcpReadTagPacketShortLength];
@ -145,6 +147,8 @@ static const NSUInteger MTTcpProgressCalculationThreshold = 4096;
_socket.delegate = nil;
_socket = nil;
if (_connectionClosed)
_connectionClosed();
id<MTTcpConnectionDelegate> delegate = _delegate;
if ([delegate respondsToSelector:@selector(tcpConnectionClosed:)])
[delegate tcpConnectionClosed:self];
@ -374,6 +378,8 @@ static const NSUInteger MTTcpProgressCalculationThreshold = 4096;
_packetHead = nil;
}
if (_connectionReceivedData)
_connectionReceivedData(packetData);
id<MTTcpConnectionDelegate> delegate = _delegate;
if ([delegate respondsToSelector:@selector(tcpConnectionReceivedData:data:)])
[delegate tcpConnectionReceivedData:self data:packetData];
@ -402,6 +408,8 @@ static const NSUInteger MTTcpProgressCalculationThreshold = 4096;
- (void)socket:(GCDAsyncSocket *)__unused socket didConnectToHost:(NSString *)__unused host port:(uint16_t)__unused port
{
if (_connectionOpened)
_connectionOpened();
id<MTTcpConnectionDelegate> delegate = _delegate;
if ([delegate respondsToSelector:@selector(tcpConnectionOpened:)])
[delegate tcpConnectionOpened:self];

View File

@ -7,6 +7,9 @@
objects = {
/* Begin PBXBuildFile section */
D0580ABF1B0F3E7100E8235B /* SSignalKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D0580ABE1B0F3E7100E8235B /* SSignalKit.framework */; };
D0580AC21B0F3E9C00E8235B /* MTDiscoverConnectionSignals.h in Headers */ = {isa = PBXBuildFile; fileRef = D0580AC01B0F3E9C00E8235B /* MTDiscoverConnectionSignals.h */; };
D0580AC31B0F3E9C00E8235B /* MTDiscoverConnectionSignals.m in Sources */ = {isa = PBXBuildFile; fileRef = D0580AC11B0F3E9C00E8235B /* MTDiscoverConnectionSignals.m */; };
D079AB9C1AF39B8000076F59 /* MtProtoKitMac.h in Headers */ = {isa = PBXBuildFile; fileRef = D079AB9B1AF39B8000076F59 /* MtProtoKitMac.h */; settings = {ATTRIBUTES = (Public, ); }; };
D079ABB01AF39BA400076F59 /* MTProtoKit.h in Headers */ = {isa = PBXBuildFile; fileRef = D063A31D18B158AE00C65116 /* MTProtoKit.h */; settings = {ATTRIBUTES = (Public, ); }; };
D0CB05FC1ADC4483005E298F /* MtProtoKit.h in Headers */ = {isa = PBXBuildFile; fileRef = D0CB05FB1ADC4483005E298F /* MtProtoKit.h */; settings = {ATTRIBUTES = (Public, ); }; };
@ -250,6 +253,9 @@
D0503AD918B027F80074C3FE /* MTOutputStream.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = MTOutputStream.m; path = MTProtoKit/MTOutputStream.m; sourceTree = "<group>"; };
D0503ADC18B029480074C3FE /* MTInputStream.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = MTInputStream.h; path = MTProtoKit/MTInputStream.h; sourceTree = "<group>"; };
D0503ADD18B029480074C3FE /* MTInputStream.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = MTInputStream.m; path = MTProtoKit/MTInputStream.m; sourceTree = "<group>"; };
D0580ABE1B0F3E7100E8235B /* SSignalKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = SSignalKit.framework; path = "../../../../Library/Developer/Xcode/DerivedData/Telegraph-dzhgyeoibunjpxfckifwvbawfdmi/Build/Products/Debug-iphoneos/SSignalKit.framework"; sourceTree = "<group>"; };
D0580AC01B0F3E9C00E8235B /* MTDiscoverConnectionSignals.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MTDiscoverConnectionSignals.h; sourceTree = "<group>"; };
D0580AC11B0F3E9C00E8235B /* MTDiscoverConnectionSignals.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MTDiscoverConnectionSignals.m; sourceTree = "<group>"; };
D05A831718AFB3F9007F1076 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; };
D05A832818AFB3F9007F1076 /* XCTest.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = XCTest.framework; path = Library/Frameworks/XCTest.framework; sourceTree = DEVELOPER_DIR; };
D05A832B18AFB3F9007F1076 /* UIKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UIKit.framework; path = Library/Frameworks/UIKit.framework; sourceTree = DEVELOPER_DIR; };
@ -438,6 +444,7 @@
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
D0580ABF1B0F3E7100E8235B /* SSignalKit.framework in Frameworks */,
D0D1A0721ADDE2FC007D9ED6 /* libz.dylib in Frameworks */,
D0CB066B1ADC48C4005E298F /* libcrypto.a in Frameworks */,
);
@ -453,6 +460,8 @@
D063A33518B161B600C65116 /* MTTransportScheme.m */,
9389BC5918DA2BD300F9C1A6 /* MTDiscoverTransportSchemeAction.h */,
9389BC5A18DA2BD300F9C1A6 /* MTDiscoverTransportSchemeAction.m */,
D0580AC01B0F3E9C00E8235B /* MTDiscoverConnectionSignals.h */,
D0580AC11B0F3E9C00E8235B /* MTDiscoverConnectionSignals.m */,
);
name = "Transport Scheme";
sourceTree = "<group>";
@ -578,6 +587,7 @@
D05A831618AFB3F9007F1076 /* Frameworks */ = {
isa = PBXGroup;
children = (
D0580ABE1B0F3E7100E8235B /* SSignalKit.framework */,
D0D1A0711ADDE2FC007D9ED6 /* libz.dylib */,
D063A2F918B14AB500C65116 /* libcrypto.dylib */,
D05A831718AFB3F9007F1076 /* Foundation.framework */,
@ -1105,6 +1115,7 @@
D0CB06581ADC45CE005E298F /* MTNetworkAvailability.h in Headers */,
D0CB06601ADC45CE005E298F /* MTHttpWorkerBehaviour.h in Headers */,
D0CB06211ADC454C005E298F /* MTKeychain.h in Headers */,
D0580AC21B0F3E9C00E8235B /* MTDiscoverConnectionSignals.h in Headers */,
D0CB065F1ADC45CE005E298F /* MTHttpWorker.h in Headers */,
D0CB063B1ADC4591005E298F /* MTPreparedMessage.h in Headers */,
D0CB065E1ADC45CE005E298F /* MTHttpTransport.h in Headers */,
@ -1271,6 +1282,7 @@
D0CB06141ADC44B7005E298F /* MTQueue.m in Sources */,
D0CB06711ADC4A50005E298F /* MTTransportScheme.m in Sources */,
D0D1A04B1ADD983C007D9ED6 /* MTMsgContainerMessage.m in Sources */,
D0580AC31B0F3E9C00E8235B /* MTDiscoverConnectionSignals.m in Sources */,
D0CB06341ADC4588005E298F /* MTDatacenterAddress.m in Sources */,
D0CB06111ADC44B7005E298F /* MTTimer.m in Sources */,
D0CB062E1ADC457B005E298F /* MTDatacenterAuthAction.m in Sources */,
@ -1509,6 +1521,10 @@
DYLIB_CURRENT_VERSION = 1;
DYLIB_INSTALL_NAME_BASE = "@rpath";
ENABLE_STRICT_OBJC_MSGSEND = YES;
FRAMEWORK_SEARCH_PATHS = (
"$(inherited)",
"$(USER_LIBRARY_DIR)/Developer/Xcode/DerivedData/Telegraph-dzhgyeoibunjpxfckifwvbawfdmi/Build/Products/Debug-iphoneos",
);
GCC_NO_COMMON_BLOCKS = YES;
GCC_PRECOMPILE_PREFIX_HEADER = YES;
GCC_PREFIX_HEADER = "MtProtoKitiOS/MtProtoKit-Prefix.pch";
@ -1553,6 +1569,10 @@
DYLIB_CURRENT_VERSION = 1;
DYLIB_INSTALL_NAME_BASE = "@rpath";
ENABLE_STRICT_OBJC_MSGSEND = YES;
FRAMEWORK_SEARCH_PATHS = (
"$(inherited)",
"$(USER_LIBRARY_DIR)/Developer/Xcode/DerivedData/Telegraph-dzhgyeoibunjpxfckifwvbawfdmi/Build/Products/Debug-iphoneos",
);
GCC_NO_COMMON_BLOCKS = YES;
GCC_PRECOMPILE_PREFIX_HEADER = YES;
GCC_PREFIX_HEADER = "MtProtoKitiOS/MtProtoKit-Prefix.pch";
@ -1598,6 +1618,7 @@
D079ABAB1AF39B8000076F59 /* Release */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
D0CB060E1ADC4483005E298F /* Build configuration list for PBXNativeTarget "MtProtoKit" */ = {
isa = XCConfigurationList;

View File

@ -77,17 +77,17 @@
/**
The callback dispatch queue on success. If `NULL` (default), the main queue is used.
*/
@property (nonatomic) dispatch_queue_t successCallbackQueue;
@property (nonatomic, strong) dispatch_queue_t successCallbackQueue;
/**
The callback dispatch queue on failure. If `NULL` (default), the main queue is used.
*/
@property (nonatomic) dispatch_queue_t failureCallbackQueue;
@property (nonatomic, strong) dispatch_queue_t failureCallbackQueue;
/**
The dispatch group on which to call the completion/failure block
*/
@property (nonatomic) dispatch_group_t dispatchGroup;
@property (nonatomic, strong) dispatch_group_t dispatchGroup;
/**
A Boolean value determining whether or not the class can process the specified request. For example, `AFJSONRequestOperation` may check to make sure the content type was `application/json` or the URL path extension was `.json`.

View File

@ -38,11 +38,11 @@ static NSString * AFStringFromIndexSet(NSIndexSet *indexSet) {
}
if (range.length == 1) {
[string appendFormat:@"%u", range.location];
[string appendFormat:@"%lu", (unsigned long)range.location];
} else {
NSUInteger firstIndex = range.location;
NSUInteger lastIndex = firstIndex + range.length - 1;
[string appendFormat:@"%u-%u", firstIndex, lastIndex];
[string appendFormat:@"%lu-%lu", (unsigned long)firstIndex, (unsigned long)lastIndex];
}
range.location = nextIndex;