Tạo các khung công tác iOS / OSX: có cần thiết phải ký mã chúng trước khi phân phối cho các nhà phát triển khác không?


90

Tôi đang học cách tạo các khuôn khổ iOS và OSX. Hãy lấy iOS làm ví dụ, các bước sau đây phù hợp với tôi cho đến nay:

  1. xcodebuild framework sử dụng -sdk iphonesimulator và Build action
  2. xcodebuild framework sử dụng -sdk iphoneos và Build action
  3. Sử dụng công cụ lipo để tạo nhị phân phổ quát để lipo -infotạo ra dự kiến:

Các kiến ​​trúc trong tệp béo: Foo.framework / Foo là: i386 x86_64 armv7 arm64

Các câu hỏi là:

  1. Tôi đọc rằng khung của tôi có thể được ký lại bởi nhà phát triển đang sử dụng nó: "Code Sign on Copy" nhưng tôi không hiểu điều kiện tiên quyết cho nó là gì, tức là tôi có nên thêm bước thiết kế mã để ký mã nhị phân phổ quát đó với danh tính ký của tôi trước đây không phân phối nó cho các nhà phát triển khác?

  2. nếu trước đó là tích cực - tôi có nên sử dụng danh tính "Phân phối iPhone: ..." hoặc "Nhà phát triển iPhone: ..." là đủ (để khuôn khổ của tôi là một phần của một số dự án iOS vượt qua tất cả các loại xác thực, đặc biệt là xác thực App Store )?

Cơ sở cho câu trả lời của tôi là "Lỗi CodeSign: bắt buộc phải ký mã cho loại sản phẩm 'Khung' trong SDK 'iOS 8.3'" mà tôi đã thấy trên một số khung của bên thứ ba và đối tượng mã Carthage # 235 hoặc "không được ký "(một ví dụ: sự cố tôi đã báo cáo trên Realm # 1998 .

Vì vậy, tôi muốn chắc chắn rằng người dùng các khung công tác của tôi sẽ không gặp phải bất kỳ vấn đề nào về thiết kế mã khi họ sử dụng chúng.

Tái bút Câu hỏi này thậm chí còn thú vị hơn khi không được áp dụng cho một nhà phát triển đơn lẻ mà cho một tổ chức là nhà cung cấp khung.


Nhận xét này đề xuất sử dụng 'CODE_SIGN_IDENTITY = Nhà phát triển iPhone' nhưng không rõ tại sao 'Nhà phát triển' được sử dụng thay vì 'Phân phối iPhone'.
Stanislav Pankevich

Chủ đề liên quan: Xuất ứng dụng với khung nhúng nhưng không có câu trả lời xác định.
Stanislav Pankevich

Tôi cũng đã đánh lừa câu hỏi này trên Diễn đàn nhà phát triển Apple: forum.developer.apple.com/thread/6400 .
Stanislav Pankevich

tôi có một câu hỏi khi bạn phân phối khuôn khổ của mình, bạn phân phối một bản dựng gỡ lỗi hay bản phát hành? và nếu bạn phân phối nó trong phiên bản phát hành, làm thế nào để làm điều này?
niczm25,

@ niczm25, đây là một trong những cách tôi thực hiện: stanislaw.github.io/2015/11/23/… .
Stanislav Pankevich

Câu trả lời:


137

Tôi mở tiền thưởng: "Tìm kiếm câu trả lời từ các nguồn đáng tin cậy và / hoặc chính thức." nhưng đã không nhận được như vậy kể từ đó.

Mặc dù câu trả lời được cung cấp bởi @jackslash là đúng, nhưng nó chỉ kể một phần của câu chuyện, vì vậy tôi muốn viết theo cách của riêng mình theo cách mà tôi muốn biết ngay tại thời điểm tôi đặt câu hỏi này.

Thực tế của câu trả lời này là: Tháng 7 năm 2015. Rất có thể mọi thứ sẽ thay đổi.

Trước hết, hãy khẳng định rằng các hành động cần thiết để ký mã chính xác của khuôn khổ phải được chia thành các bước mà Nhà phát triển của khuôn khổ phải thực hiệncác bước mà Người tiêu dùng của khuôn khổ đó phải thực hiện.

TLDR;

Đối với khung OSX: Nhà phát triển có thể tự do phân phối khung OSX mà không cần gán mã vì Người tiêu dùng sẽ ký mã lại.

