Probably, every developer, when he begins to master a new technology, wants to try everything on his own, to implement everything from the lowest level, so that later he can enjoy the result of his work. However, with the accumulation of experience, many tasks become quite boring and I want to save myself from this necessary, but uninteresting routine. In this article I want to share what ways and means will help simplify the life of the developer and save nerves.
Setup of the project, development environment, connection of libraries, snippeta
This is one of the first and easiest, but still essential actions, however many articles have already been written about it, such as
this ,
this ,
this and there is hardly any developer who does not know this, therefore we will not dwell on this. Also, quite a lot of useful plugins are written for Xcode, a review article on which you can read
here .
Own CocoaPods repository
In addition to connecting your favorite or necessary libraries for this project via CocoaPods, you can add your repository with the most frequent “helper functions”. For example, who does not bother to write the following code:
[self.subviews makeObjectsPerformSelector:@selector(removeFromSuperview)];
or
')
NSData *data = [responseString dataUsingEncoding:NSUTF8StringEncoding]; return [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingMutableContainers error:nil];
To rid myself of this, I use a repository on
GitHub with useful categories that greatly reduce coding. Using it, it can all be rewritten as follows:
[self removeAllSubviews]; return responseString.JSON;
Localization of the application
Almost always you need to make at least two or three project localizations. Xcode has its own means for this, and Apple developers should be honored for improving them, but still this is not the most convenient way, especially if the application is already in the AppStore and you need to release an update - you have enough problems with Base Internationalization, so with Localizable.Strings. Those who have already encountered this know that Xcode cannot add or update values ​​in localized * .strings files for Storyboard, and also the genstrings utility expects only new added strings to enter, unless we want to regenerate all occurrences again.
Let's start with Localizable.Strings. I allocate a separate h-file for NSLocalizedString, for example StringConstants.h, in which localized strings are defined via #define. With this approach, you can kill two birds with one stone:
- Collect common phrases and words, such as "Cancel", "Exit", "Invalid login or password", etc., which are likely to be present in any project, so that you can carry it with you with ready-made lines
- Reuse existing lines within the project, without typing the long and inconvenient NSLocalizedString macro each time.
So, displaying a standard UIAlertView with an error message will look like this:
[[[UIAlertView alloc] initWithTitle:kErrorString message:kInvalidLoginOrPasswordString delegate:nil cancelButtonTitle:@"OK" otherButtonTitles:nil] show];
As for the generation of localized files, for this I use the second h-file, NewStringConstants.h, to which I add those entries that need to be localized, and then delete them. Directly in Localizable.Strings new entries add script to Build Phases:
cd ${PROJECT_DIR}/MyProject genstrings -a -o Base.lproj NewStringConstants.h genstrings -a -o ru.lproj NewStringConstants.h genstrings -a -o pt-PT.lproj NewStringConstants.h genstrings -a -o es.lproj NewStringConstants.h
All that remains to be done after this is to write local string values ​​in Localizable.Strings files.
With Storyboard, the task is also solved through a script, which is discussed in detail in
this article. Here I want to briefly mention that the essence of the script is that it extracts the lines from the Storyboard using the ibtool utility, and when called it checks whether any changes have occurred. If the latter are present, the localized strings are exported, after which the localized files are merged. Again, it remains to correct the localized files. I also want to mention the AppleGlot tool, which is described in the above article, but it uses a different approach in an iterative localization update. The choice of a particular tool remains for the developer, depending on his preferences.
Application Testing
Here we will talk about the manual testing of the application in a limited number of devices. No matter how much code is covered by unit tests, manual testing cannot be ruled out. Basically, this is done by the developer himself during the creation of the application, but when it is ready, you need to transfer the application to an ordinary user who does not have an eye and who will use the application as an uninitiated average user. It is good if there is a complete set of devices with all supported operating systems, but this is not generally the case. Even if there is a whole line of devices, then, as a rule, they do not differ in the variety of operating systems, which is basically not necessary, of course, but it will not hurt to check. The iOS simulator will come to the rescue, which can be configured by selecting the desired item from the drop-down menu. However, without additional actions, the tester will have to transfer source codes, which is not always acceptable. Next, I will describe how you can transfer the assembled application for testing on the iOS simulator and which one you need to install for this additional software.
Installing sim_launcher and ios-sim
gem install sim_launcher brew install ios-sim
sim_launcher allows you to run iOS applications in the simulator via HTTP GET requests. This is convenient because all the organizational work for testing can be organized in a browser, without forcing the user to remember the terminal commands. ios-sim is a kind of wrapper on the terminal commands, simplifying work with the simulator. It seems that sim_launcher has not been updated for some time, so it is not compatible with the latest version of ios-sim. You need to correct the following functions in the simulator.rb file located in the sim_launcher installation folder:
Fixes simulator.rb def start_simulator(sdk_version, device_family) sdk_version ||= SdkDetector.new(self).latest_sdk_version run_synchronous_command( :start, '--devicetypeid', sdk_version, '--exit' ) end def launch_ios_app(app_path, sdk_version, device_family, app_args = nil) if problem = SimLauncher.check_app_path( app_path ) bangs = '!'*80 raise "\n#{bangs}\nENCOUNTERED A PROBLEM WITH THE SPECIFIED APP PATH:\n\n#{problem}\n#{bangs}" end sdk_version ||= SdkDetector.new(self).latest_sdk_version args = ["--args"] + app_args.flatten if app_args run_synchronous_command( :launch, app_path, '--devicetypeid', sdk_version, '--exit', *args ) end
Running the build on the simulator
sim_launcher
This command raises the web service on port 8881. Instead of <path-to-app> specifying the full path to the .app file, go to the browser at
http: // localhost: 8881 / launch_iphone_app? Sdk = com.apple.CoreSimulator.SimDeviceType.iPhone-6,% 208.1 & app_path = <path-to-app> . If the iPhone 6 simulator with iOS 8.1 opens, then everything is working properly. If any errors appear in the browser window, then, most likely, something is wrong with the source code sim_launcher, or the .app file does not support work in the simulator. You can build the simulator using the following command:
xcodebuild -workspace MyProject.xcworkspace -scheme MyProject -arch i386 -sdk iphonesimulator
Finishing touches
Running the simulator from the browser is convenient, but manually typing the address is not very cool. You can create a small html-page that would provide some convenient UI tester. The simplest implementation is as follows:

HTML code <!DOCTYPE HTML> <html> <head> <meta charset="utf-8"> <title>Testing utility</title> </head> <body> <form action="http://localhost:8881/launch_iphone_app" method="get" target="_blank"> <p><select name="sdk" size="15"> <option disabled>Select a device</option> <option value="com.apple.CoreSimulator.SimDeviceType.iPhone-4s, 7.1">iPhone 4s iOS 7.1</option> <option value="com.apple.CoreSimulator.SimDeviceType.iPhone-5, 7.1">iPhone 5 iOS 7.1</option> <option value="com.apple.CoreSimulator.SimDeviceType.iPhone-5s, 7.1">iPhone 5s iOS 7.1</option> <option value="com.apple.CoreSimulator.SimDeviceType.iPad-2, 7.1">iPad 2 iOS 7.1</option> <option value="com.apple.CoreSimulator.SimDeviceType.iPad-Retina, 7.1">iPad Retina iOS 7.1</option> <option value="com.apple.CoreSimulator.SimDeviceType.iPad-Air, 7.1">iPad Air iOS 7.1</option> <option value="com.apple.CoreSimulator.SimDeviceType.iPhone-4s, 8.1">iPhone 4s iOS 8.1</option> <option value="com.apple.CoreSimulator.SimDeviceType.iPhone-5, 8.1">iPhone 5 iOS 8.1</option> <option value="com.apple.CoreSimulator.SimDeviceType.iPhone-6-Plus, 8.1">iPhone 6 Plus iOS 8.1</option> <option value="com.apple.CoreSimulator.SimDeviceType.iPhone-6, 8.1">iPhone 6 iOS 8.1</option> <option value="com.apple.CoreSimulator.SimDeviceType.iPad-Retina, 8.1">iPhad Retina iOS 8.1</option> <option value="com.apple.CoreSimulator.SimDeviceType.iPad-Air, 8.1">iPad Air iOS 8.1</option> </select></p> <p><input name="app_path"/></p> <p><input type="submit" value="Run"/></p> </form> </body> </html>
The list of simulators that are currently available for launch via ios-sim can be obtained using the command
ios-sim showdevicetypes
Cutting design
I think that a lot of iOS developers in parallel are, if not experienced, then quite advanced users of Adobe Photoshop, because sometimes you have to refine or export something from layouts. To cut the interface elements, you can connect a
script that will do it in a couple of clicks.
Application Publishing
For a good design of the application page in the AppStore, you must provide it with appropriate screenshots. In addition to the need to do them for each supported device, you must also take care of all localizations. Without automation, this process also carries the
pain of a lot of chore. The site
fastlane.tools provides a diagram of the automation of many processes related both to testing, continuous integration, and the publication of the application. All source codes are laid out in open access, and also there is an instruction to them. Here I just want to comment on the part on working with screenshots. Using the UI Automation, a script is prepared that the simulator will execute in automatic mode, in the right places of which you need to add the command to create a screenshot. Separate scripts for phones and tablets are supported. All screenshots are sorted by localization and stored in separate folders, as well as generated overview html-page. With the help of another script, all screenshots can be downloaded to iTunesConnect also without user intervention. Thus, it remains only to adjust the parameters.
On this I would like to complete this article. I hope it will be useful not only for those who have just begun to learn or are interested in the charms of iOS development, but also for experienced developers who may not have known that you can entrust a lot of boring work to a computer, keeping the most interesting development. In the comments I propose to discuss, if any, other tools and methods to speed up or simplify some tasks.