Creating the iOS / OSX Framework: Do they need to be coded before being distributed to other developers?

I am learning how to create iOS and OSX frameworks. For example, take iOS, the following steps work for me:

  • xcodebuild framework using -sdk iphonesimulator and build action
  • xcodebuild framework using -sdk iphoneos and build action
  • Use the lipo tool to create a universal binary so lipo -info :

Architecture in the fat file: Foo.framework / Foo: i386 x86_64 armv7 arm64

Questions:

  • I read that my frameworks can be re-signed by the developer who uses it: "Code Sign on Copy", but I don’t understand what are the prerequisites for it, i.e. should I add code with code that encodes that universal binary with my signature identifier before distributing it to other developers?

  • if the previous one is positive - should I use the identifier "iPhone Distribution: ..." or "iPhone Developer: ..." enough (so that my infrastructure is part of any iOS project, all kinds of validations pass, especially checks in the App Store) ?

The background for my answer is “CodeSign error: code signing is required for the product type“ Framework ”in the iOS 8.3 SDK, which I saw in a number of third-party frameworks and Carthage # 235 or“ the code object is not signed at all ”(one example: problem that I reported in Realm # 1998 .

Therefore, I want to be sure that users of my frameworks will not encounter problems with code names when using them.

PS This question becomes even more interesting when it is applied not to one developer, but to an organization that is an infrastructure provider.

+53
ios code-signing ios-frameworks
Jun 21 '15 at 10:02
source share
2 answers

I discovered generosity: "Looking for an answer made up of reliable and / or official sources." but since then they haven’t received them.

While the answer provided by @jackslash is correct, it tells only part of the story, so I want to write my own so that I can see it at the moment I asked this question.

Validity of this answer: July 2015. Most likely, everything will change.

First of all, let it be argued that the steps necessary to properly sign the framework code should be divided into steps within which the developer must take steps that the user environment must take.

TL; DR;

For the OSX platform: The developer is free to distribute the OSX platform without coordination, as the consumer will rewrite it anyway.

For the iOS platform: The developer can freely distribute the iOS infrastructure without coordination, because the consumer will rewrite it anyway, but the developer is forced to Xcode to encode his structure when creating them for the iOS device.

Because of the radar: “iOS frames containing slices of the simulator cannot be sent to the App Store.” The consumer of the iOS infrastructure is forced to run special scripts like “copy_frameworks” or “strip_frameworks”, which uses lipo -remove to remove slices of the simulator from the iOS infrastructure and transcodes the shared framework, because at that moment its identification of codes, regardless of whether it was (or was not), is deleted as a side effect of lipo -remove .

The following is a longer answer.




This answer is not an “extract from reliable and / or official sources,” but rather is based on a number of empirical observations.

Empirical observation No. 1: the consumer does not care, because they will recode the structure that they receive from the developer

Binary wireframes of well-known open source projects on Github are not codes . The codesign -d -vvvv gives: "the code object is not signed at all" on all the iOS and OSX binary systems that I used to study. Some examples: ReactiveCocoa and Mantle , Realm , PromiseKit .

From this observation, it is clear that the authors of these frameworks assume that they will be coordinated by the consumer on their behalf, that is, the consumer should use the "Code Sign on Copy" flag in the "Built-in frameworks" construction phase provided by Xcode, or use some custom shell script. which does the same thing manually: the code structure for the username.

I have not found a single example of the opposite: open source frameworks that would be distributed with the identification of the code in it, so in the rest of the answer I assume that this widely accepted approach is correct: there is no need for the Developer platform to distribute its frameworks other developers with code identification in it, because the consumer will still recode it .

Empirical observation No. 2, which applies only to iOS and which is fully related to developers

While it doesn't matter to the Consumer whether the framework they get from the Developer is code or not, the developer still needs to code his iOS infrastructure as part of his build process when they create it for the iOS device , because otherwise Xcode not created: CodeSign error: code signing is required for product type 'Framework' in SDK 'iOS 8.1' . To quote Justin Spahr-Summers :

