Problems with dependencies of Simperium - simperium

I am evaluating to move a project to Simperium for synchronization. The project already uses CocoaHTTPServer, ASIHTTPRequest and some other frameworks.
Now Simperium also seems to contain (at least parts of) of these frameworks. Removing the CocoaHTTPServer framework from my projects linking phase, I got undefined symbols linker errors regarding these symbols: HTTPAsyncFileResponse, HTTPFileResponse, HTTPDataResponse, HTTPServer, HTTPDataResponse, HTTPConnection.
Is it possible to fix these linker errors with the current framework version?
Or would it be possible to provide a framework with these frameworks as external, dependant frameworks, so I can use my own versions?

This is equivalent to Linker errors building iOS app with Simperium, which has a suggested workaround while a proper fix is implemented. The proper fix should be ready soon.

Related

Does bitcode support weak linking third party frameworks?

Question stated simply in title. Here is my setup:
Building a dynamic framework that optionally links (weak link) to GoogleInteractiveMediaAds.framework. For apps that use my framework, GoogleInteractiveMediaAds is an optional dependency, and the framework will work fine without it. This is currently working.
However the problem arises when attempting to rebuild from bitcode, as typically happens when exporting an Ad Hoc build with "Rebuild from Bitcode" selected. The bitcode compile process fails with:
ipatool failed with an exception: #<CmdSpec::NonZeroExitException: $/Applications/Xcode.app/Contents/Developer/usr/bin/bitcode-build-tool ...
And looking deeper into the log file I find the error description:
Failed to resolve linkage dependency MyFramework arm64 -> #rpath/GoogleInteractiveMediaAds.framework/GoogleInteractiveMediaAds: Could not resolve #rpath in #rpath/GoogleInteractiveMediaAds.framework/GoogleInteractiveMediaAds from MyFramework
error: GoogleInteractiveMediaAds not found in dylib search path
Note: GoogleInteractiveMediaAds.framework does include bitcode.
Obviously this error is avoiding by not selecting "Rebuild from Bitcode". If I were to answer my own question, I'd say, no, it looks like when compiling from bitcode, you cannot use weakly linked frameworks. Simply from the fact that the bitcode compilation step is trying to link to a framework which isn't included in the app target. However I haven't been able to find any official documentation surround using weak linking with bitcode, or any relevant StackOverflow answers about it, so I'm not sure if I'm missing something or if there is some relevant compiler/linker settings that I am missing to get this to work.
In your case, you will need to wait for the fix in framework itself.
We've got similar issue while distributing our framework, which I described here and I just wan't to share results of our investigation, because seems that no-one has published their results.
No needs to distribute without bitcode. Long story short, there were LLVM instrumentation included, which prevents AppStore processing. I've written a whole blog about XCode 12 and BigSur issues with XCFramework.
To sum up, here is a few required steps to make sure while creating XCFramework for distribution:
Using archive builds is a MUST, release build isn't enough
BUILD_LIBRARY_FOR_DISTRIBUTION must be set to YES
SKIP_INSTALL must be set to NO
GCC_INSTRUMENT_PROGRAM_FLOW_ARCS = NO to turn off GCC instrumentation and remove them from the binary
CLANG_ENABLE_CODE_COVERAGE = NO to turn off code coverage tools from the binary
Having all of the above helped to solve our preparing and distribution problem and hopefully save you some time if you happened to face same issues as we did.

Xcode 8 : Disabling bitcode and Umbrella frameworks

