Open source projects should be more accessible to contributors

There are ton of developers out there, me included, who are looking for open source projects to help and improve their technical skills. It’s a good opportunity to dive into other people code, learn good practices and actually have code reviews from peers. Unfortunately, it’s often really hard to find a good project to actually contribute. And even then, it is difficult to know where to start and what you could actually do.

The project doesn’t work out of the box

The code can sometimes have a lot of dependencies and project developers didn’t take the time to write a “Getting started” note to help potential contributors to have a working copy of your project. Even when its there, it has to be up to date.

Project owner doesn’t explicitly say how contributors can help

What could potential others do to help in your project? That’s often unclear. They could find something to do by solving the issues, add features from a roadmap,  improve the tests coverage, everything is possible but usually hard to guess. Within issues, it’s usually better if they are tagged so it’s easy to see if it’s important or if it can be done without having a global knowledge of the project.

There is this post about the CONTRIBUTING.md file on Github, I like the idea and think it is a good place to gather all this thing that will help others to help!

I’m a really fan of the open source philosophy, I really would like to find more projects I could contribute 🙂

iOS and the status bar

Since iOS 7, there is this UIViewControllerBasedStatusBarAppearance or “View controller-based status bar appearance” option in Info.plist that aims to manage the way status bar appearance is set across the app.

Typical answers on Stack Overflow to questions regarding status bar text color not changing to white when using the UIApplication setStatusBarStyle: method or not disappearing when hiding will say:

Just set the “View controller-based status bar appearance” option to NO in your Info.plist.

That’s a mistake. By doing this, you are turning off the feature introduced in iOS 7. Even if I agree that this is convenient, I could not encourage you more to work with UIViewControllerBasedStatusBarAppearance set to YES.

Here are some things I learned trying to get it to work:

  1. The “Status bar style” and “Status bar is initially hidden” are still used during launch screen.
  2. If a view controller is not contained in a navigation controller and if you want to have a status bar with text colored in white, then you have to override the preferredStatusBarStyle method to say that you want the light content status bar style
  3. If you are using navigation controllers, the previous method is ignored so you should use [[UINavigationBar appearance] setBarStyle:UIBarStyleBlack];, status bar style is automatically set light content in this case
  4. To hide status bar, there is also this “prefersStatusBarHidden” method that you can override
  5. The overridden methods are called when  your view controller is first displayed, but you can force iOS to update status bar settings by calling [self setNeedsStatusBarAppearanceUpdate]; at runtime

A good example of something you can’t achieve with UIViewControllerBasedStatusBarAppearance set to NO: is getting the status bar to white text color when opening a MFMailComposeViewController; even with status bar default color globally set, the status bar stays written in black. To bypass that, you must change the option value to YES, and you can, for instance, create a category like this one:

#import "MFMailComposeViewController+StatusBarStyle.h"
@implementation MFMailComposeViewController (StatusBarStyle)
#pragma mark - Status bar management
- (UIStatusBarStyle)preferredStatusBarStyle
{
return UIStatusBarStyleLightContent;
}
- (UIViewController *)childViewControllerForStatusBarStyle
{
return nil;
}
@end

Part of the credit goes to this post: https://coderwall.com/p/hitv1q/mastering-ios-7-uistatusbarstyle

The difference between line separator and paragraph separator

Did you know that there is a possible difference between line and paragraph separators with unicode characters?

This is very interesting when you are working with attributed strings. Basically, a \n is a paragraph separator (same as unicode character U+2029), lineSpacing doesn’t have any impact on this “line break“. You must use unicode line separator (U+2028) instead.

// Let's prepare our paragraph style attribute
NSMutableParagraphStyle *paragraphStyle = [[NSMutableParagraphStyle alloc] init];
paragraphStyle.lineSpacing = 4.0f; // For line separators and automatic line breaks
paragraphStyle.paragraphSpacing = 20.0f; // For paragraph separators

// Now we can use it to create an attributed string that behave differently with line and paragraph separators
[[NSAttributedString alloc] initWithString:@"Hello, World!"
attributes:@{ NSParagraphStyleAttributeName: paragraphStyle }];

More information about this in Apple iOS documentation

Xcode and code signing

As an iOS developer who is member of multiple teams and who is managing multiple clients Apple IDs, I totally approve the guidelines of Jared Sinclair in its post “Follow These Guidelines and Never Struggle with Xcode Code Signing Again“, more particularly the one about Xcode helpers:

Never use Xcode’s built-in code signing helpers. Especially avoid any button that says Fix Issue.

As Jared explains, it fills developer portal with worthless “iOS Team Provisioning Profile: XXX” provisioning profiles. Once sync in Xcode, there are so many profiles that you can’t find the one you are really looking for. The worst part of it is that this helper isn’t always working as you expect, especially if you don’t know what you are doing, and it arrives that you still can’t deploy on device after using it…