Đối với khuôn khổ iOS: Nhà phát triển có thể tự do phân phối khuôn khổ iOS mà không cần gán mã vì Người tiêu dùng sẽ ký mã lại nó, nhưng Nhà phát triển bị Xcode buộc phải thiết kế khung của họ khi họ xây dựng cho thiết bị iOS.

Do radar: "Không thể gửi các khung công tác iOS chứa các lát trình mô phỏng đến App Store" Khung công tác Consumer of iOS buộc phải chạy tập lệnh đặc biệt như "copy_frameworks" hoặc "strip_frameworks", dùng lipo -removeđể loại bỏ các lát trình mô phỏng khỏi khuôn khổ iOS và tái -codesigns đã loại bỏ khung công tác bởi vì tại thời điểm này, mã xác định danh tính của nó bất kể nó là gì (hoặc không) bị loại bỏ như là tác dụng phụ của lipo -removethao tác.

Câu trả lời dài hơn sau đây.


Câu trả lời này không phải là "bản vẽ từ các nguồn đáng tin cậy và / hoặc chính thức" mà là dựa trên một số quan sát thực nghiệm.

Quan sát theo kinh nghiệm số 1: Người tiêu dùng không quan tâm vì họ sẽ thiết kế lại khuôn khổ thiết kế mã mà họ nhận được từ Nhà phát triển

Các bản phân phối khung nhị phân của các dự án nguồn mở nổi tiếng trên Github không được ký mã . Lệnh codesign -d -vvvvcung cấp: "đối tượng mã hoàn toàn không được ký" trên tất cả các khung nhị phân iOS và OSX mà tôi đã sử dụng để khám phá. Một số ví dụ: ReactiveCocoaMantle , Realm , PromiseKit .

Từ quan sát này, rõ ràng là các tác giả của các khuôn khổ này dự định chúng được ký mã bởi Người tiêu dùng, thay mặt cho họ, tức là Người tiêu dùng phải sử dụng cờ "Ký mã khi sao chép" trong giai đoạn xây dựng "Khuôn khổ nhúng" do Xcode cung cấp hoặc sử dụng một số trình bao tùy chỉnh script thực hiện điều tương tự theo cách thủ công: mã thiết kế khuôn khổ thay mặt Người tiêu dùng.

Tôi không tìm thấy bất kỳ ví dụ nào về điều ngược lại: khung mã nguồn mở sẽ được phân phối với mã định danh trong đó, vì vậy trong phần còn lại của câu trả lời, tôi giả định cách tiếp cận được áp dụng rộng rãi này là đúng: không cần khung Nhà phát triển phân phối khuôn khổ của họ cho các nhà phát triển khác có mã xác định danh tính trong đó vì Người tiêu dùng dù sao cũng sẽ ký mã lại nó .

Quan sát theo kinh nghiệm # 2 chỉ áp dụng cho iOS và hoàn toàn là mối quan tâm của Nhà phát triển

Trong khi người tiêu dùng không quan tâm cho dù khuôn khổ mà họ nhận được từ nhà phát triển được codesigned hay không, nhà phát triển vẫn cần codesign khuôn khổ iOS của họ như là một phần của quá trình xây dựng của mình khi họ xây dựng nó cho thiết bị iOS bởi vì nếu không Xcode không xây dựng: CodeSign error: code signing is required for product type 'Framework' in SDK 'iOS 8.1'. Để trích dẫn Justin Spahr-Summers :

Các khung OS X không cần phải được ký mã khi xây dựng ... Thật không may, Xcode yêu cầu các khung iOS phải được ký mã tại thời điểm xây dựng.

Câu trả lời khá tốt này cho câu hỏi số 2 của tôi: Danh tính "Nhà phát triển iPhone" đủ để tạo ra Xcode để nó xây dựng khung iOS cho thiết bị. Nhận xét này trên Carthage # 339 cũng nói điều tương tự.

Quan sát thực nghiệm # 3: Công cụ lipo

Hành vi cụ thể của công cụ lipo: khi áp dụng cho nhị phân khuôn khổ, nó luôn luôn đệ quy loại bỏ bất kỳ bản sắc codesign từ nó : lipo -create/-remove codesigned framework ... -> not codesigned framework.

Đây có thể là câu trả lời tại sao tất cả các ví dụ trong quan sát số 1 hoàn toàn không được ký mã: danh tính ký mã của chúng bị biến mất sau khi lipo được áp dụng nhưng vì theo quan sát số 1 Người tiêu dùng không quan tâm nên vẫn ổn.

Quan sát này đặc biệt liên quan đến quan sát số 4 tiếp theo về AppStore.

