how obfuscation android app Bundle works? - sharedpreferences

devs , I know that Obfuscation is about renames the remaining classes, fields, and methods using short meaningless names . ...
is there any difference between Obfuscation a bundle (.aab) and Obfuscation an apk (.apk) ?

Related

CMake - how to properly handle dependencies between executables?

I'm trying to setup a project that would consist of two executables: the actual application app and a test application test (i.e. executable that runs unit tests).
Obviously, test depends on functions/classes defined in app, meaning that correct build order has to be ensured. What is more however, app has a few external dependencies of its own, e.g. boost, which makes test transitively dependent on them as well.
What is the most idiomatic way of resolving these dependencies?
Two approaches I tried are:
Make an intermediate app_lib library target, consisting of all source files except main.cpp, then link both executables against it (target_link_libraries(test PRIVATE app_lib)).
Set ENABLE_EXPORTS property on app target, allowing test to link against it directly (target_link_libraries(test PRIVATE app)).
While both of these approaches work, they both seem quite hacky. The latter feels a tad better but if I understand it correctly, it was originally meant to enable plugin development, hence the "hacky" feeling.
To reiterate - what would be the correct way of setting up such project? Are these two the only possible solutions or there is another, better one?

How to manage the code of multiple, very similar Xcode projects

Greetings Stackoverflow Community,
I have taken on the task of 'unifying' 4 mobile iPhone apps that share 95% of the code and differ only in 5% (this is somewhat of an over-simplification, but never mind). Each of the apps has its own hefty set of resources (media files).
After 'unifying' the 4 apps, I will be adding new functionality to the apps, mostly functionality that the apps will share.
I would appreciate hearing your opinions on what's the best way to manage the code of these apps. Here is the approach I'm taking at the moment.
I'm maintaining only one Xcode project which includes the functionality of all 4 apps. The functionality that is not shared among all apps is enclosed in a condition such as: if (appName == 'X')...
Each app has its own info.plist file, so I have 4 of such files: infoX.plist, infoY.plist, ...
Before I build an app, two things are done:
a. in the Build Settings, I specify the name of info.plist to use.
b. I ensure that only the app's resources (media files) are in the project. I delete the other apps' resources.
As the apps are 95% similar in their code, having only "One App to Rule Them All" ensures that when the code gets upgraded, all apps enjoy the upgrade. You can assume that the apps will remain very similar in their code.
As the apps' media files are large and many, I'm keeping them off the Git repository.
How does this all sound?
Many thanks!
There are better ways:
A. Move to framework
It depends on how generic are common parts of the apps. But you should think about putting parts of it in a separate project that is a framework. You can link your 4 apps against that framework. But, of course, not everything will go there.
B. Have different targets
For sure you should have 4 different targets. Xcode let you set build settings for each setting commonly per project or specially per target. Additionally you can customize the build phases (including copy of the media files) on a per target base. So you do not have to rename or delete and insert anything. You simply select a target, you want to build.
C. Project tree
Xcode allows you to have subprojects with common code. Maybe things like common "foundation" classes of your app. You can have different projects for each app in a single workspace, all using the subproject.
Probably the best way is a combination, depending on what is the subject. However I would start with B. and likely add the other techniques, if needed.
I encountered more or less the same case, and we decided to use one Xcode project with multiple targets. That way you can simply change the target before hitting the build button (or configure specific build scripts changing the target). In our project, we had a few files sharing the same names (in different folders), and associated each one with a different target. For example, we had three "Stylesheet.h/.m" with different UIColor & UIFont definitions stored in different folders, and each one of them was linked to a different target. Same thing for the "Localizable.strings".

Build Multiple iOS Apps out of a Framework

