İOS / OSX Çerçeveleri Oluşturma: Diğer geliştiricilere dağıtmadan önce bunları kodlamak gerekli midir?


91

İOS ve OSX çerçevelerinin nasıl oluşturulacağını öğreniyorum. Örneğin iOS'u ele alalım, aşağıdaki adımlar şu ana kadar benim için çalışıyor:

  1. -sdk iphonesimulator ve Build eylemini kullanarak xcodebuild çerçevesi
  2. -sdk iphoneos ve Build eylemini kullanarak xcodebuild çerçevesi
  3. Evrensel ikili oluşturmak için lipo aracını kullanın, böylece lipo -infobeklenen:

Fat dosyasındaki mimariler: Foo.framework / Foo: i386 x86_64 armv7 arm64

Sorular şunlardır:

  1. Çerçevemin, onu kullanan geliştirici tarafından yeniden imzalanabileceğini okudum: "Kopyalamada Kod İmzası", ancak bunun için önkoşulların ne olduğunu anlamıyorum, yani daha önce imzalama kimliğimle bu evrensel ikiliyi kod imzalamak için kod işareti adımı eklemeli miyim? diğer geliştiricilere dağıtıyor musunuz?

  2. önceki olumlu ise - "iPhone Dağıtımı: ..." kimliğimi veya "iPhone Geliştiricisi: ..." yeterli mi kullanmalıyım (böylece bazı iOS projelerinin bir parçası olan çerçevem, özellikle App Store doğrulaması olmak üzere her türlü doğrulamayı geçer ) ?.

