Using blocks in iOS. Part 1
- From the sandbox
- Tutorial
In the process of learning Objective-C and iOS development, I could not understand how the blocks work. It was confusing that they can be passed as parameters to methods. I came across an article that seemed extremely interesting to me, since not only blocks were considered, but also the application development process. The post is adapted for xCode 7.3.1.
Blocks are an incredibly powerful addition to C / Objective-C, which allows you to "wrap" pieces of code in separate units and operate on them as objects. More and more APIs require the use of blocks in iOS, so it’s very important to understand them. However, their syntax and some subtle aspects are often confusing for beginners. But you should not be afraid - this lesson will be very useful.
In two parts of this tutorial, we will create a small iOS project called “iOS Diner”. The application itself is simple: the user selects a dish from the menu to create an order, as if about to have lunch. Caution: in the process of creation, the feeling of hunger escalates!
In the first part, we will develop the UI of our application, at the same time examining the Storyboard(literally - storyboard - approx. per.), including a small memo on the creation and use of web services for loading menus in JSON format.
Note . If you are already pretty good at Storyboard and Interface Builder , you can skip the first part and go straight to the second part , where we will start using blocks. This part focuses only on Storyboard and Interface Builder .
The second part will show the comprehensive use of blocks for programming application logic, asynchronous data processing, background tasks, use as an alternative to many standard APIs, and much more.
Open Xcode and create a new project.

In the name of the project, indicate "iOSDiner."

Run the project. Of course, it is still empty, and the simulator will have a blank white screen.

In the project settings in Deployment Info, uncheck the Portrait box .

The first thing we will do is customize the presentation. To do this, you need a little graphics. You can download from here . This will need to be added to the project resources.
To be honest, I never liked the way xCode handles matching files in a project and file system, so I usually add resources manually in the file system. In Finder, open the project folder and in it create the “Resources” folder. In it, create the “Images” folder.

Copy the graphics from the downloaded ZIP file to the Images folder, then drag the Resources folder to the IOSDiner folder in Xcode, as shown in the screenshot below.

Now you can see the Resources folder in Xcode, in which there is a subfolder Images with downloaded images, just like in the file system.
Open Main.storyboard .

If you do not see the second column with the name “ View Controller Scene ”, click on the Expand button below .
So, we are going to add images to the Storyboard as UIImageViews and UIButtons . To make it easier, open the Utilities sidebar and select Media Library .

Here we see all the earlier images added to the project. Surely you noticed that each picture has its own copy with “@ 2x” at the end of the name. It is used for the retina version.
We are only interested in the usual picture. You can check what version of the picture it is by clicking and pressing the space bar. Drag “bg_wall.png” to the root-view, as shown below. If you are not sure that the image is set correctly, you can switch to Size Inspector to change its X and Y coordinates.


Now do the same with the following images:
Note. You can force the Image View to fit the exact size of the picture by pressing Cmd and the = key at the same time . Having put all the pictures in their place, run the project.

Wow! Almost like an app! Next, add the user interface parts. In the Utilities panel, switch to the Object Library .
Drag Button to the center of our view, above the monitor. Double click on the newly added button and write “-1”.

Make sure the button is highlighted. In the Attributes Inspector, set the Background attribute to “button_silver.png.” Press and hold the Alt key and drag the -1 button to the right. This will create a copy of the object. Change its text to +1.


Drag another button to the left edge of the monitor. Set Button Type to Custom , remove the button’s title and drag “button_arrow_left.png” from the Media Library .

Copy this button and change the background image to “button_arrow.png”

And the last button remains. Place it under the board and set the background image to "total_field.png". Run the project.

It looks pretty nice. The next things we'll add are labels and a preview window.
Go to the Object Library again . Drag UILabel onto the board and stretch it to fit the board.

In Atrributes Inspector, set Lines to 0 (this will make the label multi-line), change the Text Color to white, and Font to Marker Felt 17.0. Usually, I consider the use of Marker Felt a crime, but in our case it is quite suitable.

Drag and drop the UIImageView onto the monitor.

