Creating your own custom libraries in iOS? - objective-c

I'm fairly new to programming and wanted to start programming more efficiently. Try as I may I often find myself straying from the MVC model.
I was wondering are there any tips or methods in keeping your code organized when coding in xcode objc? To be more specific (I know you guys like that :) I want to
Be able to write libraries or self-containing code that can bring from one project to another
Share my code with others as open sourced projects
Prevent myself from writing messy code that does not follow proper structure

Use a high warning level. Build cleanly.
Remove all static analyzer issues.
Write some unit tests.
Keep the public interfaces small.
Specify your library's dependencies (e.g. minimum SDK versions and dependent libraries).
Compile against multiple/supported OS versions regularly.
Learn to create and manage static library targets. This is all you should need to support and reuse the library in another project (unless you drag external resources into the picture, which becomes a pain).
No global state (e.g. singletons, global variables).
Be precise about support in multithreaded contexts (more commonly, that concurrency shall be the client's responsibility).
Document your public interface (maybe your private one too…).
Define a precise and uniform error model.
You can never have enough error detection.
Set very high standards -- Build them for reuse as reference implementations.
Determine the granularity of the libraries early on. These should be very small and focused.
Consider using C or C++ implementations for your backend/core libraries (that stuff can be stripped).
Do establish and specify any prefixes for your library's objc classes and categories. Use good prefixes too.
Minimize visible dependencies (e.g. don't #import tons of frameworks which could be hidden).
Be sure it compiles without the client needing to add additional #imports.
Don't rely on clients putting things in specific places, or that resources will have specific names.
Be very conservative about memory consumption and execution costs.
No leaks.
No zombies.
No slow blocking operations on the main thread.
Don't publish something until it's been well tested, and has been stable for some time. Bugs break clients' code, then they are less likely to reuse your library if it keeps breaking their program.
Study, use, and learn from good libraries.
Ask somebody (ideally, who's more experienced than you) to review your code.
Do use/exercise the libraries wherever appropriate in your projects.
Fix bugs before adding features.
Don't let that scare you -- it can be really fun, and you can learn a lot in the process.

There are a number of ways you can reuse code:
Store the code in a common directory and include that directory in your projects. Simple, but can have versioning issues.
Create a separate project which builds a static iOS library and then create a framework. More complex to setup because it involves scripting to build the framework directory structure. But easy to use in other projects and can handle versioning and device/simulator combined libs.
Create a separate project which builds a static iOS library and then include this as a subproject in other projects. Avoids having to build frameworks and the results can be more optimised.
That's the basic 3, there are of course a number of variations on these and how you go about them. A lot of what you decide to do is going to come down to who you are going to do this for. For example I like sub projects for my own code, but for code I want to make available for others, I think frameworks are better. even if they are more work to create. Plus I can then wrap them up with docsets of the api documentation and upload the whole lot as a DMG to github for others to download.

Related

How to implement custom build types for Modern CMake in a generalizable (multi-compiler/platform/generator) way?

We currently have a multi-platform, multi-compiler build for a C++ program based on a bunch of custom ad hoc scripts. I'm investigating switching over to Modern CMake (with "modern" used in the sense described here), and trying to do it in a "best practices" way as much as possible. (For example, doing so in a fashion which will work with all sorts of generator types.)
The issue I'm running into is that we have more build types (build modes? configuration types?) than just the standard Release/Debug/RelWithDebInfo/MinSizeRel. I'm wondering how to implement these with Modern CMake.
From what I can tell (e.g. from the FAQ), the "traditional" way to add new build modes would be to hardcode various variables with names containing the new mode name. I'm skeptical about this approach for several reasons. First off, the list of variables which need to be set is left rather unclear. Secondly, it looks like the Modern CMake approach is to attach compiler flags to targets, rather than messing with global settings, and I'm not sure how to square that with the build type globals. Lastly, given the hope to have things working in a multi-compiler/cross platform fashion, I'm a bit concerned that Release/Debug/etc. works "automagically" on multiple platforms/compilers, but the custom build modes seem to require hard coding things for a particular platform/compiler. I realize that some platform/compiler specific code may be unavoidable, but I'm hoping to minimize that to the extent possible, and do that robustly.
What's the recommended best practices "Modern CMake" way of creating custom build/configuration types/modes? Specifically one which is most extensible for use with multiple compilers and platforms, and works robustly with both multi-configuration and single-configuration generators?

Most efficient was to reuse classes across iOS Projects

I have created a number of re-usable classes that I use across xcode projects, for example:
Utility
EmailController
MarketingController
FlashLightController
etc
I had been simply copying these class files from and back into a central repository, but now I have a number of apps it is all getting a little confusing from a config management point of view. So I was looking for an alternative.
I started investigating Static Libraries but they seem to be quite a lot of more effort for simply re-using code (e.g. different libs for device vs simulator, still having to have copies of .h files, etc).
Does anyone know of a decent alternative for quick and easy code reuse?
Thanks, Charlie
You can put the code files into a project without actually copying them into the project. In other words, just keep the class files in a completely separate location. Import them into many projects, but uncheck the option to copy them in. The projects will still refer to them successfully. Now a change made in the class files will propagate to every project that uses them.
Also, consider whether workspaces will help you.
In my view, almost anything is better than making a library or framework!
Static libraries would probably be your best bet, as I have used them and have found them to be pretty easy to use. (I haven't had to use different libraries for device or simulator, mine works on them all). Having the header isn't that annoying, and static libraries are really the only way (outside of dynamic libraries, which are banned by apple) other than copying the files to reuse code.

Is there a good way in XCode to reuse Classes across projects and easily share with other devs?

I have a library that I created which I would like to use the included classes across a few different projects while maintaining the library code independently. I would also like to be able to easily share it with other developers and have them easily implement it. At this point it doesn't need to be a static library.
What is the best method to do this? I have seen other devs put their classes in a brand new XCode project then import that, but what is best practice?
I think the best practice is to create a project with a static library target. Other developers can include it as a subproject in their projects.
Second best would be to simply make a directory of source files that can be included in a project on an as-needed basis. This is useful for general purpose utility code where a particular project may not want all of it.
In both cases, the library code should belong to its own git repository and included in a project as a git submodule.
If it will ever become a static library, it's best to make it one now, rather than waiting until it is "ready"; by the time you decide to switch it over, a few projects will already be using it, and converting each of them to use it will be a pain. Just do it the right way from the beginning.
If you want to distribute the library without source, you will want to use lipo to build a universal library that contains both ARM and x86 code. Unfortunately, Xcode doesn't make this as easy as it could be, but it's not too difficult with some light shell scripting.
As far as I know you should create a new project and that project to any other project you want use library in. Then link the projects and you can access it. The other way which I have done also, copy the library classes directly to the new project and access the library through importing the needed classes. In my case i found creating a project and linking it with the new project is the easiest. although copying the classes isnwhat we all do when using external libraries such as cocos2d. As far as sharing it with others, just upload it to github another place of your choice so it can be used by other dev's. I hope this helps you.t
I don't know how mature the code is, but since you specifically mention wanting to share it with other developers, you may want to investigate CocoaPods.

objective-c frameworks - Dynamic Library Install Name

I'm new to objective-c & osx architecture. I started playing with building a framework and then using it. I followed this great tutorial.
During the tutorial, I had to set the framework's target's Dynamic Library Install Name to #rpath/MyFramework.framework/Versions/A/MyFramework. My understanding is that #rpath will expand to the loader's (consumer's) run-path search paths.
It seems as if the responsibility of loading the framework is split between the framework author and the consumer author. Could someone please explain why the author of the framework needs to be concerned with the consumer's run-path search path? For example, if the framework-author set the Dynamic Library Install Name to point to some random directory (instead of #rpath) how would the client be able to consume the framework?
Thanks in advance.
It depends a lot on how the framework is being used. And it's important to remember that the framework construct has existed for a long time on the platform.
For a system framework, such as the ones that Apple creates, you're going to be quite happy that they keep the frameworks in a known location. In those cases, the paths that they use are fixed for the OS, and it guarantees that you don't accidentally load the wrong one. Further, as indicated in the Framework documentation, these frameworks are loaded only once on the machine, regardless of how many times they are used (see Apple:What Are Frameworks) . The benefit here is performance and it is for both the code and the resources in many cases.
Due to the recent move to randomize framework locations,and Apple's comments in the release notes that "Mountain Lion randomly relocates the kernel, kexts, and system frameworks at system boot," it certainly appears they're still sharing these resources, and thus still gaining from this benefit.
For embedded frameworks, the situation is a lot more tedious, and Apple has moved through a variety of methods over the years to make it easier to find frameworks wherever they may be. Due, again, to the shared nature, it would make sense for Applications which share common library requirements to share them on the machine, both for purposes of efficiency, and to make sure they're at the same version if they're sharing data. So, for example, if you have two separate apps that use the same framework to work with shared data, you might put the shared framework in /Library/Frameworks and have both apps explicitly look for that, making sure that some other (possibly older) version of the framework, that has been loaded by another App, is not used instead.
In the end, there's a lot of flexibility for the Framework producer and consumer the way that it currently works. It means that the developer can decide to share a framework, include a private copy of the framework, or even do both, depending upon whether the framework exists on the machine or not. However, the price for that flexibility is the complexity that we have today.
Another example of a reason you might not want to use #rpath specifically is for tightly-linked embedded frameworks (yes, people embed frameworks within other frameworks). In these cases, you don't know where the first framework is loaded, but you want to put the embedded framework inside of it, so that they stay together. In this case #loader_path is relative to the code that is loading it, so that your plug-in's framework can find its resources correctly.
In answer to your specific example about somebody setting the Dynamic Library Install Name
to a "random" location. In this case, you'd have to know that location. There might be many reasons for somebody doing this, such as wanting to discourage reuse by other programs, or because there are large resources within the framework that should only be installed in a known shared location.

Obfuscate Objective-C code for a reusable iOS package [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Objective-C Code Obfuscation
I am trying to put together an iOS package that can be reused in multiple apps. I would like to be able to bundle it up for others to easily plug in and use, and I would like to obfuscate the code so that no one can read it.
What would you recommend between building a framework, a static library, or another solution to accomplish this and why?
If you're distributing for iOS, you have two options:
Distribute a precompiled binary and headers
Distribute the source
Since you're asking about hiding stuff, I don't think #2 is what you're looking for.
As for #1, the best you can do is just not tell 3rd party users about more stuff. They'll still be able to use the runtime to find methods and properties and instance variables, etc. If you're doing everything in C-land (ie, no Objective-C classes), then they can still use things like otool to dump symbols.
In short:
It's probably not worth trying to "obfuscate" your code. Just tell them about the stuff they need to know about, then give them a .a file and the headers they need.
A framework is the standard Cocoa approach to shared code. You can distribute a framework as a compiled code library and a collection of public headers without making any of the underlying Objective-C soure code visible. Of course, a dedicated hacker could still read the machine code, but this would be a big undertaking, and probably not worth the time they would have to spend on it.
If you are really concerned about sensitive code, you could consider an internet-based service, in which your library calls out to a remote server under your control to perform some business logic. This approach is quite a bit more involved, and does not offer as much flexibility for your customers.