I have a project where I need to build some apps out of one Basic App.
For "Sub-Apps" it changes the API-Credentials, Fonts, Sizes, Colors and some features of the App.
So I changed my App that I can easily add features, change colors, ... by changing simple String constants to build new Apps faster.
I thought that the best solution would be to add multiple Targets to this XCode Project and set the individual Settings of the App with Conditional Compiler flags
#ifdef AppTarget1
qr_reader = YES;
#endif
But the Problem is, that in future will be available multiple versions of the Framework. So when updating an App based on a old Framework we always had to do the adjustments to work with the new Version of the framework (if any) and we've no control over the Framework Versions, ect.
One goal is also to allow our Developers with a Simple Podfile build new Apps easily.
So the next idea was to create a Framework Project, what then is included with CocoaPods in our Main Apps. I followed this tutorial: http://chariotsolutions.com/blog/post/using-cocoapods-to-manage-private-libraries/
In the MainApp I included the Framework, the MainApp-AppDelegate Class is a Subclass of the Framework-AppDelegate Class.
#interface MainApp_AppDelegate : FrameworkAppDelegate
The Method where I set all the App-Based Settings I overwrite in the MainApp_AppDelegate.
#implementation MainApp_AppDelegate
-(void)initSettings {
qr_reader = YES;
}
#end
It worked like a charm, but one Problem I've with images. The AppFramework contains Image training.png and image y.png.
In the Main App xyz I decide that the Image training.png looks not good for this App, so I want to change only that (y.png I want the version included in the Framework). I put the x.png into the Main App Ressources Folder, but after compiling and Running there I see the Image included in the AppFramework Project.
Are there any ways to change that behaviour or better ways to create a Framework?
What is happening is Cocoapods copies its resources in the final .app bundle after your app is done copying his. So your training.jpg gets overwritten by your framework's.
Build phases order
As #masam said, you need to reorder the build phases of your project in order to copy your app's resources after Cocoapods' resources.
(Notice how "Copy Bundle Resources" is now under "Copy Pods Resources" in the list)
Force resources copy
Unfortunately, this will not be sufficient, as Xcode's build system is (tries to be?) smart and will not copy (or recompile in the case of a source file) a target which is "up-to-date". For a static resource like an image, being up-to-date means that the target path (in the final .app bundle) is newer than the source path (in you Xcode project).
So if you try to run your app now, you will notice no change. Xcode won't copy the training.jpg as it is already present and newer in the .app.
You will need to trick Xcode into thinking that the resources in the .app are outdated and needs to be updated. To do this, add a new "Run Script Build Phase" between "Copy Pods Resources" and "Copy Bundle Resources":
The script should set the modification date of the resources to an earlier date, to force Xcode to copy your app's resources. touch does the job:
find ${TARGET_BUILD_DIR} -name 'training.jpg' -exec touch -ct $(date -v-1d "+%Y%m%d%H%M.%S") {} \;
We use date -v-1d "+%Y%m%d%H%M.%S" to set the resource's modification date to yesterday.
Xcode will now overwrite the framework's image with the app's one.
Manage the targets resources
Again, as #masam said, don't forget to add the resource only to correct targets.
eg.
Here, the app image will be used in DummyApp, but DummyApp2 will use the framework image.
Conclusion
tl;dr: Avoid this if possible.
For a newcomer on your project, this is impossible at first glance to know why some targets build with one file and not the other;
Depending on the kind of resources of the framework you want to override, you will probably need to maintain the "Reset Resources Modification Time" script (probably by making find more inclusive, eg. find ${TARGET_BUILD_DIR} -name '*.png');
More of a subjective opinion: I'd recommend against hiding resources from the framework with your owns.
On the one-target-per-app-flavor thingy:
Remember that each modification you make on one target's Build Phases will NOT impact other targets Build Phases. You'll need to edit every targets individually. Hence my previous don't do it if you can avoid it.
I perfectly understand the need to have multiple targets to build multiples apps based on the same codebase, but Xcode is horribly bad at managing a large number of targets. Take it from a guy currently working on an fairly large app (1k+ files, and a lot of dependencies) with 65 different targets: this is a nightmare.
The .pbxproj will basically grow in factor of your number of targets (25MB in my case), and you'll get the beach ball each time a project modification in done in Xcode. And as each target is managed independently, each time you need to eg. add/remove a compile flag, you will need to update each target, one. by. one. (or you will edit the .pbxproj "by hand" with sed/awk/whatever, which is faster, but risky... but fun :)).
Oh... and did I mention merge conflicts?
This might be due to a certain order in your build phases (Project -> Build Phases). Default, it will copy the bundle resources first and then copy Pods resources (overwriting the resources you had in your main application).
You could change the order of "Copy Pods Resources" to an earlier phase by dragging it to above "Copy Bundle Resources".
You also have to verify that the image resource included in your main project, has a correct target membership, by clicking on the image resource -> file inspector -> target membership. It should be checked for the target you are compiling.
duplicate your targets !?
The last apps I build by this way were using a different bundle identifier for each target.
Then just have a test to you bundle ID to make your different settings programmatically.
NSString *bundleIdentifier = [[NSBundle mainBundle] bundleIdentifier];