In Attributes Inspector, change Mode to Aspect Fit.

Drag another UILabel onto the plate in the lower right. Make it the size of the gray area of the plate and set Alignment to Center.

Next, you need to establish the relationship between the user interface that we just created and the code. For this, IBOutlets and IBActions are needed . IB stands for Interface Builder , which is used to create the UI in xCode.
So, let's write some code to connect UI elements through IBOutlets and IBActions .
Close the Utilities tab and open the Assistant editor . Depending on how it is configured, the screen may not look the same as in the screenshot. If you want to change the display of the Assistant editor , look in its menu.

Let's start with the buttons. Select the -1 button, hold down the Ctrl key and drag it into the code. This automates the creation of an IBOutlet for the button.
For this object, all that is needed is to name it. I like the “ib” prefixes, because in xCode it is easy to find all the elements by autocomplete. Name this object "ibRemoveItemButton" and click Connect .

We do the same with the rest of the buttons.




Set labels in the same way.



Now ViewController.m should look like this:
Now we have to add IBActions for UIButtons . These are methods that are called in response to certain events (Touch Up Inside, Touch Up Outside, Touch Cancel, etc.). For buttons, the most commonly used Touch Up Inside.
Choose the button "-1". Again, use the Ctrl key to drag it to ViewController.m . Since this is an IBAction , we use the iba prefix. Repeat for all buttons.





Before starting the code, we’ll configure the web service. I am not going to explain everything in great detail, since there are already several lessons for this ( How To Write A Simple PHP / MySQL Web Service for an iOS App and How to Write an iOS App That Uses a Web Service ).
The code below shows what the PHP code for the web service will look like.
This web service is a very simple PHP script that returns a JSON array. The array contains the so-called associative array (PHP), or a dictionary (Objective-C), which contains the name, price and image name for the item. The only thing to note in the above code is the line
I use it to simulate a slow web service to better show how blocks can help with asynchronous operations.
You can copy this code to a file with the .php extension and place it on a hosting, or just use mine .
The draft of this part of the lesson can be downloaded here . Well, there were a lot of all sorts of things that had nothing to do with blocks. But now, having installed view and a web service , we can move on to coding, where we will use blocks to make our application fully functional.
Foreword
Blocks are an incredibly powerful addition to C / Objective-C, which allows you to "wrap" pieces of code in separate units and operate on them as objects. More and more APIs require the use of blocks in iOS, so it’s very important to understand them. However, their syntax and some subtle aspects are often confusing for beginners. But you should not be afraid - this lesson will be very useful.
In two parts of this tutorial, we will create a small iOS project called “iOS Diner”. The application itself is simple: the user selects a dish from the menu to create an order, as if about to have lunch. Caution: in the process of creation, the feeling of hunger escalates!
In the first part, we will develop the UI of our application, at the same time examining the Storyboard(literally - storyboard - approx. per.), including a small memo on the creation and use of web services for loading menus in JSON format.
Note . If you are already pretty good at Storyboard and Interface Builder , you can skip the first part and go straight to the second part , where we will start using blocks. This part focuses only on Storyboard and Interface Builder .
The second part will show the comprehensive use of blocks for programming application logic, asynchronous data processing, background tasks, use as an alternative to many standard APIs, and much more.
Getting started
Open Xcode and create a new project.

In the name of the project, indicate "iOSDiner."

Run the project. Of course, it is still empty, and the simulator will have a blank white screen.

In the project settings in Deployment Info, uncheck the Portrait box .

The first thing we will do is customize the presentation. To do this, you need a little graphics. You can download from here . This will need to be added to the project resources.
To be honest, I never liked the way xCode handles matching files in a project and file system, so I usually add resources manually in the file system. In Finder, open the project folder and in it create the “Resources” folder. In it, create the “Images” folder.

Copy the graphics from the downloaded ZIP file to the Images folder, then drag the Resources folder to the IOSDiner folder in Xcode, as shown in the screenshot below.

Now you can see the Resources folder in Xcode, in which there is a subfolder Images with downloaded images, just like in the file system.
Adding Images
Open Main.storyboard .