I'm currently building an Umbrella framework (before anyone say so, I know this is discouraged by Apple, but I am in the case were I'm the owner of all the sub-frameworks, they are not distributed if they are not part of this or another Umbrella framework I may create, and we are in a closed source configuration) within Xcode 8.
I've followed this post to create the framework: https://stackoverflow.com/a/41815368/2572568
Everything is working fine except that I got the following error:
dyld: Library not loaded: #rpath/B.framework/B
Referenced from: /private/var/containers/Bundle/Application/E0113060-CA91-47F8-BEE3-BDF1F847DB3A/app.app/Frameworks/A.framework/A
Reason: no suitable image found. Did find:
/private/var/containers/Bundle/Application/E0113060-CA91-47F8-BEE3-BDF1F847DB3A/app.app/Frameworks/A.framework/Frameworks/B.framework/B: required code signature missing for '/private/var/containers/Bundle/Application/E0113060-CA91-47F8-BEE3-BDF1F847DB3A/app.app/Frameworks/A.framework/Frameworks/B.framework/B'
app is the Application using the Umbrella framework A which has a sub-framework B
I found that disabling bitcode from all the projects is solving this issue (and that's what I am doing now) from this thread : https://github.com/CocoaPods/CocoaPods/issues/3661
So here are my questions:
What does disabling bitcode is exactly doing ? I found that Apple can run optimization after you submitted your code. Are these speed optimization or disk space optimization, or any other optimization ?
Am I doing something wrong building my Umbrella framework ? Is it possible not to disable bitcode ?
First of all:
I came into the exact same problem today and I couldn't fix it. But removing Bitcode fixt it for me. Thanks for that
To your questions:
Bitcode is something kind of similar to Java's Bytecode. Your app gets compiled completely, but not in machine code (like assembler). Your app is compiled to Bitcode. This helps Apple to build different versions of your app on their server. One for 64bit and one for 32bit devices. Then they separate both apps, which saves disk space on the actual device.
And they probably have some further optimisations, which could speed up the app. Generally it's not needed today.
I tried almost everything I could imagine and at the moment I would say: No it's not possible to disable bitcode, if you have a big umbrella framework. Can you check if you have sub-frameworks in your umbrella framework which do not support Bitcode ? Like AWS SDK, Facebook SDK...
It may be possible to support Bitcode if all sub-frameworks support Bitcode. This answer seems promising me, but it's a bit old: https://stackoverflow.com/a/27638841/1203713
Regards,
Alex
Ok so after a few more researches on completely unrelated questions, I found this thread : https://github.com/Carthage/Carthage/issues/535
In substance, this solve question 2 and another one : Yes, you can enable bitcode for your Umbrella framework.
To do so, you must manually set a User-defined setting (inside Build settings, click on the plus in the top bar) named BITCODE_GENERATION_MODE to bitcode. This will force Xcode to build you project with real bitcode and not only a bitcode subset.
You have to set this flag for all the frameworks under your Umbrella framework.

Xcode -" ld: framework not found" happening on a framework not included directly

A bit of story:
I created a framework called, Notifications, that allows our iOS applications to use one of our new backend service. I created the framework in Swift, and included it in our main application which is written in Obj-C. This was working great until one of my colleauges updated the main application to allow us use Swift in the main application.
I am now getting the following error:
ld: framework not found ISO8601 for architecture x86_64
This is a rather interesting error as the Notifications framework uses ISO8601, and it is included in the Notifications framework. The main application does not reference this framework at all.
Yes, I did check to make sure ISO8601 has has the x86_64 architecture, and all included frameworks, and the Notifications framework also has all the required architectures.
I looked at the build settings and they appear to be all in line with building the project as expected.
For me the only difference appears to be enabling Swift in the main app. I have cleaned, deleted derived data, and various build settings trying to get it working.
Any thoughts or ideas for fixes would be greatly appreciated.

How can code using a framework class run without the framework?

I'm running an app that uses EAAccessoryManager, which should only be available via the ExternalAccessory framework. Yet it compiles and runs without ExternalAccessory being included in the list of frameworks to link. Nor is it loaded into Xcode by any other targets. How is this possible? I'm mystified.
I'm curious because I have another project that loads a static library that also references EAAccessoryManager, and in that case, the app won't compile, exiting with the error Undefined symbols for architecture i386. This is more what I expect. What can account for the difference?
Could be a linker build setting rather than a link build phase.
In Build Settings, in the “Apple LLVM 5.1 – Languages – Modules” section, “Link Frameworks Automatically” is enabled:
This is a new feature I never noticed before discovered while reading this post on #import (thanks #RhythmicFistman for the hint!). When I change that setting to “No”, I get the linker errors I expect.

RestKit in a Workspace

I have a workspace set up in Xcode. It contains a number of static library projects that I link to in my main project.
The process of linking to these projects is much longer than it should be. But the key for me in getting this to work was removing the -ObjC linker flag from my build settings. This kept me from getting duplicate files when I used a library in more than one place.
But this gave me a problem when trying to include RestKit in my project, because the documentation says that the -ObjC linker flag is necessary, which I have found to be the case.
Is there a way of including RestKit in a workspace like this and linking to it like any other static library? Without having to use the -ObjC linker flag?
If you are planning to target your app for IOS 5 and above then you can try using the built-in NSURLConnection along with NSJSONSerialization class (If you return JSON response) for the purpose.

Resources