I will add that you shouldn’t be the one in your team touching the code signing settings if you don’t know how the whole code signing system works.

Understanding fonts and UIFont

For the first time in years, I had to dig inside one of the fundamental things we use everyday and everywhere: fonts.

Do you know how a fond is built? Applied to iOS, do you know how a UILabel will render a font?

First of all, a font is basically a container for vectors representing symbols from different categories such as letters, numbers, punctuation and other characters you can usually type with your keyboard. The more existing symbol a font contains, the more complete it is.

Within a font editor (Glyphs, Fontlab or whatever software allowing you to create and / or edit fonts) and for each symbol, the font “creator” draws vectorial paths according to some kind of grid. In iOS, UIFont’s grid looks like:

UIFont explained
UIFont as explained in Apple Developer documentation

The baseline if the base of all symbols. Then you have to distinguish the cases between minuscule letters with the x-height (X-height in the previous figure) since the minus “x” is supposed to be a perfect lower character; and the capital letters having their theoretical height represented in cap height.

Space on top of the baseline to the higher symbol Y offset is called the ascent or ascender. Space under the baseline and used for letter legs is called the descent or descender. There is more space under descent, it represents a gap to add between lines.

Adding the ascent to the descent and the line gap results in the line height which is basically the height of a single line of text.

That explains a lot! Did you ever notice that a label vertically centered in a view is not perfectly in the middle of the view?

It looks good...
It looks good…
... but if you zoom
… but if you zoom
...and it's even more visible if you add a background color to the label
…and it’s even more visible if you add a background color to the label

This is not a bug, just the way a font is rendered in a label. The extra space here is just the combination of both ascender and descender, and this space could be use (even if it is not in this case) to display accents, cedillas or other things that will be drew outside of the cap height bounding box.

Now, how can we respect a graphical chart dictating exact point size spacing between labels starting from the exact bottom of a label and ending to the exact top of another one?

chart
yeah, that’s always easier to say for designers when they are in Photoshop or InDesign…

So now, I have to work on a solution, the basic idea behind it is to subclass the UILabel class to have it read the metrics of UIFont’s and know its exact height. Even if it’s not working perfectly for every font (especially for some custom fonts that seems to be badly created) at the moment, the result is promising!

Promising results using the fitting label solution
Promising results using the fitting label solution

 

Core Data Stack

Recently, I’ve read this article Marcus Zarra about the base Core Data stack he uses in its projects. I couldn’t agree more about some topics discussed by Marcus:

The Cora Data stack doesn’t belong to the App Delegate

I do not create the Core Data stack in the App Delegate. That is not where it belongs. I create it in its own controller class. Our persistence layer is far too important to be delegated to the Application Delegate. It deserves a proper controller of its own.

This is not only true about the Cora Data stack, but this is a very good example since Apple project templates using Cora Data are putting everything into the base AppDelegate class; most developers never question that fact and continue to think that the AppDelegate is some sort of garbage where they should write everything and anything.

Dependency Injection

The proper way to get access to the persistence controller is to inject it into each view controller as they are built and accessed.

If there is something I wish I could never see or write again, this is probably this ugly MANAGED_OBJECT_CONTEXT macro pointing to something like:

((AppDelegate *)[[UIApplication sharedApplication] delegate]) managedObjectContext

The dependency injection is the solution, unfortunately, this technique is pretty annoying to use since the easier way is to do it is to inject our persistence controller during controllers and view controllers initialization…

This apart, I truly think dependency injection can help when it comes to testing. My approach for that will be very slightly different since I would probably prefer a different initializer for the PersistenceController class, with something more like:

/**
Default initializer

@param storeType Core data store type (eg: NSSQLiteStoreType or NSInMemoryStoreType)
@param modelName Name of the managed object model file
@param dataStoreName Name for the data store file that will be written on disk
@param callback A block to be called once persistence stack is ready to be used
@return An instance of PersistenceController class
*/

- (instancetype)initWithStoreType:(NSString *)storeType modelName:(NSString *)modelName dataStoreName:(NSString *)dataStoreName callback:(void (^)(void))callback
{
if (self = [super init])
{
// Hold parameters
_storeType = storeType;
_modelName = modelName;
_dataStoreName = dataStoreName;
_initCallback = callback;

// Initialize Core Data stack
[self initializeCoreData];
}

return self;
}

This allows in-memory data stores that can be created for testing purpose.

However, I’m really looking for a way to enjoy the benefits of dependency injection without the struggle of passing my persistence controller again and again. This is where I go for now, any suggestion will of course be welcomed!

The original post discussed here can be found here: http://martiancraft.com/blog/2015/03/core-data-stack

I  Swift

Not a surprise, Swift is very different from Objective-C,  knowledge of Cocoa and Cocoa Touch APIs helps a lot to skip the struggle coming from iOS and is a real plus in learning.