If you do not see the second column with the name “ View Controller Scene ”, click on the Expand button below .
So, we are going to add images to the Storyboard as UIImageViews and UIButtons . To make it easier, open the Utilities sidebar and select Media Library .

Here we see all the earlier images added to the project. Surely you noticed that each picture has its own copy with “@ 2x” at the end of the name. It is used for the retina version.
We are only interested in the usual picture. You can check what version of the picture it is by clicking and pressing the space bar. Drag “bg_wall.png” to the root-view, as shown below. If you are not sure that the image is set correctly, you can switch to Size Inspector to change its X and Y coordinates.


Now do the same with the following images:
- person.png
- sign_theiOSdiner.png
- chalkboard.png
- bg_counter.png
- total_field.png
- food_box.png
Note. You can force the Image View to fit the exact size of the picture by pressing Cmd and the = key at the same time . Having put all the pictures in their place, run the project.

Wow! Almost like an app! Next, add the user interface parts. In the Utilities panel, switch to the Object Library .
Drag Button to the center of our view, above the monitor. Double click on the newly added button and write “-1”.

Round rect button
В оригинале использовались Round Rect Button, которые отсутствуют в xCode 7.3.1. На Stack Overflow есть решение, как их использовать.
Make sure the button is highlighted. In the Attributes Inspector, set the Background attribute to “button_silver.png.” Press and hold the Alt key and drag the -1 button to the right. This will create a copy of the object. Change its text to +1.


Drag another button to the left edge of the monitor. Set Button Type to Custom , remove the button’s title and drag “button_arrow_left.png” from the Media Library .

Copy this button and change the background image to “button_arrow.png”

And the last button remains. Place it under the board and set the background image to "total_field.png". Run the project.

It looks pretty nice. The next things we'll add are labels and a preview window.
Go to the Object Library again . Drag UILabel onto the board and stretch it to fit the board.

In Atrributes Inspector, set Lines to 0 (this will make the label multi-line), change the Text Color to white, and Font to Marker Felt 17.0. Usually, I consider the use of Marker Felt a crime, but in our case it is quite suitable.

Drag and drop the UIImageView onto the monitor.

In Attributes Inspector, change Mode to Aspect Fit.

Drag another UILabel onto the plate in the lower right. Make it the size of the gray area of the plate and set Alignment to Center.

Install IBOutlets and IBActions
Next, you need to establish the relationship between the user interface that we just created and the code. For this, IBOutlets and IBActions are needed . IB stands for Interface Builder , which is used to create the UI in xCode.
- IBOutlet , basically, is the relationship of a UI element (button or label) with its link in the code.
- IBAction is an action (or method, as it is more convenient) in the code that can be connected to some event (button click, for example) in the developed interface.
So, let's write some code to connect UI elements through IBOutlets and IBActions .
Close the Utilities tab and open the Assistant editor . Depending on how it is configured, the screen may not look the same as in the screenshot. If you want to change the display of the Assistant editor , look in its menu.

Let's start with the buttons. Select the -1 button, hold down the Ctrl key and drag it into the code. This automates the creation of an IBOutlet for the button.
For this object, all that is needed is to name it. I like the “ib” prefixes, because in xCode it is easy to find all the elements by autocomplete. Name this object "ibRemoveItemButton" and click Connect .

We do the same with the rest of the buttons.




Set labels in the same way.



Now ViewController.m should look like this:
#import "ViewController.h"@interfaceViewController ()@property (weak, nonatomic) IBOutletUIButton *ibRemoveItemButton;
@property (weak, nonatomic) IBOutletUIButton *ibAddItemButton;
@property (weak, nonatomic) IBOutletUIButton *ibPreviousItemButton;
@property (weak, nonatomic) IBOutletUIButton *ibNextItemButton;
@property (weak, nonatomic) IBOutletUIButton *ibTotalOrderButton;
@property (weak, nonatomic) IBOutletUILabel *ibChalkboardLabel;
@property (weak, nonatomic) IBOutletUIImageView *ibCurrentItemImageView;
@property (weak, nonatomic) IBOutletUILabel *ibCurrentItemLabel;
@end@implementationViewController
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
@end
Now we have to add IBActions for UIButtons . These are methods that are called in response to certain events (Touch Up Inside, Touch Up Outside, Touch Cancel, etc.). For buttons, the most commonly used Touch Up Inside.
Choose the button "-1". Again, use the Ctrl key to drag it to ViewController.m . Since this is an IBAction , we use the iba prefix. Repeat for all buttons.





