class
MTApiEnvironment
@property (nonatomic) int32_t apiId;
@property (nonatomic, strong, readonly) NSString *deviceModel;
@property (nonatomic, strong, readonly) NSString *systemVersion;
@property (nonatomic, strong) NSString *appVersion;
@property (nonatomic, strong, readonly) NSString *systemLangCode;
@property (nonatomic, strong) NSNumber *layer;
@property (nonatomic, strong, readonly) NSData *systemCode;
@property (nonatomic, strong) NSString *langPack;
@property (nonatomic, strong, readonly) NSString *langPackCode;
@property (nonatomic, strong, readonly) NSString *apiInitializationHash;
@property (nonatomic) bool disableUpdates;
@property (nonatomic) NSData *tcpPayloadPrefix;
@property (nonatomic) NSDictionary *datacenterAddressOverrides;
@property (nonatomic, strong, readonly) MTSocksProxySettings *socksProxySettings;
@property (nonatomic, strong, readonly) MTNetworkSettings *networkSettings;
@property (nonatomic, copy) void (^passwordInputHandler)(void);
- (MTApiEnvironment *)withUpdatedLangPackCode:(NSString *)langPackCode;
- (MTApiEnvironment *)withUpdatedSocksProxySettings:(MTSocksProxySettings *)socksProxySettings;
- (MTApiEnvironment *)withUpdatedNetworkSettings:(MTNetworkSettings *)networkSettings;
- (MTApiEnvironment *)withUpdatedSystemCode:(NSData *)systemCode;
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
// init
- (instancetype)init
{
self = [super init];
if (self != nil)
{
_deviceModel = [self platformString];
#if TARGET_OS_IPHONE
_systemVersion = [[UIDevice currentDevice] systemVersion];
#else
NSProcessInfo *pInfo = [NSProcessInfo processInfo];
_systemVersion = [[[pInfo operatingSystemVersionString] componentsSeparatedByString:@" "] objectAtIndex:1];
#endif
NSString *suffix = @"";
#if TARGET_OS_OSX
#ifdef BETA
suffix = @" BETA";
#endif
#ifdef APPSTORE
suffix = @" APPSTORE";
#endif
#ifdef STABLE
suffix = @" STABLE";
#endif
#endif
NSString *versionString = [[NSString alloc] initWithFormat:@"%@ (%@)%@", [[[NSBundle mainBundle] infoDictionary] objectForKey:@"CFBundleShortVersionString"], [[[NSBundle mainBundle] infoDictionary] objectForKey:@"CFBundleVersion"], suffix];
_appVersion = versionString;
_systemLangCode = [[NSLocale preferredLanguages] objectAtIndex:0];
#if TARGET_OS_OSX
_langPack = @"macos";
#else
_langPack = @"ios";
#endif
_langPackCode = @"";
[self _updateApiInitializationHash];
}
return self;
}
// update api initialization hash
- (void)_updateApiInitializationHash {
_apiInitializationHash = [[NSString alloc] initWithFormat:@"apiId=%" PRId32 "&deviceModel=%@&systemVersion=%@&appVersion=%@&langCode=%@&layer=%@&langPack=%@&langPackCode=%@&proxy=%@&systemCode=%@", _apiId, _deviceModel, _systemVersion, _appVersion, _systemLangCode, _layer, _langPack, _langPackCode, _socksProxySettings, _systemCode];
}
// set layer
- (void)setLayer:(NSNumber *)layer {
_layer = layer;
[self _updateApiInitializationHash];
}
// set app version
- (void)setAppVersion:(NSString *)appVersion {
_appVersion = appVersion;
[self _updateApiInitializationHash];
}
// set language pack
- (void)setLangPack:(NSString *)langPack {
_langPack = langPack;
[self _updateApiInitializationHash];
}
// set language pack code
- (void)setLangPackCode:(NSString *)langPackCode {
_langPackCode = langPackCode;
[self _updateApiInitializationHash];
}
// platformString
- (NSString *)platformString
{
switch ([self platformType])
{
case UIDevice1GiPhone: return IPHONE_1G_NAMESTRING;
case UIDevice3GiPhone: return IPHONE_3G_NAMESTRING;
case UIDevice3GSiPhone: return IPHONE_3GS_NAMESTRING;
case UIDevice4iPhone: return IPHONE_4_NAMESTRING;
case UIDevice4SiPhone: return IPHONE_4S_NAMESTRING;
case UIDevice5iPhone: return IPHONE_5_NAMESTRING;
case UIDevice5SiPhone: return IPHONE_5S_NAMESTRING;
case UIDevice6iPhone: return IPHONE_6_NAMESTRING;
case UIDevice6PlusiPhone: return IPHONE_6Plus_NAMESTRING;
case UIDevice6siPhone: return IPHONE_6S_NAMESTRING;
case UIDevice6SPlusiPhone: return IPHONE_6SPlus_NAMESTRING;
case UIDevice7iPhone: return IPHONE_7_NAMESTRING;
case UIDevice7PlusiPhone: return IPHONE_7Plus_NAMESTRING;
case UIDevice8iPhone: return IPHONE_8_NAMESTRING;
case UIDevice8PlusiPhone: return IPHONE_8Plus_NAMESTRING;
case UIDeviceXiPhone: return IPHONE_X_NAMESTRING;
case UIDeviceSEPhone: return IPHONE_SE_NAMESTRING;
case UIDeviceXSiPhone: return IPHONE_XS_NAMESTRING;
case UIDeviceXSMaxiPhone: return IPHONE_XSMAX_NAMESTRING;
case UIDeviceXRiPhone: return IPHONE_XR_NAMESTRING;
case UIDeviceUnknowniPhone: return IPHONE_UNKNOWN_NAMESTRING;
case UIDevice1GiPod: return IPOD_1G_NAMESTRING;
case UIDevice2GiPod: return IPOD_2G_NAMESTRING;
case UIDevice3GiPod: return IPOD_3G_NAMESTRING;
case UIDevice4GiPod: return IPOD_4G_NAMESTRING;
case UIDevice5GiPod: return IPOD_5G_NAMESTRING;
case UIDevice6GiPod: return IPOD_6G_NAMESTRING;
case UIDeviceUnknowniPod: return IPOD_UNKNOWN_NAMESTRING;
case UIDevice1GiPad : return IPAD_1G_NAMESTRING;
case UIDevice2GiPad : return IPAD_2G_NAMESTRING;
case UIDevice3GiPad : return IPAD_3G_NAMESTRING;
case UIDevice4GiPad : return IPAD_4G_NAMESTRING;
case UIDevice5GiPad : return IPAD_5G_NAMESTRING;
case UIDevice6GiPad : return IPAD_6G_NAMESTRING;
case UIDeviceiPadPro12_93g : return IPAD_PRO_12_9_NAMESTRING;
case UIDeviceiPadPro11 : return IPAD_PRO_11_NAMESTRING;
case UIDeviceiPadPro6g : return IPAD_PRO_6G_NAMESTRING;
case UIDeviceiPadPro10_5 : return IPAD_PRO_10_5_NAMESTRING;
case UIDeviceiPadPro12_9 : return IPAD_PRO_12_9_NAMESTRING;
case UIDeviceUnknowniPad : return IPAD_UNKNOWN_NAMESTRING;
case UIDeviceAppleTV2 : return APPLETV_2G_NAMESTRING;
case UIDeviceAppleTV3 : return APPLETV_3G_NAMESTRING;
case UIDeviceAppleTV4 : return APPLETV_4G_NAMESTRING;
case UIDeviceUnknownAppleTV: return APPLETV_UNKNOWN_NAMESTRING;
case UIDeviceSimulator: return SIMULATOR_NAMESTRING;
case UIDeviceSimulatoriPhone: return SIMULATOR_IPHONE_NAMESTRING;
case UIDeviceSimulatoriPad: return SIMULATOR_IPAD_NAMESTRING;
case UIDeviceSimulatorAppleTV: return SIMULATOR_APPLETV_NAMESTRING;
case UIDeviceIFPGA: return IFPGA_NAMESTRING;
case UIDeviceOSX: return [self macHWName];
default: return IOS_FAMILY_UNKNOWN_DEVICE;
}
}
// macHWName
-(NSString *)macHWName {
size_t len = 0;
sysctlbyname("hw.model", NULL, &len, NULL, 0);
if (len) {
char *model = malloc(len*sizeof(char));
sysctlbyname("hw.model", model, &len, NULL, 0);
NSString *name = [[NSString alloc] initWithUTF8String:model];
free(model);
return name;
};
return @"macOS";
}
// platform type
- (NSUInteger)platformType
{
#if TARGET_OS_IPHONE
NSString *platform = [self platform];
// The ever mysterious iFPGA
if ([platform isEqualToString:@"iFPGA"]) return UIDeviceIFPGA;
// iPhone
if ([platform isEqualToString:@"iPhone1,1"]) return UIDevice1GiPhone;
if ([platform isEqualToString:@"iPhone1,2"]) return UIDevice3GiPhone;
if ([platform hasPrefix:@"iPhone2"]) return UIDevice3GSiPhone;
if ([platform hasPrefix:@"iPhone3"]) return UIDevice4iPhone;
if ([platform hasPrefix:@"iPhone4"]) return UIDevice4SiPhone;
if ([platform hasPrefix:@"iPhone5"]) return UIDevice5iPhone;
if ([platform hasPrefix:@"iPhone6"]) return UIDevice5SiPhone;
if ([platform isEqualToString:@"iPhone7,1"]) return UIDevice6PlusiPhone;
if ([platform isEqualToString:@"iPhone7,2"]) return UIDevice6iPhone;
if ([platform isEqualToString:@"iPhone8,1"]) return UIDevice6siPhone;
if ([platform isEqualToString:@"iPhone8,2"]) return UIDevice6SPlusiPhone;
if ([platform isEqualToString:@"iPhone9,1"]) return UIDevice7iPhone;
if ([platform isEqualToString:@"iPhone9,3"]) return UIDevice7iPhone;
if ([platform isEqualToString:@"iPhone9,2"]) return UIDevice7PlusiPhone;
if ([platform isEqualToString:@"iPhone9,4"]) return UIDevice7PlusiPhone;
if ([platform isEqualToString:@"iPhone10,1"]) return UIDevice8iPhone;
if ([platform isEqualToString:@"iPhone10,4"]) return UIDevice8iPhone;
if ([platform isEqualToString:@"iPhone10,2"]) return UIDevice8PlusiPhone;
if ([platform isEqualToString:@"iPhone10,5"]) return UIDevice8PlusiPhone;
if ([platform isEqualToString:@"iPhone10,3"]) return UIDeviceXiPhone;
if ([platform isEqualToString:@"iPhone10,6"]) return UIDeviceXiPhone;
if ([platform isEqualToString:@"iPhone11,2"]) return UIDeviceXSiPhone;
if ([platform isEqualToString:@"iPhone11,6"]) return UIDeviceXSMaxiPhone;
if ([platform isEqualToString:@"iPhone11,4"]) return UIDeviceXSMaxiPhone;
if ([platform isEqualToString:@"iPhone11,8"]) return UIDeviceXRiPhone;
if ([platform isEqualToString:@"iPhone8,4"]) return UIDeviceSEPhone;
// iPod
if ([platform hasPrefix:@"iPod1"]) return UIDevice1GiPod;
if ([platform hasPrefix:@"iPod2"]) return UIDevice2GiPod;
if ([platform hasPrefix:@"iPod3"]) return UIDevice3GiPod;
if ([platform hasPrefix:@"iPod4"]) return UIDevice4GiPod;
if ([platform hasPrefix:@"iPod5"]) return UIDevice5GiPod;
if ([platform hasPrefix:@"iPod7"]) return UIDevice6GiPod;
// iPad
if ([platform hasPrefix:@"iPad1"]) return UIDevice1GiPad;
if ([platform hasPrefix:@"iPad2"]) return UIDevice2GiPad;
if ([platform hasPrefix:@"iPad3"]) return UIDevice3GiPad;
if ([platform hasPrefix:@"iPad4"]) return UIDevice4GiPad;
if ([platform hasPrefix:@"iPad5"]) return UIDevice5GiPad;
if ([platform hasPrefix:@"iPad6"]) return UIDevice6GiPad;
if ([platform isEqualToString:@"iPad8,5"] ||
[platform isEqualToString:@"iPad8,6"] ||
[platform isEqualToString:@"iPad8,7"] ||
[platform isEqualToString:@"iPad8,8"]) {
return UIDeviceiPadPro12_93g;
}
if ([platform isEqualToString:@"iPad8,1"] ||
[platform isEqualToString:@"iPad8,2"] ||
[platform isEqualToString:@"iPad8,3"] ||
[platform isEqualToString:@"iPad8,4"]) {
return UIDeviceiPadPro11;
}
if ([platform isEqualToString:@"iPad7,5"] ||
[platform isEqualToString:@"iPad7,6"]) {
return UIDeviceiPadPro6g;
}
if ([platform isEqualToString:@"iPad7,3"] ||
[platform isEqualToString:@"iPad7,4"]) {
return UIDeviceiPadPro10_5;
}
if ([platform isEqualToString:@"iPad7,1"] ||
[platform isEqualToString:@"iPad7,2"]) {
return UIDeviceiPadPro12_9;
}
// Apple TV
if ([platform hasPrefix:@"AppleTV2"]) return UIDeviceAppleTV2;
if ([platform hasPrefix:@"AppleTV3"]) return UIDeviceAppleTV3;
if ([platform hasPrefix:@"iPhone"]) return UIDeviceUnknowniPhone;
if ([platform hasPrefix:@"iPod"]) return UIDeviceUnknowniPod;
if ([platform hasPrefix:@"iPad"]) return UIDeviceUnknowniPad;
if ([platform hasPrefix:@"AppleTV"]) return UIDeviceUnknownAppleTV;
// Simulator thanks Jordan Breeding
if ([platform hasSuffix:@"86"] || [platform isEqual:@"x86_64"])
{
return UIDeviceSimulatoriPhone;
}
#else
return UIDeviceOSX;
#endif
return UIDeviceUnknown;
}
// get system info by name
- (NSString *)getSysInfoByName:(char *)typeSpecifier
{
size_t size;
sysctlbyname(typeSpecifier, NULL, &size, NULL, 0);
char *answer = malloc(size);
sysctlbyname(typeSpecifier, answer, &size, NULL, 0);
NSString *results = [NSString stringWithCString:answer encoding: NSUTF8StringEncoding];
free(answer);
return results;
}
// platform
- (NSString *)platform
{
return [self getSysInfoByName:"hw.machine"];
}
// copy
- (instancetype)copyWithZone:(NSZone *)__unused zone {
MTApiEnvironment *result = [[MTApiEnvironment alloc] init];
result.apiId = self.apiId;
result.appVersion = self.appVersion;
result.layer = self.layer;
result.langPack = self.langPack;
result->_langPackCode = self.langPackCode;
result->_socksProxySettings = self.socksProxySettings;
result->_networkSettings = self.networkSettings;
result->_systemCode = self.systemCode;
result.disableUpdates = self.disableUpdates;
result.tcpPayloadPrefix = self.tcpPayloadPrefix;
result.datacenterAddressOverrides = self.datacenterAddressOverrides;
[result _updateApiInitializationHash];
return result;
}
// with updated socks proxy settings
- (MTApiEnvironment *)withUpdatedSocksProxySettings:(MTSocksProxySettings *)socksProxySettings {
MTApiEnvironment *result = [[MTApiEnvironment alloc] init];
result.apiId = self.apiId;
result.appVersion = self.appVersion;
result.layer = self.layer;
result.langPack = self.langPack;
result->_langPackCode = self.langPackCode;
result->_socksProxySettings = socksProxySettings;
result->_networkSettings = self.networkSettings;
result->_systemCode = self.systemCode;
result.disableUpdates = self.disableUpdates;
result.tcpPayloadPrefix = self.tcpPayloadPrefix;
result.datacenterAddressOverrides = self.datacenterAddressOverrides;
[result _updateApiInitializationHash];
return result;
}
// with updated network settings
- (MTApiEnvironment *)withUpdatedNetworkSettings:(MTNetworkSettings *)networkSettings {
MTApiEnvironment *result = [[MTApiEnvironment alloc] init];
result.apiId = self.apiId;
result.appVersion = self.appVersion;
result.layer = self.layer;
result.langPack = self.langPack;
result->_langPackCode = self.langPackCode;
result->_socksProxySettings = self.socksProxySettings;
result->_networkSettings = networkSettings;
result->_systemCode = self.systemCode;
result.disableUpdates = self.disableUpdates;
result.tcpPayloadPrefix = self.tcpPayloadPrefix;
result.datacenterAddressOverrides = self.datacenterAddressOverrides;
[result _updateApiInitializationHash];
return result;
}
// with updated system code
- (MTApiEnvironment *)withUpdatedSystemCode:(NSData *)systemCode {
MTApiEnvironment *result = [[MTApiEnvironment alloc] init];
result.apiId = self.apiId;
result.appVersion = self.appVersion;
result.layer = self.layer;
result.langPack = self.langPack;
result->_langPackCode = self.langPackCode;
result->_socksProxySettings = self.socksProxySettings;
result->_networkSettings = self.networkSettings;
result->_systemCode = systemCode;
result.disableUpdates = self.disableUpdates;
result.tcpPayloadPrefix = self.tcpPayloadPrefix;
result.datacenterAddressOverrides = self.datacenterAddressOverrides;
[result _updateApiInitializationHash];
return result;
}