why CocoasPod increase IPA size? how to reduce the size? - ios

CocoasPod is good, But sometimes it's not.
Why? Because there is a flag call "-ObjC" in your project.
It will pull ALL OBJECT FILES into your resulting binary.
For example, an empty project with "pod 'AFNetworking'" and the flag "-ObjC" is on, that will cause the binary will be 7MB. 7MB for an empty project, that's suck.
Some frameworks like Google Map SDK need the flag "-ObjC" is on.
So, if your project with "AFNetworking pod" and "Google Map SDK", it will cause the binary will be 17MB.
So my question is:
How can I turn off the "-ObjC" flag for special Library?
For example, just keep the "-ObjC" for Google Map SDK, but turn it off on AFNetworking.

You should try the answer to this question so as to reduce the .ipa size.
In general, adding a static library to your project in Objective-C
will pull ALL OBJECT FILES into your resulting binary because cocoa
pods installation adds -ObjC flag to your linker settings, and as
stated in linker manual:
-ObjC Loads all members of static archive libraries that implement
an Objective-C class or category.
This flag included to solve problem with linking categories, because
by default linker will not include object files containing only
categories into resulting binary.

Related

Linker error comes when implement Creative SDK for Image Effects in ios

I want to implement image effects in my project.
So I am trying to implement CREATIVE SDK for this image effects.
https://creativesdk.adobe.com/docs/ios/#/articles/imageeditor/index.html
I have completed all steps which is mentioned in this above document. Also, I have take care of Other Linker Flags, Frameworks, Path of Frameworks and all other thigs.
But Still Getting Linker error.
Look forward to hearing your responses!
Ensure that in project target - on your MAC/ Local Device folder, the required files are there.
The problem you are facing is that Xcode is unable to link the _AdobeAuthManagerLoggedOutNotification.
Also make ensure that step 3, 4 are exclusively taken care of during installation.
Copy resources
Make sure AdobeCreativeSDKImageResources.bundle is included in your target's "Copy Bundle Resources" build phase.
Add linker flags
Update your target's (or project's) build settings to include the following "Other Linker Flags":
-ObjC
-all_load
the order in step 4 is really important.

Can the -ObjC flag be applied selectively to static libraries?

TL;DR
How can I make the -ObjC linker flag target a specific static library and not all the static libraries I am linking against in order to avoid unused object files being linked in with my app?
Too Long; Did Read
So you are developing a new iOS app and you add in your homegrown "objcutil" static library which contains a variety of useful Objective-C classes (not implemented as categories) to do various things that have been useful in the past. So far, so good, and only those object files that are being referenced in the utility library are being linked with the app.
Then you decide to integrate the Google Maps SDK which wants you to use the -ObjC Other Linker Flags and all of a sudden dependencies in the utility library fail to be resolved, because you haven't configured Xcode to link to those libraries.
OK I can resolve the missing dependencies easily enough, however you now have unused object files and library dependencies that you don't need and you'd like to be a bit tidier than that.
So how do you avoid OCD overload?
Some reference from the ld manpage:
-ObjC Loads all members of static archive libraries that define an Objective C class or a category. This option does not apply to dynamic
shared libraries.
Xcode Version: 5.1.1
OSX Version: 10.9.4
OK so the answer is to use -force_load instead of -ObjC as -force_load is more focused.
So WRT to the Google Maps SDK, if you followed the instructions and copied the static framework into the app project directory, then the framework will be in the project root directory and you can remove -ObjC from the Other Linker Flags and replace it with
-force_load GoogleMaps.framework/Versions/Current/GoogleMaps:
Nothing else needs changing.
For other libraries you will need to use the full static library path as the argument to -force_load.

Linker flags for iOS with Xcode

Where can I find documentation on the compiler flags and linker flags that we can specify for our iOS projects in Xcode?
The present reason I want to read more on the possible flags in the first place is that the Google Admob SDK says we MUST set the linker -Objc flag, whereas Facebook SDK suggests NOT setting it for smaller binaries. So, I was wondering, can we set Objc for a particular library (google admob in this case) and have it unset for another library (facebook)? I expected to be able to find a man page or some other doc about what the compiler and linker options are in the first place, and then zoom in on Objc. There's tons of documentation and stackoverflow posts etc. on how to set linker flags in Xcode. What's lacking is a listing of possible linker flags we can set, and what they each mean.
Surprisingly, googling around made me quite confused, as there's stuff on clang, llvm, llvm-gcc, etc., and LLVM site lists a number of llvm commands but I don't see -Objc listed in any of the corresponding pages. Apart from the question of whether the compiler and linker are clang or llvm, or whatever they're called, is there a place we could go to in order to read documentation on whatever Xcode is currently using by default for compiling and linking iOS projects? (say, both Xcode 4.6 and Xcode 5.0.2, in case there are different doc sets?) Thanks!
You can try man 1 ld.
For the -ObjC flag in particular the description is:
-ObjC Loads all members of static archive libraries that
implement an Objective-C class or category.
EDIT
For your other question about the AdMob SDK and the Facebook SDK, I would suggest to add the -ObjC to the linker flags and take a look at this article which explains why. Basically Facebook suggests not to use it, because your executable will end up being larger due to additional object code loaded into your binary.
I had this problem when I put a function into my .hpp file.
void logError(char const* szError)
{
...
}
I had to add in the inline to make it work.
inline void logError(char const* szError)
{
...
}
Even better don't define your functions inside your headers.

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.

Is there a better way to link to a configuration specific static lib on iOS than OTHER_LINKER_FLAGS?

Situation: Linking against an SDK (which I'm building) that has Release, Debug, & Distribution versions of it's static library (.a file). There doesn't seem to be a way in Xcode GUI to indicate that a static library is only used for a given Configuration.
I can use "Other Linker Flags" (OTHER_LDFLAGS) in the Build pane of the target or project settings like this:
-all_load -ObjC "${SRCROOT}/MySDKFolder/${CONFIGURATION}-universal/libMYsdk.a"
which seems to work. Just wondering if anyone knows a better way. ( the -all_load and -ObjC are to get ObjC categories linked in properly).
I'm using gcc 4.2 at this point (SDK default for 4.3 sdk and 3.x.x Xcode).
So, it turns out I was letting the Xcode UI confuse me. If you add the generic search path with the ${CONFIGURATION} variables and then add one of the static library instances to the project and target it'll do the right thing and link with the right one even though if you get info on that library in the project it'll show you the specific path.
However, if you want it to actually have Xcode notice changes made to one of the static libraries, you'll need to add ALL versions of your static library to the project and target (yes, it'll look like it's linking with all three, no worries!).
To have Xcode detect the the .a file changed as the result of a build script phase you have to actually have all the source files that are used to build the .a file in the Run Script Input pane (a pain!) to not have to run your build script every time; And all three variants of the .a file in the output pane so Xcode knows what to check after your script runs to see if it needs to relink the project.

Resources