Quan sát thực nghiệm # 4: Không thể gửi các khung iOS chứa các lát trình mô phỏng lên App Store

Điều này được thảo luận rộng rãi trong: Realm # 1163Carthage # 188 và radar được mở: rdar: // 19209161 .

Đây hoàn toàn là mối quan tâm của Người tiêu dùng: đối với khung phổ quát iOS mà Người tiêu dùng đưa vào ứng dụng của họ, khi ứng dụng đang được xây dựng, họ phải chạy tập lệnh đặc biệt (Giai đoạn chạy tập lệnh tùy chỉnh) để loại bỏ phần mô phỏng khỏi hệ nhị phân của khung đó để ứng dụng có thể vượt qua xác thực AppStore.

Ví dụ tốt cho các khung nhị phân mà tôi tìm thấy trong Realm: strip-frameworks.sh .

Nó sử dụng lipođể loại bỏ tất cả các phần của kiến ​​trúc khác ${VALID_ARCHS}và sau đó mã hóa lại nó với danh tính của Người tiêu dùng - đây là nơi mà quan sát số 3 bắt đầu: khung công tác được thiết kế lại mã do các thao tác lipo trên đó.

Carthage có tập lệnh CopyFrameworks.swift thực hiện điều tương tự với tất cả các khung được Người tiêu dùng bao gồm: nó loại bỏ các lát trình mô phỏng và thay mặt Người tiêu dùng thiết kế lại khung mã.

Ngoài ra còn có bài viết hay: Tách các kiến ​​trúc không mong muốn khỏi các thư viện động trong Xcode .


Bây giờ là tổng quan về các bước cần thiết để sản xuất cả iOS và OSX từ quan điểm của cả Nhà phát triển và Người tiêu dùng. Đầu tiên cái dễ hơn:

OSX

Nhà phát triển:

  1. Xây dựng khung OSX
  2. Cung cấp cho người tiêu dùng

Không có hoạt động thiết kế mã nào được yêu cầu từ Nhà phát triển.

Khách hàng:

  1. Nhận khung OSX từ Nhà phát triển
  2. Sao chép khuôn khổ vào Khung công tác / thư mục và tự động gán mã đó cho Người tiêu dùng, thay mặt cho họ, như một phần của quy trình "Ký mã khi sao chép".

iOS

Nhà phát triển:

  1. Xây dựng khung iOS cho thiết bị. Xcode cần thiết lập mã, danh tính "Nhà phát triển iPhone" là đủ.
  2. Xây dựng khuôn khổ iOS cho trình mô phỏng.
  3. Sử dụng lipo tạo ra khung iOS phổ biến từ hai phiên bản trước. Tại thời điểm này, danh tính thiết kế mã của 1 bước bị mất: nhị phân khung phổ quát "hoàn toàn không được ký" nhưng điều đó vẫn ổn vì "Người tiêu dùng không quan tâm".
  4. Cung cấp cho người tiêu dùng

Khách hàng:

  1. Nhận khung iOS từ Nhà phát triển
  2. Sao chép khung công tác vào thư mục Khung / (bước này có thể thừa tùy thuộc vào tập lệnh trong bước 3 là gì.)
  3. Sử dụng tập lệnh đặc biệt như một phần của quá trình xây dựng: tập lệnh này tách trình mô phỏng tách khỏi khuôn khổ iOS và sau đó mã hóa lại nó thay mặt cho Người tiêu dùng.

9
Đây là một bài viết có giá trị. Nice one
jackslash

@Stanislaw cảm ơn vì những thông tin chi tiết và dữ liệu quý giá. Vì tôi đang viết một khung công tác do tôi tự thiết kế cho các nhà phát triển, tôi muốn họ có thể sử dụng khung công tác đó như hiện tại và sử dụng nó mà không cần tạo tập lệnh đặc biệt để tải lên cửa hàng ứng dụng. Tôi nghĩ GoogleMobileAd hoạt động theo cách đó. nhưng bạn nói rằng họ phải chạy một tập lệnh nào đó? bạn biết cách GoogleMobileAds không yêu cầu điều đó không? cảm ơn
Michael A

@MichaelA, quả thực là thú vị. Tôi sẽ nhìn.
Stanislav Pankevich

Bạn có thể cung cấp cho tôi liên kết đến GoogleMobileAds mà bạn đang sử dụng không?
Stanislav Pankevich,

1
Cảm ơn bạn đã tiết kiệm thời gian của tôi, điều đó đã làm việc cho tôi. Xcode 7.3, Mac OS X 10.11.4.
eugen

