( instancetype ) provisionerWithCredentials : ( NSString ) اسم المستخدم : ( NSString ) كلمة {
العودة [[EEProvisioning الوك ] initWithCredentials: اسم المستخدم: كلمة المرور].
}
( instancetype ) initWithCredentials : ( NSString ) اسم المستخدم : ( NSString ) كلمة {
النفس = [ سوبر الحرف الأول ].
إذا (ذاتي) {
_username = اسم المستخدم ؛
_password = كلمة المرور ؛
}
العودة الذاتية
}
( NSError ) _errorFromString : ( NSString ) سلسلة {
NSDictionary * userInfo = @ {
NSLocalizedDescriptionKey : NSLocalizedString (سلسلة ، لا شيء ) ،
NSLocalizedFailureReasonErrorKey : NSLocalizedString (سلسلة ، لا شيء ) ،
NSLocalizedRecoverySuggestionErrorKey : NSLocalizedString ( @ " " ، لا شيء )
} ؛
مناولة (خطأ ، لا شيء ، لا شيء ، لا شيء ، لا شيء ) ؛
العودة ؛
}
[ النفس _provisioningStageTwoWithIdentifier: معرف andCallback: ^ ( NSError * خطأ، NSString * privateKey، NSDictionary * شهادة) {
إذا (خطأ) {
ALog ( @ " ERROR: ٪ @ " ، error. localizedDescription ) ؛
مناولة (خطأ ، لا شيء ، لا شيء ، لا شيء ، لا شيء ) ؛
العودة ؛
}
[ النفس _provisioningStageThreeWithIdentifier: معرف binaryLocation: binaryLocation andCallback: ^ ( NSError * خطأ، NSString * appIdId، NSDictionary * الاستحقاقات) {
إذا (خطأ) {
ALog ( @ " ERROR: ٪ @ " ، error. localizedDescription ) ؛
مناولة (خطأ ، لا شيء ، لا شيء ، لا شيء ، لا شيء ) ؛
العودة ؛
}
[ self _provisioningStageFourWithIdentifier: معرف appIdId: appIdId والاستدعاء: ^ ( NSError * error، NSData * embeddedMobileprovision) {
// انتهى ، ارجع إلى المتصل.
completionHandler (خطأ، embeddedMobileprovision، privateKey، شهادة، والاستحقاقات)؛
}] ؛
}] ؛
}] ؛
}] ؛
}
// // //////////////////////////////////////////////////// ////////////////////////////////////////////////////// //////////////
// الطرق الخاصة: مرحلة التزويد 1
// // //////////////////////////////////////////////////// ////////////////////////////////////////////////////// //////////////
NSError * error2 = [EEProvisioning _errorFromString: [ @ " listAllDevelopmentCertificatesForTeamID: " stringByAppendingString: error.localizedDescription]]؛
completionHandler (error2، لا شيء ، لا شيء )؛
العودة ؛
}
// TODO: تحقق من plist بحثًا عن الأخطاء.
/ *
* نحتاج إلى إنشاء شهادة توقيع رموز التطوير للجهاز الحالي إذا لم يكن أحدها موجودًا ،
* أو إذا فقدنا المفتاح الخاص محليًا. في حالة فقد المفتاح الخاص ، يجب أن نبطله
* شهادة التطوير للجهاز الحالي.
*
* علاوة على ذلك ، لن نستخدم "Cydia" كاسم لشهادة التوقيع بالرمز. الأصلي
* قام Cydia Extender بهذا ، مما تسبب بعد ذلك في حدوث مشكلات: لا يمكن للأجهزة الأخرى استخدام نفس معرف Apple
* للتوقيع ، لأنهم سيفقدون المفتاح الخاص للشهادة. كنتيجة ل،
* سيحاولون تقديم طلب توقيع رمز جديد باستخدام اسم الجهاز "Cydia" و machineId
* من "CB6D337C-3D63-4523-AADE-6622234ABDA8". ثم يتم رفض هذا!
*
* لتلخيص:
1. تحقق مما إذا كان لدينا المفتاح الخاص لشهادة التطوير في سلسلة المفاتيح لمعرف هذا الجهاز
2. تحقق من وجود شهادة تطوير لمعرف هذا الجهاز وصالحة.
2-أ. إذا كان كلاهما صحيحًا ، فقم بإرجاع كل من الشهادة والمفتاح إلى معالج الإكمال.
3. إذا كان أي منهما غير صحيح ، أرسل طلب توقيع رمز تطوير جديد ، وألغه إذا كان (1) صحيحًا.
3.a. أعد الشهادة الجديدة والمفتاح إلى معالج الإكمال.
*
* لاحظ أيضًا أننا قمنا بتخزين معرف الفريق الذي يستخدمه المفتاح الخاص. هذا حتى نتمكن من الكشف عن المستخدم
* قام بتبديل الحسابات ، ولذا نقوم بإعادة / إنشاء CSR للتطوير حسب الحاجة.
* /
NSString * privateKey = [SAMKeychain passwordForService: @ " com.matchstic.openextender " الحساب: @ " privateKey " ].
NSString * privateKeyAssociatedTeamID = [SAMKeychain passwordForService: @ " com.matchstic.openextender " الحساب: @ " privateKeyTeamID " ].
BOOL hasValidCertificate = NO ؛
NSDate * الآن = [ تاريخ NSDate ] ؛
شهادة NSDictionary * ؛
لـ ( NSDictionary * deb in [plist objectForKey: @ " الشهادات " ]) {
NSString * machineId = ديكت [ @ " machineId " ].
إذا ([machineId isEqualToString: [ self _identifierForCurrentMachine ]]) {
// حسنًا رائع. الآن ، نتحقق لمعرفة ما إذا كانت قد انتهت صلاحيتها.
شهادة = ديكت ؛
// قارن expirationDate إلى الآن. إذا تم تمريرها ، فإن الشهادة غير صالحة.
hasValidCertificate = نعم ؛
NSDate * CertificateExpiryDate = [ ict objectForKey: @ " expirationDate " ] ؛
إذا ([ قارن الآن : CertificateExpiryDate] == NSOrderedDescending) {
// مرت الشهادة تاريخ انتهاء صلاحيتها.
hasValidCertificate = NO ؛
}
كسر .
}
}
BOOL currentTeamIDMatchesStored = [[EEAppleServices currentTeamID ] isEqualToString: privateKeyAssociatedTeamID] ،
إذا (! hasValidCertificate || [privateKey isEqualToString: @ " " ] || privateKey == nil ||! currentTeamIDMatchesStored) {
// إذا كانت الشهادة موجودة بالفعل ، فقم بإبطالها.
BOOL shouldRevokeFirst = Certificate! = لا شيء ؛
// إبطال تلك الشهادة! لاحظ أن هذا الإلغاء خاص بهذا الجهاز فقط.
// لذلك ، يجب ألا نواجه مشكلة إذا كنا في فريق يسمح بنشر App Store.
إذا (shouldRevokeFirst) {
NSString * serialNumber = [شهادة objectForKey: @ " serialNumber " ].
NSString * reason = @ " " ؛
إذا ([مفتاح خاص isEqualToString: @ " " ] || privateKey == nil ||! currentTeamIDMatchesStored)
السبب = @ " عدم امتلاك المفتاح الخاص لذلك المخزن على هذا الجهاز. " ؛
آخر
السبب = @ " هذه الشهادة منتهية الصلاحية. " ؛
NSLog ( @ " إبطال الشهادة بالرقم التسلسلي ' ٪ @ ' ، بسبب ٪ @ " ، الرقم التسلسلي ، السبب) ؛
[EEAppleServices revokeCertificateForSerialNumber: serialNumber andTeamID: [EEAppleServices currentTeamID ] withCompletionHandler: ^ ( NSError * error، NSDictionary * plist) {
إذا (خطأ) {
ALog ( @ " ERROR: ٪ @ " ، error. localizedDescription ) ؛
// معالجة الخطأ.
مناولة (خطأ ، لا شيء ، لا شيء ) ؛
العودة ؛
}
// لا داعي للقلق بشأن أي أخطاء قائمة على plist هنا.
// أرسل طلب توقيع الرمز الجديد إلى Apple.
[ النفس _submitNewCodeSigningRequestForTeamID: [EEAppleServices currentTeamID ] MACHINENAME: [ النفس _nameForCurrentMachine ] machineId: [ النفس _identifierForCurrentMachine ] withCallback: ^ ( NSError * خطأ، NSString * privateKey، NSDictionary * شهادة) {
إذا (خطأ) {
ALog ( @ " ERROR: ٪ @ " ، error. localizedDescription ) ؛
// معالجة الخطأ.
مناولة (خطأ ، لا شيء ، لا شيء ) ؛
العودة ؛
}
// قم بتخزين مفتاح خاص جديد في سلسلة المفاتيح للاستخدام في المستقبل.
[SAMKeychain setPassword: privateKey forService: حساب @ " com.matchstic.openextender " : @ " privateKey " ] ؛
[SAMKeychain setPassword: [EEAppleServices currentTeamID ] للخدمة: حساب @ " com.matchstic.openextender " : @ " privateKeyTeamID " ] ؛
// اقرأ الشهادة من النتيجة ، وأعد تمريرها إلى المتصل باستخدام المفتاح الخاص أيضًا.
completionHandler ( لا شيء ، privateKey، شهادة)؛
}] ؛
}] ؛
العودة ؛
}
// نحتاج إلى تقديم طلب توقيع رمز ، حتى نتمكن من تسجيل الدخول على هذا الجهاز.
// أرسل طلب توقيع الرمز الجديد إلى Apple.
[ self _submitNewCodeSigningRequestForTeamID: [EEAppleServices currentTeamID ]
machineName: [ self _nameForCurrentMachine ]
machineId: [ self _identifierForCurrentMachine ]
withCallback: ^ ( NSError * خطأ، NSString * privateKey، NSDictionary * شهادة) {
إذا (خطأ) {
ALog ( @ " ERROR: ٪ @ " ، error. localizedDescription ) ؛
// معالجة الخطأ.
مناولة (خطأ ، لا شيء ، لا شيء ) ؛
العودة ؛
}
// قم بتخزين مفتاح خاص جديد في سلسلة المفاتيح للاستخدام في المستقبل.
[SAMKeychain setPassword: privateKey forService: حساب @ " com.matchstic.openextender " : @ " privateKey " ] ؛
[SAMKeychain setPassword: [EEAppleServices currentTeamID ] للخدمة: حساب @ " com.matchstic.openextender " : @ " privateKeyTeamID " ] ؛
// اقرأ الشهادة من النتيجة ، وأعد تمريرها إلى المتصل باستخدام المفتاح الخاص أيضًا.
completionHandler ( لا شيء ، privateKey، شهادة)؛
}] ؛
} آخر {
// إعادة المفتاح الخاص إلى المتصل.
completionHandler ( لا شيء ، privateKey، شهادة)؛
}
}] ؛
}
( NSString *) _nameForCurrentMachine {
// بحاجة إلى تغيير كيفية الحصول على اسم الجهاز للأجهزة التي تعمل بنظام iOS.
إذا كان TARGET_OS_SIMULATOR
عودة @ " Simulator " ؛
elif TARGET_OS_IPHONE
عودة [ NSString stringWithFormat: @ " ٪ @ " ، [[UIDevice currentDevice ] اسم ]].
// // EEProvisioning.m // OpenExtenderTest // // تم إنشاؤه بواسطة مات كلارك بتاريخ 28/12/2017. // حقوق الطبع والنشر © 2017 مات كلارك. كل الحقوق محفوظة. //
استيراد " EEProvisioning.h "
استيراد " EEAppleServices.h "
استيراد " EESigning.h "
استيراد " SAMKeychain.h "
include < cstdio >
تشمل < iostream >
تشمل < openssl / rsa.h >
include < openssl / pem.h >
// NSHost هي واجهة برمجة تطبيقات خاصة على الأنظمة الأساسية بخلاف أنظمة macOS
إذا كان TARGET_OS_IPHONE
@ واجهة NSHost : NSObject
import < UIKit / UIKit.h > // للحصول على اسم الجهاز
endif
تعريف ALog (fmt، ...) NSLog (( @ " ٪ s [Line ٪ d ] " fmt) ، PRETTY_FUNCTION ، LINE ، ## VA_ARGS)
implementation EEProvisioning
// // //////////////////////////////////////////////////// ////////////////////////////////////////////////////// ////////////// // التهيئة // // //////////////////////////////////////////////////// ////////////////////////////////////////////////////// //////////////
( instancetype ) provisionerWithCredentials : ( NSString ) اسم المستخدم : ( NSString ) كلمة { العودة [[EEProvisioning الوك ] initWithCredentials: اسم المستخدم: كلمة المرور]. }
( instancetype ) initWithCredentials : ( NSString ) اسم المستخدم : ( NSString ) كلمة { النفس = [ سوبر الحرف الأول ].
إذا (ذاتي) { _username = اسم المستخدم ؛ _password = كلمة المرور ؛ }
العودة الذاتية }
( NSError ) _errorFromString : ( NSString ) سلسلة { NSDictionary * userInfo = @ { NSLocalizedDescriptionKey : NSLocalizedString (سلسلة ، لا شيء ) ، NSLocalizedFailureReasonErrorKey : NSLocalizedString (سلسلة ، لا شيء ) ، NSLocalizedRecoverySuggestionErrorKey : NSLocalizedString ( @ " " ، لا شيء ) } ؛
NSError * error = [ NSError errorWithDomain: NSCocoaErrorDomain الكود: - 1 userInfo: userInfo] ؛
خطأ العودة }
// // //////////////////////////////////////////////////// ////////////////////////////////////////////////////// ////////////// // الطرق العامة // // //////////////////////////////////////////////////// ////////////////////////////////////////////////////// //////////////
( الفراغ ) provisionDevice : ( NSString ) UDID اسم : ( NSString ) اسم withTeamIDCheck : ( NSString (^) ( NSArray )) teamIDCallback andCallback : ( الفراغ (^) ( NSError *)) completionHandler { // لا .
[ self _provisioningStageOneWithIdentifier: @ " " withTeamIDCheck: teamIDCallback and Callback: ^ ( NSError * error) { إذا (خطأ) { ALog ( @ " ERROR: ٪ @ " ، error. localizedDescription ) ؛
}] ؛ }
( الفراغ ) revokeCertificatesWithTeamIDCheck : ( NSString (^) ( NSArray )) teamIDCallback andCallback : ( الفراغ (^) ( NSError *)) completionHandler {
[ self _provisioningStageOneWithIdentifier: @ " " withTeamIDCheck: teamIDCallback and Callback: ^ ( NSError * error) { إذا (خطأ) { ALog ( @ " ERROR: ٪ @ " ، error. localizedDescription ) ؛
}] ؛ }
( الفراغ ) downloadProvisioningProfileForApplicationIdentifier : ( NSString ) معرف binaryLocation : ( NSString ) binaryLocation withTeamIDCheck : ( NSString (^) ( NSArray )) teamIDCallback andCallback : ( الفراغ (^) ( NSError ، NSData ، NSString ، NSDictionary ، NSDictionary *)) إتمام ؛ {
/ *
[ self _provisioningStageOneWithIdentifier: المعرف withTeamIDCheck: teamIDCallback and Callback: ^ ( NSError * error) { إذا (خطأ) { ALog ( @ " ERROR: ٪ @ " ، error. localizedDescription ) ؛
}] ؛
}
// // //////////////////////////////////////////////////// ////////////////////////////////////////////////////// ////////////// // الطرق الخاصة: مرحلة التزويد 1 // // //////////////////////////////////////////////////// ////////////////////////////////////////////////////// //////////////
( الفراغ ) _provisioningStageOneWithIdentifier : ( NSString ) معرف withTeamIDCheck : ( NSString (^) ( NSArray )) teamIDCallback andCallback : ( الفراغ (^) ( NSError )) completionHandler {
/ *
[ self _signIn: _username password: _password withCallback: ^ ( NSError * error) { إذا (! خطأ) { // استمر فقط إذا تمت المصادقة! NSLog ( @ " Authenticated! " ) ؛
}] ؛ }
( باطل ) _signIn : ( NSString ) اسم المستخدم كلمة المرور : ( NSString ) كلمة withCallback : ( الفراغ (^) ( NSError *)) completionHandler {
[EEAppleServices signInWithUsername: username password: password andCompletionHandler: ^ ( NSError error، NSDictionary plist) { إذا (خطأ) { ALog ( @ " ERROR: ٪ @ " ، error. localizedDescription ) ؛
}] ؛ }
// // //////////////////////////////////////////////////// ////////////////////////////////////////////////////// ////////////// // الطرق الخاصة: مرحلة التزويد 2 // // //////////////////////////////////////////////////// ////////////////////////////////////////////////////// //////////////
( الفراغ ) _provisioningStageTwoWithIdentifier : ( NSString ) معرف andCallback : ( باطل (^) ( NSError ، NSString ، NSDictionary )) completionHandler {
/ *
[ النفس _handleDevelopmentCodesigningRequestIfNecessary: ^ ( NSError خطأ، NSString privateKey، NSDictionary * شهادة) { إذا (! خطأ) { NSLog ( @ " لدينا شهادة تطوير يمكن استخدامها! " ) ؛ } آخر { ALog ( @ " ERROR: ٪ @ " ، error. localizedDescription ) ؛ }
}] ؛ }
( الفراغ ) _handleDevelopmentCodesigningRequestIfNecessary : ( باطل (^) ( NSError ، NSString ، NSDictionary *)) completionHandler {
[EEAppleServices listAllDevelopmentCertificatesForTeamID: [EEAppleServices currentTeamID ] withCompletionHandler: ^ ( NSError error، NSDictionary plist) { إذا (خطأ) { ALog ( @ " ERROR: ٪ @ " ، error. localizedDescription ) ؛
}] ؛
}
( NSString *) _nameForCurrentMachine { // بحاجة إلى تغيير كيفية الحصول على اسم الجهاز للأجهزة التي تعمل بنظام iOS.
إذا كان TARGET_OS_SIMULATOR
عودة @ " Simulator " ؛
elif TARGET_OS_IPHONE
عودة [ NSString stringWithFormat: @ " ٪ @ " ، [[UIDevice currentDevice ] اسم ]].
آخر
عودة [ NSString stringWithFormat: @ " ٪ @ " ، [[ NSHost currentHost ] localizedName ]].
endif
}
( NSString ) _identifierForCurrentMachine { // نحن نستخدم UUID مستمر هنا ، وليس UDID أو أي شيء. NSString uuid = [SAMKeychain passwordForService: @ " com.matchstic.openextender " الحساب: @ " uuid " ] ؛ إذا (! uuid || [uuid isEqualToString: @ " " ]) { uuid = [[ NSUUID UUID ] UUIDString ] ، [SAMKeychain setPassword: uuid للخدمة: حساب @ " com.matchstic.openextender " : @ " uuid " ] ؛ } عودة uuid }
// إرجاع مفتاح خاص جديد في args [1] وشهادة جديدة في args [2] من comletionHandler.
( الفراغ ) _submitNewCodeSigningRequestForTeamID : ( NSString ) teamid MACHINENAME : ( NSString ) MACHINENAME machineId : ( NSString ) machineId withCallback : ( الفراغ (^) ( NSError ، NSString ، NSDictionary )) completionHandler {
// أولاً ، نقوم بإنشاء CSR. NSData privateKey ؛ NSData codeSigningRequest ؛
int ret = [ self _generateCodeSigningRequest: & privateKey: & codeSigningRequest]؛ إذا (ret! = 1 ) { NSError * error = [EEProvisioning _errorFromString: @ " submitDevelopmentCSR: فشل إنشاء طلب توقيع رمز " ]؛ ALog ( @ " ERROR: ٪ @ " ، error. localizedDescription ) ؛
}
NSLog ( @ " إنشاء طلب توقيع رمز ، إرسال ... " ) ؛
// ذاهب إلى إضافة بادئة إلى اسم الجهاز. MACHINENAME = [ NSString stringWithFormat: @ " RPV- ٪ @ " ، MACHINENAME].
// الآن بعد أن أصبح لدينا CSR والمفتاح الخاص ، يمكننا تقديم CSR إلى Apple. [EEAppleServices submitCodeSigningRequestForTeamID: teamid machineName: machineName machineID: machineId codeSigningRequest: codeSigningRequest withCompletionHandler: ^ ( NSError error، NSDictionary plist) { إذا (خطأ) { ALog ( @ " ERROR: ٪ @ " ، error. localizedDescription ) ؛
}] ؛ }
( int ) _generateCodeSigningRequest : ( NSData ) privateKey : ( NSData ) codeSigningRequest {
// الشفرة المستخدمة من: http://www.codepool.biz/how-to-use-openssl-to-generate-x-509-certificate-request.html
int ret = 0 ؛ RSA r = NULL ؛ BIGNUM bne = NULL ؛
عدد int nVersion = 1 ؛ بت عدد صحيح = 2048 ؛ طويلة غير موقعة = RSA_F4 ؛
X509_REQ x509_req = NULL ؛ X509_NAME x509_name = NULL ، EVP_PKEY pKey = NULL ؛ BIO csr = NULL ؛ BIO privKey = NULL ؛ char data = NULL ؛ لين طويل = 0 ؛
// معلومات الشهادة. const char szCountry = " US " ؛ const char szCommon = " Cydia " ؛
// 1. إنشاء مفتاح rsa bne = BN_new () ، ret = BN_set_word ( bne ، int (e)) ؛ إذا (ret! = 1 ) { الانتقال إلى free_all ؛ }
ص = RSA_new () ؛ ret = RSA_generate_key_ex (r، bits، bne، NULL ) ؛ إذا (ret! = 1 ) { الانتقال إلى free_all ؛ }
// 2. تعيين إصدار x509 req x509_req = X509_REQ_new () ، ret = X509_REQ_set_version (x509_req ، nVersion) ؛ إذا (ret! = 1 ) { الانتقال إلى free_all ؛ }
// 3. تعيين موضوع x509 مطلوب x509_name = X509_REQ_get_subject_name (x509_req) ؛
أرجع = X509_NAME_add_entry_by_txt (x509_name، " C " ، MBSTRING_ASC، ( CONST غير موقعة تشار *) szCountry، - 1 ، - 1 ، 0 )؛ إذا (ret! = 1 ) { الانتقال إلى free_all ؛ }
أرجع = X509_NAME_add_entry_by_txt (x509_name، " CN " ، MBSTRING_ASC، ( CONST غير موقعة تشار *) szCommon، - 1 ، - 1 ، 0 )؛ إذا (ret! = 1 ) { الانتقال إلى free_all ؛ }
// 4. تعيين المفتاح العام لـ x509 req pKey = EVP_PKEY_new () ، EVP_PKEY_assign_RSA (pKey، r) ؛
ret = X509_REQ_set_pubkey (x509_req ، pKey) ؛ إذا (ret! = 1 ) { الانتقال إلى free_all ؛ }
// 5. تعيين مفتاح تسجيل x509 req ret = X509_REQ_sign (x509_req ، pKey ، EVP_sha1 ()) ؛ // إرجاع x509_req-> التوقيع-> الطول إذا (ret <= 0 ) { الانتقال إلى free_all ؛ }
csr = BIO_new ( BIO_s_mem ()) ؛ ret = PEM_write_bio_X509_REQ (csr، x509_req) ؛
privKey = BIO_new ( BIO_s_mem ()) ؛ ret = PEM_write_bio_RSAPrivateKey (privKey، r، NULL ، NULL ، 0 ، NULL ، NULL ) ؛
// 6. ادفع CSR والمفتاح الخاص في مخرجات وظيفتنا. len = BIO_get_mem_data (csr، & data) ؛
len = BIO_get_mem_data (privKey، & data) ؛
// 7. مجاني free_all: ص = NULL ؛ // سيكون مجانيًا بتنسيق rsa عند EVP_PKEY_free (pKey)
X509_REQ_free (x509_req) ؛ BIO_free_all (csr) ؛ BIO_free_all (privKey) ؛
EVP_PKEY_free (مفتاح pKey) ؛ BN_free ( بن ) ؛
العودة (ret == 1 ) ؛ }
// // //////////////////////////////////////////////////// ////////////////////////////////////////////////////// ////////////// // الطرق الخاصة: مرحلة التزويد 3 // // //////////////////////////////////////////////////// ////////////////////////////////////////////////////// //////////////
( الفراغ ) _provisioningStageThreeWithIdentifier : ( NSString ) معرف binaryLocation : ( NSString ) binaryLocation andCallback : ( الفراغ (^) ( NSError ، NSString ، NSDictionary *)) completionHandler {
/ *
[ self _addOrUpdateApplicationID: المعرف موقع ثنائي: موقع ثنائي withCompletionHandler: ^ ( NSError خطأ، NSString appIdId، NSDictionary * الاستحقاقات) { إذا (خطأ) { ALog ( @ " ERROR: ٪ @ " ، error. localizedDescription ) ؛ }
}] ؛ }
( الفراغ ) _addOrUpdateApplicationID : ( NSString ) applicationIdentifier binaryLocation : ( NSString ) binaryLocation withCompletionHandler : ( الفراغ (^) ( NSError ، NSString ، NSDictionary *)) completionHandler {
[قائمة EEAppleServicesAllApplicationsForTeamID: [EEAppleServices currentTeamID ] withCompletionHandler: ^ ( NSError error، NSDictionary plist) { إذا (خطأ) { ALog ( @ " ERROR: ٪ @ " ، error. localizedDescription ) ؛
}] ؛ }
( الفراغ ) _recursivelyAssignApplicationIdId : ( NSString ) applicationIdId toApplicationGroups : ( NSMutableArray ) applicationGroups interimAppGroups : ( NSMutableArray ) interimAppGroups withCompletionHandler : ( باطل (^) ( NSError ، NSArray *)) completionHandler {
// End Case guard إذا (applicationGroups. count == 0 ) { completionHandler ( لا شيء ، interimAppGroups)؛ العودة ؛ }
NSString * nextApplicationGroup = [applicationGroups firstObject ].
[ النفس _assignApplicationIdId: applicationIdId toGroupIfNecessary: nextApplicationGroup withCompletionHandler: ^ ( NSError خطأ، NSString groupIdentifier) {
}] ؛ }
( الفراغ ) _assignApplicationIdId : ( NSString ) applicationIdId toGroupIfNecessary : ( NSString ) applicationGroupIdentifier withCompletionHandler : ( باطل (^) ( NSError ، NSString )) completionHandler { [قائمة EEAppleServicesAllApplicationGroupsForTeamID: [EEAppleServices currentTeamID ] withCompletionHandler: ^ ( NSError error، NSDictionary plist) {
}] ؛ }
( الفراغ ) _assignAppIdId : ( NSString ) appIdId toApplicationGroupIdentifier : ( NSString ) groupIdentifier withCompletionHandler : ( باطل (^) ( NSError *)) completionHandler {
// تعيين لمجموعة التطبيق. NSLog ( @ " Assigning appIdId ' ٪ @ ' to application group ' ٪ @ ' " ، appIdId، groupIdentifier)؛
[EEAppleServices assignApplicationGroup: groupIdentifier toApplicationIdId: appIdId teamID: [EEAppleServices currentTeamID ] withCompletionHandler: ^ ( NSError error، NSDictionary plist) { إذا (خطأ) { ALog ( @ " ERROR: ٪ @ " ، error. localizedDescription ) ؛
}] ؛ }
// // //////////////////////////////////////////////////// ////////////////////////////////////////////////////// ////////////// // الطرق الخاصة: مرحلة التزويد 4 // // //////////////////////////////////////////////////// ////////////////////////////////////////////////////// //////////////
( الفراغ ) _provisioningStageFourWithIdentifier : ( NSString ) معرف appIdId : ( NSString ) appIdId andCallback : ( باطل (^) ( NSError ، NSData )) completionHandler {
/ *
[ self _removeExistingProvisioningProfileForApplication: المعرف withCallback: ^ ( خطأ NSError *) { // لا داعي للقلق إذا كان هذا قد نجح بالفعل أم لا.
}] ؛
}
( الفراغ ) _downloadTeamProvisioningProfileForAppIdId : ( NSString ) appIdId withCallback : ( باطل (^) ( NSError ، NSData *)) completionHandler {
[EEAppleServices getProvisioningProfileForAppIdId: appIdId withTeamID: [EEAppleServices currentTeamID ] andCompletionHandler: ^ ( NSError error، NSDictionary plist) { إذا (خطأ) { ALog ( @ " ERROR: ٪ @ " ، error. localizedDescription ) ؛
}] ؛ }
// يعيد "لا" إلى رد الاتصال إذا لم يتم حذف أي ملف شخصي ، نعم إذا تم حذفه.
( الفراغ ) _removeExistingProvisioningProfileForApplication : ( NSString ) bundleIdentifier withCallback : ( الفراغ (^) ( NSError )) completionHandler {
NSLog ( @ " إبطال ملف التوفير القديم لـ ' ٪ @ ' إن أمكن " ، bundleIdentifier) ؛
NSString * _actualIdentifier = [ NSString stringWithFormat: @ " ٪ @ . ٪ @ " ، [EEAppleServices currentTeamID ]، bundleIdentifier].
[EEAppleServices deleteProvisioningProfileForApplication: _actualIdentifier andTeamID: [EEAppleServices currentTeamID ] withCompletionHandler: ^ ( NSError error، NSDictionary plist) { إذا (خطأ) { ALog ( @ " ERROR: ٪ @ " ، error. localizedDescription ) ؛
}] ؛ }
@النهاية