If you want to be able to write block declarations from the top of your head, read-on!
I strongly advise against reading this post in an RSS reader or read later service. It does heavy use of colors to explain things and these colors would not appear there.
Variables in C (and by extension Objective-C) are declared using declarators.
A declarator has 2 roles:
Let’s start with the most basic declarator:
int a;
This is most likely the first line of C code you have ever written.
int
is a basic type and a
is the variable name or identifier1.
To read a declarator, you start from the identifier, then go right until you can’t and then you start over from the left of the variable2 (we’ll explain why in the next section).
Here there is nothing to the right of our variable so it’s straightforward: a
is an int
.
A declaration can only have 1 basic type and it’s the left most word of the declarator.
Declarators can modify basic types using modifiers to create derived types. The 4 modifiers (3 from ANSI-C and one from Apple’s proposed extension) are *
, []
, ()
and ^
.
*
int *a;
The basic type is still int and the name of the variable a
. But the pointer modifier *
comes to tell us that a
is a pointer to an int
instead of an int
.
The *
modifier is always to the left of the modified variable.
[]
int a[];
Here we see that the array modifier []
comes to tell us that a
is now an array of int
s instead of a simple int
. This can be completed by the dimension of the array e.g. int a[10];
.
The []
modifier is always to the right of the modified variable.
()
int f();
The function modifier ()
comes to tell us that f
is a function that returns an int
. This modifier can also specify the arguments that the function takes e.g. int f(long);
is a function that takes a long as an argument and returns an int.
The ()
modifier is always to the right of the modified variable.
Modifiers can be composed to create more complex variable types. Similarly to how arithmetic operations are ordered by precedence (* and / are executed before + and –), modifiers are too. []
and ()
have higher precedence over *
(and ^
).
Since the 2 modifiers with higher precedence are written to the right of the variable, when reading complex declarator, you always start from the identifier and go right as long as possible then go left when you reach either the end of the declarator or a closing parenthesis.
int *a[];
or as you can write it by adding parentheses to improve readability
int *(a[]);
is an array of pointers to an int
.
But you might ask, what if I want to have a pointer to an array of ints? Well since *
has lower precedence than []
, you need to use parenthesis to force that precedence.
int (*a)[];
Here, a
is a pointer to an array of int
s.
You cannot have an array of functions and a function cannot return an array or a function3. A function can however take an array as an argument.
int f(int [10]);
Here f is a function that takes an array of 10 int
s as an argument and returns an int
.
int *f(); int *(f());
In both cases, f
is a function that returns a pointer to an int
.
What if you want a pointer to a function? Parentheses!
int (*f)()
f
is a pointer to a function that returns an int
.
^
Apple introduced a 4th modifier in its proposed extension of the ANSI-C standard: ^
.
This modifier is called the block pointer modifier (or closure modifier as they were originally called). Blocks are very similar to pointers for functions. You declare a block the same way you would declare a pointer to a function.
The block pointer modifier can only be applied to a function (you cannot write int ^a;
as this is not defined).
This is the reason why int ^b()
is illegal and will cause a compiler error: If you read this declarator using the precedence rules, b would be a function that returns a block pointer to an int. There is no such thing and this is why when declaring a block you need to always put the caret and the identifier in parentheses.
int (^b)()
b
is a block pointer to a function that returns an int
or as abbreviated a block that returns an int
.
You can of course specify the arguments that the block takes:
int (^b)(long)
is a block that takes a long as an argument returns a int
.
This is where the syntax for block declarations comes from.
Now you already know that there are other syntaxes that you need to remember in order to use blocks: the one used to define a block literal, and the one to pass the block to an Objective-C method.
A declarator is made up of 2 things: an abstract declarator in which you insert the identifier.
Abstract declarators are used in 3 cases in standard C:
In casts: in int *a; long *b = (long *) a;
, (long *)
is an abstract declarator for a pointer to a long
.
As arguments of sizeof(): malloc(sizeof(long *));
When declaring argument types for a function: int f(long *);
Objective-C uses abstract declarators in one more place: when declaring arguments or return values for methods.
|
Here both long **
and int *
are abstract declarators.
So in order to use blocks as arguments or return values for Objective-C methods, we need to find the abstract declarator for these blocks. This is achieved by taking the declarator and removing the identifier.
int (^b)()
becomes int (^)()
and int (^b)(long)
becomes int (^)(long)
.
example:
|
While you don’t have to name your block’s arguments in these abstract declarators, it is a good idea to do it. It will give a good hint as to what the block expects as argument and Xcode autocomplete will make your life easier when using that method.
When you write int a = 2;
, int a
is a declarator and 2
is a literal for an int.
The caret ^
is also used as a unary operator to transform a function implementation into a block4. You don’t need to specify the return type for the block (it is inferred from the return statement in that block) but you can.
Since this is the implementation of that block, you need to name your arguments here.
So for the block int (^block)(long, long);
, a block literal would be:
|
As convoluted as it may seem, blocks syntax in Objective-C is built upon standard C syntax. A block in Objective-C is nothing more than a pointer to a function that captures its scope. Once you understand that and practice writing and reading a few blocks declaration, you’ll find it much easier to apprehend.
From ANSI-C draft page 35: “An identifier can denote an object; a function; a tag or a member of a structure, union, or enumeration; a typedef name; a label name; a macro name; or a macro parameter”↩
Oddly enough, Microsoft, of all companies, has a good page explaining the interpretation of complex declarators.↩
From ANSI-C draft page 133: “A function declarator shall not specify a return type that is a function type or an array type.”↩
From Clang documentation: “A Block literal expression produces a reference to a Block. It is introduced by the use of the ^ token as a unary operator.”↩
Git had just auto-merged a xib file for me! I figured this must have something to do with Xcode 5 and its “upgrading” of xib files, so I started digging.
It turns out that the xib files generated by Xcode 5 are of a completely new kind. It seems that Apple started from scratch with this and the changes make xib files finally usable in teams of all sizes for the first time.
To demonstrate the difference between the 2 file formats I have created a new xib file in Xcode 4 and put a bunch of views in it: A UIScrollView with UIButtons, UILabels and more in it, a UITextView etc.
After that I right clicked on the file in the project navigator and selected Open As > Source Code
. Here is what that file looked like under the hood:
.xib file generated by Xcode 4 (you need to click “File suppressed. Click to show.” because github is being stupid)
1108 lines for a rather simple view! That’s a lot.
Try to make sense of the file, it’s not intelligible at least not easily. This is the main reason why people don’t like xib files and don’t use interface builder.
It gets worse: the format is non-deterministic. Meaning that if you and I create exactly the same UI in Interface builder, we might (will) not have the same file content. This use to make xib files very difficult or even impossible to merge. This is the other big reason for people not to use xib files.
Then I opened the same project in Xcode 5. When you open a xib file that was created in Xcode 4 in Xcode 5 you are prompted to upgrade the file to the new format. You want to only do it if all the people working on the project use Xcode 5 because the new files can’t be opened by older versions of Xcode.
I clicked Upgrade and then opened the xib file as source code again to see what had changed. Here is what it looked like.
.xib file generated by Xcode 5 (again, click “File suppressed. Click to show.”)
103 lines! The old file had more than 10 times as many lines! Now this is what I call a drastic reduction.
And look at it, it’s actually understandable. The file now reflects the view hierarchy that you see in the left part of Interface Builder! With a little bit of practice you could even write that xml code. Ok, ok I am pushing it a little here.
On top of that, the code generated seems to be deterministic now. This means that with the same user interface in input it will generate the same xib file. This makes manual merging much easier if it is needed.
The best part is that this new file format is not only understandable by humans but git can also make sense of the changes happening and will now most of the time auto-merge your xib files for you!
Now if someone tells you that they don’t want to use xib files, send them to this article, I don’t think there are many reasons left not to use them.
This is not the only improvement that Xcode 5 brings to Interface Builder, for example, setting auto-layout constraints is now awesome whereas it was a pain before. If you have tried setting constraints in code you know that it is not a walk in the park.
Let me know what you think on twitter!
]]>In this article, I am going to explain how to get both the currently released version of your app and the development build you are working on the same device easily. I am also going to explain how to have 2 different icons for them so that you can tell them apart.
Update: You only need 2 different App IDs if you need to use things such as push notifications or iCloud. Otherwise you can use a wildcard profile with 2 different bundle IDs. Thanks @alloy for the tip.
When you install an App, in order to determine if you are trying to install a new app or to update an app already installed, the device compares their App IDs.
So the first thing to do is to go in the provisioning center and create a second App ID for the development version of your app so that the device will be able to keep the two versions of your app.
If your App Store app has the App ID com.mycompany.myapp
I suggest you create com.mycompany.myapp-beta
or com.mycompany.myapp-dev
.
While you’re in there also create a provisioning profile for that new App ID.
In order to differentiate the 2 versions when they are on my device, I use 2 different icons. The beta version has a black and yellow work in progress banner at the top left.
The first time I saw that technique used it was on a springboard screenshot of Federico Viticci’s phone where he had a development version of Tweetbot.
I created a PSD template to create those development icons, here it is: App-icon-beta-overlay
Name your icons Icon.png
, Icon@2x.png
, Icon-beta.png
and Icon-beta@2x.png
.
By default, Xcode creates 2 build configurations for you: Debug and Release. I like to add a third one, AppStore. I use them as follow:
Now we need to setup the project so tat it will use the correct App ID and icon for each configuration.
To do so, go in your project’s Build Settings and scroll all the way down. Add a User-defined setting that you call BUNDLE_IDENTIFIER
and another one that you call APP_ICON_NAME
. Set the values for each build configuration as in the following screenshot:
Now we need to tell Xcode to use these settings when building your app
Open the info.plist file for your project (It’s in Supporting files and is called MyApp-Info.plist).
There under bundle identifier, replace the bundle identifier that you currently have with ${BUNDLE_IDENTIFIER}
Also open the Icon files drop down and make sure the 2 options you have are ${APP_ICON_NAME}@2x.png
and ${APP_ICON_NAME}.png
.
The ${…}
syntax is the pre-processor syntax: the first phase of any build starts with the pre-processor going over all the files and replacing these ${…}
with the values to what they are set.
This lets you with a project that will automatically use the beta App ID and icon when you are building for testing but that will also use the regular App ID and icon when you make a build for the App Store.
Using pre-processor macros you can also access those settings from your code to set different parameters for different configurations.
You can take it now step further and define more build configuration. Let’s say your app connects to an API and you want some builds to point to the production server and some others to point to a development server, you can use this method to point them to the right URL and give them a different icon automatically!
]]>As always when writing code that other people are going to read, you want it to be as clean as possible. Here are a few tips:
Often you want to share just a few classes but it is a good idea to include a Demo project so that people can understand how your classes are intended to be used.
Have the files of interest in a folder and the files for the demo project in a different one so as not to confuse your user.
You want the project file to reflect the organization of the project folder:
Here the class I want to share is NHAlignmentLayout
the rest of the files are there to demonstrate how to use it.
Write an explicit readme with code samples and even screenshots, that will be the homepage for your repo and will likely be the decisive point for if someone who comes to your project will end up using it or not. Include explicit instructions on how to install you classes (Most likely using CocoaPods.
When you open source some of your work, you need to define what people can and cannot do with it. This is the role of a license. There are many open-source licenses such as MIT, GNU, and BSD… You can find which one is best for you by going to Choose A License. This site made by Github will help you find the best license for you.
Go to your Github account and create a new repository for your project. Name it with a name that makes sense; don’t name it XXSomethingDemo
but rather XXSomething
as this is what everybody cares about.
Check the option to add a .gitignore file and choose Objective-C.
Clone the repo you just created in a temp folder on your mac. You don’t want to add the repo as a remote for your current git repo in order to start with a fresh repo and a beautiful Initial Commit.
|
Copy and paste your project files to that folder. You want to have the .xcodeproj file at the root of the repo. Do not put everything in a folder as the only thing it will do is annoy you users.
Add your newly added files to git, commit and push to github.
|
Your project is now open-sourced and people can start using it! But for it to be really easy to use and install you want to make it available on CocoaPods.
CocoaPods is to Objective-C what gems are to Ruby. You can list in the root of your project the “pods” you need and CocoaPods will download them and install them for you.
Start by installing CocoaPods if it is not already installed on your mac.
You need to create at the root of your repo a file that is a recipe for CocoaPods to use your classes.
Navigate to your project folder in a terminal window and ask CocoaPods to create a staring pod spec for you:
|
Open that file and start filling it with the information on your project.
It is important to use a version number. I usually start with 0.1.0 but this is up to you.
The source
line is also important it is the line that tells CocoaPods where your project resides on the internet.
|
You also need to tell CocoaPods which files in your repo are relevant so that it does not copy any unneeded demo/example file.
|
Then we are going to verify the validity of your .podspec file.
You noticed that in s.source
we point to a specific tag in our repo. You need to create a tag for CocoaPods to be able to find your code. A tag is an absolute reference across branches to a state of your code in time. They’re often used for versioning and that’s what CocoaPods use them for.
Create the tag locally and then push it to Github. In your terminal window enter:
|
Then you want to make sure that you .podspec file works. To do so use the pod spec lint command
.
|
This will try to download the pod you just created from the address you supplied in the podspec file. You should get something like this:
|
Commit that file to git and push it to Github.
|
All .podspecs files are kept in a central to repo called Specs. You need to fork that repo, add your pod specs to it and then issue a pull request for it to be merged. Don’t worry it’s really easy.
Go to the Specs Github Repo and Press the Fork Button on the top right corner. This will create a copy of the Specs repo in your account.
Clone the forked repo on you computer to be able to modify it.
|
Create a folder named with the name of you pod. for me it is NHAlignmentLayout
Create a subfolder with the name of your tag 0.1.0
for me.
Copy the .podspec file you created earlier in that folder.
Commit and push your changes to you forked repo:
|
Go to the forked Specs repo on github. Press the Comparison button, next to the name of the current branch. :
This will initiate the comparison between your current repo and the original repo.
Review the changes, you should see the content of you .podspec file in green, meaning that this was added.
Press the Click to create a pull request for this comparison
Button.
This will send a pull request to the owners of the Specs repo. They are usually extremely quick to merge the pull request!
Once your pull request is approved you can start using your pod in other projects.
Now, go share your code!
]]>Then I decided to test on an actual iPad. This is when I realized that the videos looked completely different from the background. I had a color management problem. We tried every export settings we could find in After Effects, nothing would work.
The solution that I found was to have After Effect export the animation as a PNG Sequence + audio file and then to generate an mp4 video from these assets using ffmpeg.
This post explains the settings I found that worked for me.
Open a terminal window and run the following command:
ffmpeg -f image2
-i ./path/to/images/imaged.png \
-i ./path/to/audio/audio.mp3 \
-r 30 \
-vcodec libx264 \
-pix_fmt yuv420p \
-acodec libvo_aacenc \
-ab 128k \
./path/to/output/output.mp4
Let me explain the parameters here:
-i xxx
is to specify the input files (both the image sequence with the which means “number with 5 exactly digits” and the audio file)-r
is to specify the frame rate at which ffmpeg is going to interpret the png sequence-vcodec
is the video codec-pix_fmt yuv420p
is required so that the output h264 mp4 file is compatible with Apple implementation of the codec. I fyou don’t put this, the video won’t play in quicktime or on an iOS device.-acodec
is the audio codec-ab
is the audio bitrate-o
to specify the output name but it can be omitted (the last parameter is the output name in this case)The video created with this method will play on iOS devices and will match the color of images you might have next to it.
if you have a number of sequences you have to convert, you can use a for loop to let the terminal do all the work for you.
Run the following command:
for i in 1 2 3 4 5 6 7;
do
ffmpeg -f image2 \
-i ./video$i/image${i}_d.png \
-i ./video$i/audio.mp3 \
-r 30 \
-vcodec libx264 \
-pix_fmt yuv420p \
-acodec libvo_aacenc \
-ab 128k \
./video$i/output$i.mp4;
done
Grab a beer and watch the magic happen