21

Từ việc đọc chuỗi liên kết trên repo Carthage, nó có vẻ tương đối đơn giản. Nếu bạn đang phân phối khung nhị phân, bạn cần phải ký mã vào nó và nếu bạn đang phân phối nguồn thông qua carthage hoặc quả ca cao thì bạn không thực hiện vì các công cụ đó xử lý việc này thông qua các phương pháp khác nhau.

Lý do bạn cần ký mã khi bạn phân phối khung nhị phân là Xcode sẽ không tạo ra tệp nhị phân khung mà không ký mã. Nếu bạn cố gắng không ký mã vào khung nhị phân, bạn sẽ gặp lỗi này:

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

Không quan trọng mã nhận dạng mà bạn ký vào khung (Nhà phát triển iPhone hoặc Phân phối iPhone) bởi vì, như bạn đã chỉ ra, khung sẽ được ký mã lại với cài đặt "ký mã khi sao chép". Điều này có nghĩa là khung của bạn sẽ được chứng chỉ thích hợp ký lại mã từ hồ sơ nhà phát triển của người tiêu dùng khung khi khung của bạn được sao chép vào ứng dụng của họ. Điều này có nghĩa là sẽ không có vấn đề gì với App Store vì nó sẽ chỉ thấy chữ ký mã cuối cùng từ người dùng khung.

Cuối cùng, bạn cũng có thể ký mã nhị phân .framework của mình vì bạn không muốn phải duy trì một quy trình xây dựng kỳ lạ và vì Xcode sẽ chỉ xuất ra các khung đã ký nên bạn không nên di chuyển quá xa khỏi mặc định. Dù sao thì điều đó cũng không thực sự quan trọng vì người tiêu dùng cuối cùng sẽ ký lại.


trong câu trả lời của bạn, trong đoạn thứ hai của nó, bạn đang nói rằng không cần phải thiết kế khung vì nó sẽ được người tiêu dùng thiết kế lại mã và bây giờ tôi cũng chắc chắn 95% điều đó là đúng, nhưng tôi không hiểu Tại sao đồng thời trong đoạn đầu tiên bạn lại nói: "Nếu bạn đang phân phối khung nhị phân, bạn cần ký mã vào nó" - sự khác biệt là gì - nếu tôi phân phối khung nhị phân (tức là không phải nguồn của nó thông qua carthage hoặc cocoapods) tại sao Tôi sẽ cần phải ký mã nó?
Stanislav Pankevich

Tôi nghĩ rằng tôi không nên thiết kế khuôn khổ của mình cho bất kỳ loại phân phối nào tôi sử dụng (tệp .framework được nén hoặc carthage hoặc cocoapods). Ví dụ: tất cả các bản phân phối khung nhị phân sau không được ký mã: Realm , ReactiveCocoa , OCMockito .
Stanislav Pankevich

Vì vậy, tôi hơi bối rối với câu "Nếu bạn đang phân phối khung nhị phân, bạn cần mã ký tên nó" (imho) mâu thuẫn với phần còn lại của câu trả lời của bạn. Vui lòng làm rõ. Cũng xin lưu ý rằng tôi đã mở tiền thưởng này là "Tìm kiếm câu trả lời từ các nguồn đáng tin cậy và / hoặc chính thức.".
Stanislav Pankevich

1
Vâng, tôi cũng đã xem xét Realm và OCMockito. Realm có danh tính "Nhà phát triển iPhone" và vâng, OCMockito là một thư viện tĩnh. Tôi nghĩ rằng tôi hiểu vấn đề - đó là lipo loại bỏ thiết kế mã khỏi iphoneos khi nó kết hợp iphoneos được mã hóa và iphonesimulator không được mã hóa.
Stanislav Pankevich

1
tôi có một câu hỏi khi bạn phân phối khuôn khổ của mình, bạn phân phối một bản dựng gỡ lỗi hay bản phát hành? và nếu bạn phân phối nó trong phiên bản phát hành, làm thế nào để làm điều này?
niczm25,

1

Câu trả lời trên của Stanislav Pankevich rất xác đáng và đúng đắn. Nhưng xin lưu ý rằng kể từ Xcode 9.4, IDE sẽ yêu cầu bạn tắt tính năng ký mã cho iOS Cocoa Touch Frameworks. Apple ở đây hiện nói rằng bạn không nên ký mã .framework của mình.

Tôi hi vọng cái này giúp được.


1
Bạn có nguồn nào để Apple khuyến nghị không nên ký các khuôn khổ không?
Rick
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.