Install the web service
Before starting the code, we’ll configure the web service. I am not going to explain everything in great detail, since there are already several lessons for this ( How To Write A Simple PHP / MySQL Web Service for an iOS App and How to Write an iOS App That Uses a Web Service ).
The code below shows what the PHP code for the web service will look like.
<?phpfunctiongetStatusCodeMessage($status){
$codes = Array(
100 => 'Continue',
101 => 'Switching Protocols',
200 => 'OK',
201 => 'Created',
202 => 'Accepted',
203 => 'Non-Authoritative Information',
204 => 'No Content',
205 => 'Reset Content',
206 => 'Partial Content',
300 => 'Multiple Choices',
301 => 'Moved Permanently',
302 => 'Found',
303 => 'See Other',
304 => 'Not Modified',
305 => 'Use Proxy',
306 => '(Unused)',
307 => 'Temporary Redirect',
400 => 'Bad Request',
401 => 'Unauthorized',
402 => 'Payment Required',
403 => 'Forbidden',
404 => 'Not Found',
405 => 'Method Not Allowed',
406 => 'Not Acceptable',
407 => 'Proxy Authentication Required',
408 => 'Request Timeout',
409 => 'Conflict',
410 => 'Gone',
411 => 'Length Required',
412 => 'Precondition Failed',
413 => 'Request Entity Too Large',
414 => 'Request-URI Too Long',
415 => 'Unsupported Media Type',
416 => 'Requested Range Not Satisfiable',
417 => 'Expectation Failed',
500 => 'Internal Server Error',
501 => 'Not Implemented',
502 => 'Bad Gateway',
503 => 'Service Unavailable',
504 => 'Gateway Timeout',
505 => 'HTTP Version Not Supported'
);
return (isset($codes[$status])) ? $codes[$status] : '';
}
// Helper method to send a HTTP response code/messagefunctionsendResponse($status = 200, $body = '', $content_type = 'text/html'){
$status_header = 'HTTP/1.1 ' . $status . ' ' . getStatusCodeMessage($status);
header($status_header);
header('Content-type: ' . $content_type);
echo $body;
}
classInventoryAPI{
functiongetInventory(){
$inventory = array(
array("Name"=>"Hamburger","Price"=>0.99,"Image"=>"food_hamburger.png"),
array("Name"=>"Cheeseburger","Price"=>1.20,"Image"=>"food_cheeseburger.png"),
array("Name"=>"Fries","Price"=>0.69,"Image"=>"food_fries.png"),
array("Name"=>"Onion Rings","Price"=>0.69,"Image"=>"food_onion-rings.png"),
array("Name"=>"Soda","Price"=>0.75,"Image"=>"food_soda.png"),
array("Name"=>"Shake","Price"=>1.20,"Image"=>"food_milkshake.png")
);
sendResponse(200, json_encode($inventory));
}
}
sleep(5);
$api = new InventoryAPI;
$api->getInventory();
?>
This web service is a very simple PHP script that returns a JSON array. The array contains the so-called associative array (PHP), or a dictionary (Objective-C), which contains the name, price and image name for the item. The only thing to note in the above code is the line
sleep(5);
. I use it to simulate a slow web service to better show how blocks can help with asynchronous operations.
You can copy this code to a file with the .php extension and place it on a hosting, or just use mine .
What to do next
The draft of this part of the lesson can be downloaded here . Well, there were a lot of all sorts of things that had nothing to do with blocks. But now, having installed view and a web service , we can move on to coding, where we will use blocks to make our application fully functional.