-
Notifications
You must be signed in to change notification settings - Fork 0
/
index.html
159 lines (118 loc) · 6.03 KB
/
index.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Evgeny Shurakov</title>
<meta name="description" content="">
<link href="/favicon.png" rel="shortcut icon">
<link rel="stylesheet" href="/css/main.css">
<link rel="canonical" href="https://shurakov.name/">
<link rel="alternate" type="application/rss+xml" title="Evgeny Shurakov" href="https://shurakov.name/feed.xml">
</head>
<body>
<header class="inner global">
<div class="tagline"><a href="/">Evgeny Shurakov</a></div>
<div class="tagline2" id="tagline2">iOS and sometimes Android Developer</div>
<script>
document.addEventListener("DOMContentLoaded", function(event) {
var taglines = [
"iOS and sometimes Android Developer",
"iOS and sometimes macOS Developer",
"iOS Developer and sometimes an Artist",
"iOS Developer and sometimes a Photographer"];
var tagline = taglines[Math.floor(Math.random() * taglines.length)];
document.getElementById('tagline2').innerHTML = tagline;
});
</script>
</header>
<main class="page-content" aria-label="Content">
<div class="inner">
<article class="post">
<header>
<h2 class="title">
<a href="/prepare-for-release/">Prepare for release</a>
</h2>
<div class="meta date">Feb 2020</div>
</header>
<div class="entry-content">
<p>There is more to the process of releasing an app than archiving a project using release build configuration and uploading to the store. As the app grows you want to be sure about the quality.</p>
<p>In the mobile development world delivering the app to the customer takes time. Quite some time :-) Some years ago it was multiple days or even weeks of waiting time, now it’s a bit better and usually takes one or two days (thanks Apple!). Still, if you have a critical bug in the app that you want to fix, one or two days is a lot of time.</p>
<p>I collected several ways to help to ensure the quality of the app.</p>
<a href="/prepare-for-release/" class="more-link">Read on →</a>
</div>
</article>
<article class="post">
<header>
<h2 class="title">
<a href="/ios-localization-tips/">Localization tips for iOS</a>
</h2>
<div class="meta date">Jan 2020</div>
</header>
<div class="entry-content">
<p><strong>Start from day one</strong></p>
<p>Think about localization from day one, even if the app supports only one language. It doesn’t take much time but makes your life easier in the future.</p>
<p><strong>Use identifiers as keys</strong></p>
<ul>
<li>Use identifiers that reflect the function of the element as well as its location in the app.</li>
<li>Use the same identifier prefix for keys that belong to the same functional unit/page.</li>
</ul>
<p><strong>Write good comments</strong></p>
<p>Give the key a comment, saying where it is located on the screen, what kind of element it is, and what is the function. Describe all parameters that are used in this string. Use business terms, that is used in the app and not developers slang, cause most likely it won’t be localized by developers :-)</p>
<p><strong>Always use numbered format specifiers</strong></p>
<p>When using format specifiers, use numbered ones so that translators can shuffle them around.</p>
<p><strong>Example</strong></p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code><table class="rouge-table"><tbody><tr><td class="rouge-gutter gl"><pre class="lineno">1
2
3
4
5
6
7
8
</pre></td><td class="rouge-code"><pre>/* Action button to go to the next screen after user picks a date / Select countdown date screen / Create new event flow */
"create_event_select_countdown_date_action_button" = "Go";
/* Interval description / Select countdown date screen / Create new event flow. Parameters: %1$@ - formatted number of days (1 day, 5 days) */
"create_event_select_countdown_date_interval_description" = "Start %1$@ countdown";
/* Screen title / Select countdown date screen / Create new event flow */
"create_event_select_countdown_date_title" = "Select countdown date";
</pre></td></tr></tbody></table></code></pre></div></div>
<p><strong>Skip interface builder</strong></p>
<p>I find it very hard to localize interface builder files and storyboards.
I tried two options:</p>
<ul>
<li>one interface file per language for the same screen is <strong>a lot</strong> of work to maintain and support</li>
<li>using Xcode string export/import results in keys that don’t make sense and it’s not possible to add a comment</li>
</ul>
<p>My solution is to create UI elements in code or connect them from the interface file to the code and do all localization from the code.</p>
<p><strong>Provide screenshots</strong></p>
<p>Screenshots are a great way to understand the context in which strings are used. Understanding context is important to get quality localization.
Many of localization services (OneSky, Lokalise) provide a library that can take a screenshot and mark all keys it sees on it.</p>
<p><strong>Audit language files</strong></p>
<p>When making a release build, add a step to check that everything is localized. This can be done by going through language files and comparing key and its value. If they are the same, it means the localization is missing.</p>
</div>
</article>
</div>
</main>
<footer class="inner">
<span class="copyright">© 2022 Evgeny Shurakov</span>
<span class="separator">(◕ᴥ◕)</span>
<nav>
<ul>
<li><a href="/about/">About</a></li>
</ul>
</nav>
</footer>
<script type="text/javascript">
var _gaq = _gaq || [];
_gaq.push(['_setAccount', 'UA-18186151-1']);
_gaq.push(['_trackPageview']);
(function() {
var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
})();
</script>
</body>
</html>