OS X frameworks do not have to be coded in build ... Unfortunately, Xcode does require that the iOS framework be coordinated at build time.

This answers my question # 2 pretty well: “iPhone Developer ID” is enough to convince Xcode to build the iOS infrastructure for the device. This commentary on Carthage No. 339 says the same thing.

Empirical observation No. 3: lipo-tool

The specific behavior of the lipo-tool: when applied to a binary file structure, it always recursively removes any code identifiers from it. : lipo -create/-remove codesigned framework ... -> not codesigned framework .

This may be the answer why all the examples in observation No. 1 are not code at all: their identification of the code unit is reset after applying lipo, but since according to observation No. 1 the consumer does not care that this is normal.

This observation is especially relevant for the next observation No. 4 about the AppStore.

Empirical observation # 4: iOS frames containing slices of a simulator cannot be sent to the App Store

This is widely discussed in: Realm # 1163 and Carthage # 188 and the radar is open: rdar: // 19209161 .

This is completely consumer concern. For the universal iOS infrastructure that Consumer uses in their application, when the application is created, they must run a special script (custom Run script Phase) that removes the simulator fragment from this binary framework file, this application can pass the AppStore check.

A good example for binary frameworks that I found in Realm: strip-frameworks.sh .

It uses lipo to remove all slices of architectures other than ${VALID_ARCHS} , and then transcodes it with the consumer ID - here there is a substitution # 3: framework-encoded due to manipulations with lipo on it.

Carthage has a CopyFrameworks.swift script that does the same for all the frameworks included in Consumer: it removes simulator fragments and re-codesigns framework on behalf of the consumer.

There's also a good article: Removing Unwanted Architectures from Dynamic Libraries in Xcode .




Now consider the steps necessary to create both iOS and OSX from the point of view of the developer and the consumer. Simpler at first:

OSX

Developer:

  • Creates an OSX infrastructure
  • Provides it to the consumer

No code operations are required from the developer.

Consumer:

  • Gets the OSX infrastructure from the developer
  • It copies the framework to Frameworks / directory and codesigns automatically on its own, Consumers, on behalf of as part of the "Copy Signature" process.

IOS

Developer:

  • Creates an iOS infrastructure for the device. The code is required for Xcode, enough to identify iPhone Developer.
  • Creates iOS infrastructure for the simulator.
  • Uses lipo, which creates a universal iOS infrastructure from the previous two. At this stage, the code ID of the 1st step is lost: the universal binary structure is "not signed at all," but this is normal, because "The consumer does not care."
  • Provides it to the consumer

Consumer:

  • Gets iOS infrastructure from the developer
  • Copying the frame into the Frameworks / directory (this step may be redundant depending on what the script is in step 3).
  • Uses a special script as part of the build process: this script layer of the simulator divides the iOS structure, and then transcodes it to its users, on behalf of the user.
+86
Jun 29 '15 at
source share

From reading a related topic in the Carthage repository it seems relatively simple. If you distribute the binary structure, you need to sign its code, and if you distribute the source code through carthage or cocoa pods, you do not execute these tools using different methods.

The reason you need to sign code when you distribute the binary structure is because Xcode will not create the binary code of the framework without signing it. If you try not to encode the binary structure character, you will get this error:

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

It doesn’t matter which identifier you sign under the framework (iPhone Developer or iPhone Distribution), because, as you have noticed, the structure will be transcoded with the setting “code mark when copying”. This means that your infrastructure will be transcoded with the appropriate certificate from the infrastructure user profile profile when your infrastructure is copied to their application. This means that there will be no problems in the App Store, since it will only see the final signature of the code from the infrastructure user.

At the end of the day, you can also enter the code in your binary .framework file, since you do not want to support the exotic assembly process, and since Xcode will only display signed frames, you should not move too far from the default values. In any case, it does not really matter, because the end user will rewrite it.

+15
Jun 23 '15 at 10:41
source share



All Articles