Cevabımın arka planı "CodeSign hatası: kod imzalama, birkaç üçüncü taraf çerçevede ve Kartaca # 235'te gördüğüm SDK'daki" iOS 8.3 "ürün türü" Çerçeve "için gerekli" veya "kod nesnesi imzalanmamış at all "(bir örnek: Realm # 1998'de bildirdiğim sorun .

Bu nedenle, çerçevelerimi kullananların, bunları kullandıklarında herhangi bir kod imzalama sorunuyla karşılaşmayacaklarından emin olmak istiyorum.

Not: Bu soru, tek bir geliştiriciye değil, çerçeve sağlayıcısı olan bir kuruluşa uygulandığında daha da ilginç hale geliyor.


Bu yorum 'CODE_SIGN_IDENTITY = iPhone Developer' kullanılmasını öneriyor ancak 'iPhone Dağıtımı' yerine neden 'Geliştirici'nin kullanıldığı açık değil.
Stanislav Pankevich

İlgili konu: Uygulamayı gömülü çerçeveli ancak kesin bir cevabı olmadan dışa aktarma .
Stanislav Pankevich

Bu soruyu Apple Geliştirici Forumlarında da kopyaladım : forums.developer.apple.com/thread/6400 .
Stanislav Pankevich

çerçevenizi dağıtırken bir sorum var, bir hata ayıklama derlemesi veya sürüm derlemesi dağıtıyorsunuz? ve bunu sürüm yapısında dağıtırsanız, bunu nasıl yapacaksınız?
niczm25

@ niczm25, bunu yapmamın bir yolu: stanislaw.github.io/2015/11/23/… .
Stanislav Pankevich

Yanıtlar:


138

Ödülü açtım: "Güvenilir ve / veya resmi kaynaklardan gelen bir cevap arıyorum." ama o zamandan beri böyle bir şey almadım.

@Jackslash tarafından verilen cevap doğru olsa da, hikayenin sadece bir kısmını anlatıyor, bu yüzden bu soruyu sorduğum anda görmek istediğim bir şekilde kendiminkini yazmak istiyorum.

Bu cevabın gerçekliği: Temmuz 2015. Büyük olasılıkla işler değişecek.

Çerçevenin doğru kod imzalama için gerekli eylemler içine Öncelikle edelim assert bölünmüş gerektiğini çerçevenin Geliştirici almak zorunda olduğu adımlar ve bu çerçevenin Tüketici almak zorundadır adımları tekrarlayın.

TLDR;

OSX çerçevesi için: Geliştirici, OSX çerçevesini kod imzalamadan dağıtmakta özgürdür, çünkü Tüketici yine de onu yeniden kodlar.

İOS çerçevesi için: Geliştirici, iOS çerçevesini kod imzalamadan dağıtmakta özgürdür, çünkü Tüketici yine de onu yeniden kodlayacaktır, ancak Geliştirici, iOS cihazı için derlediklerinde çerçevelerini kod imzalamaya Xcode tarafından zorlanmaktadır.

Radar nedeniyle: "Simülatör dilimlerini içeren iOS çerçeveleri App Store'a gönderilemez" iOS çerçevesinin tüketicisi, lipo -removesimülatör dilimlerini iOS çerçevesinden ayırmak için kullanılan "copy_frameworks" veya "strip_frameworks" gibi özel komut dosyası çalıştırmaya zorlanır ve yeniden -codesigns, çerçeveyi tasarlar çünkü bu noktada kod imzalayan kimliği, ne olursa olsun (veya olmasaydı) lipo -removemanipülasyonun yan etkisi olarak kaldırılır .

Daha uzun cevap izler.


Bu cevap "güvenilir ve / veya resmi kaynaklardan alınan bir cevap" değil, daha çok bir dizi deneysel gözlemlere dayanmaktadır.

Ampirik gözlem # 1: Tüketici umursamıyor çünkü Geliştiriciden aldıkları çerçeveyi yeniden kodlayacaklar

Github'da iyi bilinen açık kaynaklı projelerin ikili çerçeve dağıtımları kod imzalanmamıştır . Komut şunu codesign -d -vvvvverir: Keşfetmek için kullandığım tüm ikili iOS ve OSX çerçevelerinde "kod nesnesi hiç imzalanmamış". Bazı örnekler: ReactiveCocoa ve Mantle , Realm , PromiseKit .

Bu gözlemden, bu çerçevelerin yazarlarının, kendi adlarına Tüketici tarafından kod imzalanmasını amaçladıkları açıktır, yani bir Tüketici, Xcode tarafından sağlanan "Göm çerçeveler" derleme aşamasında "Kopyalamada Kod İşareti" bayrağını kullanmalı veya bazı özel kabuklar kullanmalıdır. Aynı şeyi manuel olarak yapan komut dosyası: Müşteri adına kodlar çerçevesi.

Bunun tersinin tek bir örneğini bulamadım: içinde kod imzalayan kimlikle dağıtılacak açık kaynak çerçevesi, bu nedenle yanıtın geri kalanında bu yaygın olarak benimsenen yaklaşımın doğru olduğunu varsayıyorum: Framework Developer'ın Çerçevelerini kod imzalayan kimliği olan diğer geliştiricilere dağıtır çünkü Tüketici yine de onu yeniden kodlar .

Yalnızca iOS için geçerli olan ve tamamen Geliştiricinin endişesi olan 2 numaralı ampirik gözlem

Tüketici onlar codesigned ya da olmasın Geliştirici aldığımız çerçeve umrumda olmasa da, Geliştirici iOS cihazının için oluşturduğunuz hala inşa sürecinin bir parçası olarak iOS çerçevesini codesign gerekiyor aksi Xcode inşa olmadığından: CodeSign error: code signing is required for product type 'Framework' in SDK 'iOS 8.1'. AlıntılamakJustin Spahr-Summers'dan :

OS X çerçevelerinin derleme sırasında kod imzalanmasına gerek yoktur ... Maalesef Xcode, iOS çerçevelerinin derleme sırasında kod imzalanmasını gerektirir.

Bu, 2 numaralı soruma oldukça iyi cevaplar: "iPhone Developer" kimliği, Xcode'u cajole etmek için yeterlidir, böylece cihaz için iOS çerçevesi oluşturacaktır. Kartaca # 339 ile ilgili bu yorum aynı şeyi söylüyor.

Ampirik gözlem # 3: Lipo aracı

Lipo aracının özel davranışı: İkili çerçeveye uygulandığında, her zaman kod işareti kimliklerini ondan yinelemeli olarak kaldırır :lipo -create/-remove codesigned framework ... -> not codesigned framework .

Bu, # 1 numaralı gözlemdeki tüm örneklerin kod imzalanmamasının bir cevabı olabilir: lipo uygulandıktan sonra kodlama kimliği ortadan kalkar, ancak 1 numaralı gözleme göre tüketici umursamadığı için sorun değil.

Bu gözlem özellikle AppStore hakkındaki bir sonraki 4 numaralı gözlemle ilgilidir.

Ampirik gözlem # 4: Simülatör dilimlerini içeren iOS çerçeveleri App Store'a gönderilemez

Bu yaygın olarak tartışılıyor: Bölge # 1163 ve Kartaca # 188 ve radar açılır: rdar: // 19209161 .

Bu tamamen Tüketicinin endişesidir: Tüketicinin uygulamasına dahil ettiği iOS evrensel çerçevesi için, uygulama geliştirilirken, uygulamanın AppStore doğrulamasını geçebilmesi için simülatör dilimini bu çerçevenin ikili dosyasından kaldıran özel komut dosyası (özel Komut Dosyası Çalıştırma Aşaması) çalıştırmaları gerekir.

Realm'de bulduğum ikili çerçeveler için iyi bir örnek: strip-frameworks.sh .

lipoDışındaki tüm mimari dilimlerini kaldırmak için kullanır ${VALID_ARCHS}ve daha sonra bunu Tüketici kimliğiyle yeniden kodlar - işte burada 3 numaralı gözlem devreye girer : çerçeve, üzerindeki lipo manipülasyonları nedeniyle yeniden kodlanacaktır.

Carthage'da CopyFrameworks.swift var Tüketici tarafından dahil edilen tüm çerçevelere aynı şeyi yapan betiğine sahiptir: Simülatör dilimlerini çıkarır ve Tüketici adına çerçeveyi yeniden kodlar.

Ayrıca iyi bir makale var: Xcode'da Dinamik Kitaplıklardan İstenmeyen Mimarileri Çıkarma .


Şimdi hem Geliştiricinin hem de Tüketicinin bakış açısından hem iOS hem de OSX üretmek için gereken adımlara genel bakış. İlk önce daha kolay olanı:

OSX

Geliştirici:

  1. OSX çerçevesi oluşturur
  2. Tüketiciye verir

Geliştirici'den hiçbir kod imzalama etkinliği gerekmez.

Tüketici:

  1. Developer'dan OSX çerçevesini alır
  2. Çerçeveyi Çerçevelere / dizine kopyalar ve "Kopyalamada Kod İmzası" işleminin bir parçası olarak kendi, Tüketici adına otomatik olarak kod imzalar.

iOS

Geliştirici:

  1. Cihaz için iOS çerçevesi oluşturur. Xcode için kod imzalama gereklidir, "iPhone Developer" kimliği yeterlidir.
  2. Simülatör için iOS çerçevesi oluşturur.
  3. Önceki ikisinden evrensel iOS çerçevesi üreten lipo kullanır. Bu noktada, 1 adımın kod imzalama kimliği kaybolur: evrensel çerçeve ikili "hiç imzalanmaz", ancak "Tüketici umursamadığı" için bu iyidir.
  4. Tüketiciye verir

Tüketici:

  1. Geliştiriciden iOS çerçevesi alır
  2. Çerçeveyi Çerçeveler / dizine kopyalar (bu adım, 3. adımdaki betiğe bağlı olarak gereksiz olabilir.)
  3. Derleme işleminin bir parçası olarak özel bir komut dosyası kullanır: Bu komut dosyası, iOS çerçevesini kesip çıkarır ve ardından bunu Tüketici adına yeniden kodlar.

10
Bu değerli bir yazı. Güzel bir
jackslash

@Stanislaw içgörüler ve değerli veriler için teşekkürler. Geliştiriciler için tasarladığım bir çerçeve yazarken, onların çerçeveyi olduğu gibi alabilmelerini ve uygulama mağazasına yüklemek için özel bir komut dosyası oluşturmaya gerek kalmadan kullanabilmelerini istiyorum. GoogleMobileAd'ın bu şekilde çalıştığını düşünüyorum. ama belirli bir komut dosyasını çalıştırmaları gerektiğini söylüyorsunuz? GoogleMobileAds'in bunu nasıl gerektirmediğine dair bir fikriniz var mı? teşekkürler
Michael A

@MichaelA, gerçekten bu ilginç. Bakacağım.
Stanislav Pankevich

Bana kullanmakta olduğunuz GoogleMobileAds bağlantısı verebilir misiniz?
Stanislav Pankevich

1
Zamanımı kurtardığın için teşekkürler, bu benim için çalıştı. Xcode 7.3, Mac OS X 10.11.4.
eugen

21

Kartaca repo'sundaki bağlantılı iş parçacığını okumak nispeten basit görünüyor. İkili çerçeveyi dağıtıyorsanız, imzalamayı kodlamanız gerekir ve kaynağı kartaj veya kakao kapsülleri aracılığıyla dağıtıyorsanız, bu araçlar bunu farklı yöntemlerle halledeceğinden, bunu yapmazsınız.

İkili çerçeveyi dağıtırken kod imzalamanız gerekmesinin nedeni, Xcode'un kod imzalamadan bir çerçeve ikili dosyası üretmemesidir. İkili çerçeveyi kod imzalamamaya çalışırsanız şu hatayı alırsınız:

CodeSign error: code signing is required for product type 'Framework' in SDK 'iOS 8.1'

Çerçeveyi hangi kimlikle imzaladığınız önemli değildir (iPhone Geliştiricisi veya iPhone Dağıtımı), çünkü sizin de belirttiğiniz gibi çerçeve "kopyada kod işareti" ayarıyla yeniden kodlanacaktır. Bu, çerçeveniz uygulamalarına kopyalandığında, çerçevenizin, çerçeve tüketicisinin geliştirici profilinden uygun sertifika tarafından yeniden kodlanacağı anlamına gelir. Bu, yalnızca çerçeve tüketicisinden gelen son kod imzasını göreceğinden, App Store'da herhangi bir sorun olmayacağı anlamına gelir.

Günün sonunda, egzotik bir derleme sürecini sürdürmek zorunda kalmayacağınız için .framework ikili dosyanızı kodla imzalayabilirsiniz ve Xcode yalnızca imzalı çerçeveler çıkaracağından, varsayılanlar. Zaten önemli değil çünkü son tüketici onu yeniden imzalayacak.


Cevabınızda, ikinci paragrafında, kod imzalamaya gerek olmadığını, çünkü tüketici tarafından yeniden kodlanacağını söylüyorsunuz ve şimdi bunun doğru olduğundan% 95 eminim, ama anlamıyorum neden aynı zamanda ilk paragrafta şunu söylüyorsunuz: "İkili çerçeveyi dağıtıyorsanız, onu kod imzalamanız gerekir" - fark nedir - eğer ikili çerçeveyi dağıtırsam (yani kaynağını carthage veya cocoapod'lar aracılığıyla değil) neden Kod imzalamam gerekir mi?
Stanislav Pankevich

Kullandığım dağıtım türü ne olursa olsun çerçevemi kodlamamalıyım (sıkıştırılmış .framework dosyası veya carthage veya cocoapods). Örnekler: Aşağıdaki ikili çerçeve dağıtımlarının tümü kod imzalanmamıştır : Realm , ReactiveCocoa , OCMockito .
Stanislav Pankevich

Bu yüzden, cevabınızın geri kalanıyla (imho) çelişen "İkili çerçeveyi dağıtıyorsanız, onu kod imzalamanız gerekir" ile biraz kafam karıştı. Lütfen açıkla. Ayrıca bu ödülü "Güvenilir ve / veya resmi kaynaklardan gelen bir cevap aranıyor" olarak açtığımı lütfen unutmayın.
Stanislav Pankevich

1
Evet, Realm ve OCMockito'ya da baktım. Realm "iPhone Developer" kimliklerine sahip ve evet, OCMockito statik bir kitaplık. Sanırım sorunu anlıyorum - kod imzalı iphoneos ve kod imzasız iphonesimulator'ü birleştirdiğinde iphoneos'tan kod imzalamayı kaldıran lipo'dur.
Stanislav Pankevich

1
çerçevenizi dağıtırken bir sorum var, bir hata ayıklama derlemesi veya sürüm derlemesi dağıtıyorsunuz? ve bunu sürüm yapısında dağıtırsanız, bunu nasıl yapacaksınız?
niczm25
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.