Duplicate symbols (two projects in a workspace use the same code)

A is a module project. There are some test targets and the relevant reusable code is compiled in a separate (static library) target. A uses the third party Lumberjack logging library. The Lumberjack code was simply dropped into the project.
B is a different module project, but otherwise it has the same properties as A.
C is the main project. It depends on A and B. It links the libraries of A and B.
Compiling C will result in duplicate Lumberjack symbols.
How can I have multiple separate module projects so that...
they don't know of each other,
use the same third party code,
can be compiled and tested on their own,
included in a main project without duplicate issues?
So, to elaborate on sergio's answer, I was able to succesfully build a test setup as follows.
I included the Lumberjack code in a separate project that builds Lumberjack as a static library.
I created a new project ProjectA with a static library target ModuleA and a test app target DemoA. I copied the Lumberjack project folder into the project folder of ProjectA and then added it as a subproject. I didn't make ModuleA dependent on Lumberjack or link Lumberjack in ModuleA. Instead, I made DemoA dependent on both and link both libraries. This way, I am able to compile the test target, but the library target doesn't include Lumberjack.
I created a second project ProjectB with the analogue setup as ProjectA.
In the main project, I included ProjectA, ProjectB and Lumberjack as subprojects. Unfortunately this will make Lumberjack included 3 times in the main project, which is a little bit inconvenient and ugly (for instance when selecting dependent targets, you can't really tell which one is which).
Finally, I made the main project's target dependent on Lumberjack, ModuleA and ModuleB and link all three libraries. Now, the main project can compile without duplicate symbol error and the submodules can also be compiled and tested on their own.
Since you are targeting OSX, the solution to your issue is building Lumberjack as a framework (as opposed to link the sources code in your A and B modules) and then using that framework wherever it is required (i.e., in any project using A or B modules).
Indeed, Lumberjack already includes a project that will build a Lumberjack.framework, check this: CocoaLumberjack/Xcode/LumberjackFramework/Desktop/Lumberjack.xcodeproj.
Elaborating more on this, you would define your A and B modules as you are doing now, but without dropping Lumberjack source code in it.
What you do instead is, whenever you want to use the A static library in a executable (say, your test target), you add the library to the target and also the lumberjack framework (exactly as you do with OSX SDK frameworks).
Adding the dynamic framework is just a different way to "drop the sources", if you want, but done properly.
When you want to use both A and B in a C project, you add both static libraries and your Lumberjack framework to C.
As you can see, this way of doing will comply with all your four requirements, at the expense of introducing one dependency: you need to make clear in your static libraries documentation that they depend on the Lumberjack framework. This is actually not a big issue, since the latter is available in its own project and any one will be able to build it on his own.
If you want to improve on the handling of this dependencies, cocoapods are the way to go (a cocoapod is a file associated to your library which describes its dependencies, so when you install your library, the cocoapods system will automatically install also the dependencies). But this is highly optional. One single dependency is not a big issue to document or comply with.
Hope this answers your question.
I hate to reference an existing answer but here's one solution that's cumbersome but works: What is the best way to solve an Objective-C namespace collision?
I have this same problem and I'm working on a better solution though. Another idea that might work but I'm not yet sure how to implement it I asked here: Selectively loading classes in Objective-C
A third idea I had because of something someone said on my question was to wrap one of the libraries in a framework and create functions that reference the functions you need. Then load using something like #import <myFramework/MFMyAliases.h>
Have you tried looking at the libraries with ar? If you are very lucky, running for example
ar -t libA.a
gives you a list of files like
__.SYMDEF SORTED
Afile1.o
Afile2.o
Lumberjack1.o
Lumberjack2.o
Afile3.o
SomeOtherLibrary.o
where the Lumberjack files are clearly separable from the rest. Then, you can kick them out
with
a -d Lumberjack1.o Lumberjack2.o
and link C against this trimmed library while using the full library when testing A alone.
I was trying to achieve the same thing before few months and "Easy, Modular Code Sharing Across iPhone Apps: Static Libraries and Cross-Project References" article got all what i needed. please check it out if its useful.
Are A and B binaries?
If not you could simply uncheck the compile checkbox for all *.m files of one of the projects, so as to avoid building duplicate objects.
Also if you could use A and B thorough Cocoapods it would be best.
Try this.
It is sharing libraries/modules between different projects.

What is the best way to organize source code of a large Cocoa application in Xcode?

Here is what I'm looking for:
I'd like to separate pieces of functionality into modules or components of some sort to limit visibility of other classes to prevent that each class has access to every other class which over time results in spaghetti code.
In Java & Eclipse, for example, I would use packages and put each package into a separate project with a clearly defined dependency structure.
Things I have considered:
Using separate folders for source files and using Groups in Xcode:
Pros: simple to do, almost no Xcode configuration needed
Cons: no compile-time separation of functionality, i.e. access to everything is only one #import statement away
Using Frameworks:
Pros: Framework code cannot access access classes outside of framework. This enforces encapsulation and keeps things separate
Cons: Code management is cumbersome if you work on multiple Frameworks at the same time. Each Framework is a separate Xcode project with a separate window
Using Plugins:
Pros: Similar to Frameworks, Plugin code can't access code of other plugins. Clean separation at compile-time. Plugin source can be part of the same Xcode project.
Cons: Not sure. This may be the way to go...
Based on your experience, what would you choose to keep things separate while being able to edit all sources in the same project?
Edit:
I'm targeting Mac OS X
I'm really looking for a solution to enforce separation at compile time
By plugins I mean Cocoa bundles (http://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/LoadingCode/Concepts/Plugins.html)
I have worked on some good-sized Mac projects (>2M SLOC in my last one in 90 xcodeproj files) and here are my thoughts on managing them:
Avoid dynamic loads like Frameworks, Bundles, or dylibs unless you are actually sharing the binaries between groups. These tend to create more complexity than they solve in my experience. Plus they don't port easily to iOS, which means maintaining multiple approaches. Worst, having lots of dynamic libraries increases the likelihood of including the same symbols twice, leading to all kinds of crazy bugs. This happens when you directly include some "helper" class directly in more than one library. If it includes a global variable, the bugs are awesome as different threads use different instances of the global.
Static libraries are the best choice in many if not most cases. They resolve everything at build time, allowing code stripping in your C/C++ and other optimizations not possible in dynamic libraries. They get rid of "hey, it loads on my system but not the customer's" (when you use the wrong value for the framework path). No need to deal with slides when computing line numbers from crash stacks. They catch duplicate symbols at build time, saving many hours of debugging pain.
Separate major components into separate xcodeproj. Really think about what "major" means here, though. My 90-project product was way too many. Just doing dependency checking can become a very non-trivial exercise. (Xcode 4 can improve this, but I left the project before we ever were able to get Xcode 4 to reliably build it, so I don't know how well it did in the end.)
Separate public from private headers. You can do this with static libs just as well as you can with Frameworks. Put the public headers in a different directory. I recommend each component have its own public include directory for this purpose.
Do not copy headers. Include them directly from the public include directory for the component. Copying headers into a shared tree seems like a great idea until you do it. Then you find that you're editing the copy rather than the real one, or you're editing the real one, but not actually copying it. In any case, it makes development a headache.
Use xcconfig files, not the build pane. The build pane will drive you crazy in these kinds of big projects. Mine tend to have lines like this:
common="../../common"
foo="$(common)/foo"
HEADER_SEARCH_PATHS = $(inherited) $(foo)/include
Within your public header path, include your own bundle name. In the example above, the path to the main header would be common/foo/include/foo/foo.h. The extra level seems a pain, but it's a real win when you import. You then always import like this: #import <foo/foo.h>. Keeps everything very clean. Don't use double-quotes to import public headers. Only use double-quotes to import private headers in your own component.
I haven't decided the best way for Xcode 4, but in Xcode 3, you should always link your own static libraries by adding the project as a subproject and dragging the ".a" target into your link step. Doing it this way ensures that you'll link the one built for the current platform and configuration. My really huge projects haven't been able to convert to Xcode 4 yet, so I don't have a strong opinion yet on the best way there.
Avoid searching for custom libraries (the -L and -l flags at the link step). If you build the library as part of the project, then use the advice above. If you pre-build it, then add the full path in LD_FLAGS. Searching for libraries includes some surprising algorithms and makes the whole thing hard to understand. Never drop a pre-built library into your link step. If you drop a pre-built libssl.a into your link step, it actually adds a -L parameter for the path and then adds -lssl. Under default search rules, even though you show libssl.a in your build pane, you'll actually link to the system libssl.so. Deleting the library will remove the -l but not the -L so you can wind up with bizarre search paths. (I hate the build pane.) Do it this way instead in xcconfig:
LD_FLAGS = "$(openssl)/lib/libssl.a"
If you have stable code that is shared between several projects, and while developing those projects you're never going to mess with this code (and don't want the source code available), then a Framework can be a reasonable approach. If you need plugins to avoid loading large amounts of unnecessary code (and you really won't load that code in most cases), then bundles may be reasonable. But in the majority of cases for application developers, one large executable linked together from static libraries is the best approach IMO. Shared libraries and frameworks only make sense if they're actually shared at runtime.
My suggestion would be:
Use Frameworks. They're the most easily reusable build artifact of the options you list, and the way you describe the structure of what you are trying to achieve sounds very much like creating a set of Frameworks.
Use a separate project for each Framework. You'll never be able to get the compiler to enforce the kind of access restrictions you want if everything is dumped into a single project. And if you can't get the compiler to enforce it, then good luck getting your developers to do so.
Upgrade to XCode4 (if you haven't already). This will allow you to work on multiple projects in a single window (pretty much like how Eclipse does it), without intermingling the projects. This pretty much eliminates the cons you listed under the Frameworks option.
And if you are targeting iOS, I very strongly recommend that you build real frameworks as opposed to the fake ones that you get by using the bundle-hack method, if you aren't building real frameworks already.
I've managed to keep my sanity working on my project which has grown over the past months to fairly large (number of classes) by forcing myself to practice Model-View-Control (MVC) diligently, plus a healthy amount of comments, and the indispensable source control (subversion, then git).
In general, I observe the following:
"Model" Classes that serialize data (doesn't matter from where, and including app's 'state') in an Objective-C 1 class subclassed from NSObject or custom "model" classes that inherits from NSObject. I chose Objective-C 1.0 more for compatibility as it's the lowest common denominator and I didn't want to be stuck in the future writing "model" classes from scratch because of dependency of Objective-C 2.0 features.
View Classes are in XIB with the XIB version set to support the oldest toolchain I need to support (so I can use a previous version Xode 3 in addition to Xcode 4). I tend to start with Apple provided Cocoa Touch API and frameworks to benefit from any optimization/enhancement Apple may introduce as these APIs evolve.
Controller Classes contain usual code that manages display/animation of views (programmatically as well as from XIBs) and data serialization of data from "model" classes.
If I find myself reusing a class a few times, I'd explore refactoring the code and optimizing (measured using Instruments) into what I call "utility" classes, or as protocols.
Hope this helps, and good luck.
This depends largely on your situation and your own specific preferences.
If you're coding "proper" object-oriented classes then you will have a class structure with methods and variables hidden from other classes where necessary. Unless your project is huge and built of hundreds of different distinguishable modules then its probably sufficient to just group classes and resources into folders/groups in XCode and work with it that way.
If you've really got a huuge project with easily distinguishable modules then by all means create a framework. I would suggest though that this would only really be necessary where you are using the same code in different applications, in which case creating a framework/extra project would be a good way to effectively copy code between projects. In practically all other cases it would probably just be overkill and much more complicated than needed.
Your last idea seems to be a mix of the first two. Plugins (as I understand you are describing - tell me if I'm wrong) are just separated classes in the same project? This is probably the best way, and should be done (to an extent) in any case. If you are creating functionality to draw graphs (for example) you should section off a new folder/group and start your classes and functionality within that, only including those classes into your main application where necessary.
Let me put it this way. There's no reason to go over the top... but, even if just for your own sanity - or the maintainability of your code - you should always endeavour to group everything up into descriptive groups/folders.