<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Apps Archives - HangZone</title>
	<atom:link href="https://hangzone.com/category/apps/feed/" rel="self" type="application/rss+xml" />
	<link>https://hangzone.com/category/apps/</link>
	<description>Mobile App and Game Development</description>
	<lastBuildDate>Mon, 02 Apr 2018 18:31:57 +0000</lastBuildDate>
	<language>en-US</language>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	<generator>https://wordpress.org/?v=6.9.4</generator>

<image>
	<url>https://hangzone.com/wp-content/uploads/2022/04/cropped-HZ-Logo-32x32.png</url>
	<title>Apps Archives - HangZone</title>
	<link>https://hangzone.com/category/apps/</link>
	<width>32</width>
	<height>32</height>
</image> 
	<item>
		<title>Escape &#038; Avenge: A Developer Preview</title>
		<link>https://hangzone.com/escape-avenge-developer-preview/</link>
		
		<dc:creator><![CDATA[Judson Bandy]]></dc:creator>
		<pubDate>Mon, 02 Apr 2018 18:31:57 +0000</pubDate>
				<category><![CDATA[Apps]]></category>
		<category><![CDATA[Developer Insights]]></category>
		<guid isPermaLink="false">http://hangzone.com/?p=1851</guid>

					<description><![CDATA[<p>The HangZone Game Studio is still working hard. Since the release of Spelldom in 2015, we have been focusing more on contract work and enterprise app development, but the creative ...</p>
<p>The post <a href="https://hangzone.com/escape-avenge-developer-preview/">Escape &#038; Avenge: A Developer Preview</a> appeared first on <a href="https://hangzone.com">HangZone</a>.</p>
]]></description>
										<content:encoded><![CDATA[<p>The HangZone Game Studio is still working hard. Since the release of Spelldom in 2015, we have been focusing more on contract work and enterprise app development, but the creative juices are always flowing. Escape &amp; Avenge was a project that we began in late 2016. We have tinkered with the game on and off since then, and we believe that it’s a special game you will really enjoy.</p>
<p>Escape &amp; Avenge will be released in the App Store worldwide on April 4, 2018. To help you understand the game, this is the App Description from the App Store:</p>
<pre>You’re trapped in the dungeon of a medieval town. The king imprisoned you and killed the wizard—your magical friend and accomplice—for trying to overthrow the crown. At least that’s what the note on the wall says. You can’t remember anything, including who you are or how you got here. Can you escape the dungeon, return to the castle, and avenge your friend’s death? 

Escape and Avenge is an unconventional text-based adventure that reimagines the genre for mobile. With a couple quick taps, you can chain together any command you want—the perfect blend of speed, accuracy, and range of actions! Throw in some minimalist visual mini games and puzzles and you’ve got a new spin on interactive fiction! 

There are no ads or IAP—just a poor soul trapped in a dungeon who is looking for help.</pre>
<p>Now that you know a little about the game, let’s pull back the curtain, and give you a brief look at our thought process in creating E&amp;A.</p>
<h2>Initial Thoughts on Creating the Game</h2>
<p>Our initial wish for a new game was to make a text adventure using completely native iOS UI elements. We wanted a no frills look that would take complete advantage of the clean, understated beauty of the native UI. Any iOS user would feel comfortable and at home with the appearance and function of the UI. Also, a text adventure should take place primarily in the user’s imagination. By going with as standard of a UI as possible, we hoped to let the user’s mind fully engage in the game and create a completely unique view of the world of E&amp;A.</p>
<p>Besides that wish, we knew we wanted to have a map. For anyone who has played Zork, the lack of a map can be either extremely frustrating or it add to the mystique of the game. Maybe both. Regardless, we wanted something as user friendly as possible. Our hope for the map was that the player could understand the layout of the world, they could quickly warp around the world, and they could gauge some idea of progress.</p>
<p>We also wanted players to be able to see their inventory. You pick up all kinds of items, and we wanted a streamlined way for players to see what they had and get a quick description. Given the desire to have a couple of views, we immediately felt that a tabViewController would be a great native fit to display the views. Next, we needed to figure out how to execute them.</p>
<h2>Creating the Story and Text Input View</h2>
<p>The first and most glaring problem that we faced was finding a graceful way to deal with text/command input. As you probably know, most traditional text adventures have a text entry spot where the user can enter literally any command. The game certainly can’t respond appropriately to everything, but it can give a response of at least, “you can’t do that,” no matter what. The beauty is that nothing is given away to the user. The player must figure out every command, and there can even be cool easter egg responses when entering certain commands.</p>
<p>Unfortunately, mobile devices are not the easiest for inputing a large amount of text. We aren’t just talking about a few quick sentences. There’s a lot of guessing and failed attempts involved in text adventures. You’re going to try to give or use a certain item in all kinds of ways before you finally find the solution. In my mind, typing all inputs for a mobile text adventure will only appeal to a dedicated subset of regular text adventure players. You’re cannibalizing a large part of your potential audience by doing straight user text input on mobile.</p>
<p>Nevertheless, the alternative isn’t suited either. Simply giving a choice of possible commands completely written out takes away much of the allure of the text adventure. Sure, you’re still making choices and progressing through the story, but it minimizes how you think through items and how to use them.</p>
<h2>Our Answer to Text Input</h2>
<p>We are extremely happy with how our text input solution turned out. Our solution leverages native iOS tableViews, and allows the user to construct their sentences piece by piece with simple, quick taps.</p>
<p>The user is presented with all possible action verbs to begin with. Upon tapping one, they are given options for an object or modifier to go with that action. Sentences can build even further as you might start with “Use,” and then have to select an object, then a person or place to put or give the object to. It’s simple, quick, and very open-ended. Yes, it does restrict certain off the wall text inputs, but we feel the speed, accuracy, and efficiency make it the ideal solution for a mobile text adventure. We can’t wait for you to try it and get your feedback!</p>
<p><a href="http://hangzone.com/wp-content/uploads/2018/03/Blog-EA-Preview-Text-Entry.png"><img fetchpriority="high" decoding="async" class="alignnone wp-image-1854 size-medium" src="http://hangzone.com/wp-content/uploads/2018/03/Blog-EA-Preview-Text-Entry-300x258.png" alt="Blog E&amp;A Preview Text Entry" width="300" height="258" srcset="https://hangzone.com/wp-content/uploads/2018/03/Blog-EA-Preview-Text-Entry-300x258.png 300w, https://hangzone.com/wp-content/uploads/2018/03/Blog-EA-Preview-Text-Entry-1024x879.png 1024w, https://hangzone.com/wp-content/uploads/2018/03/Blog-EA-Preview-Text-Entry-300x258@2x.png 600w, https://hangzone.com/wp-content/uploads/2018/03/Blog-EA-Preview-Text-Entry-1024x879@2x.png 2048w" sizes="(max-width: 300px) 100vw, 300px" /></a></p>
<h2>Other Design Choices</h2>
<p>The design of the other elements of the game are a little more straightforward. The map and mini games (Yes, mini games!) get laid out in a storyboard along with all of the other views. Some of them are certainly nice exercises in constraints, but all were designed to be as fluid, simplistic, and minimalist as possible.</p>
<h2>On-Boarding New Players</h2>
<p>That gives you some idea on the interface design choices behind the game. There is still the issue of on-boarding new players, though. Do we need a tutorial? Do players already know how text adventures work well? There’s always the worry of on-boarding players too slowly with content that is too easy, or throwing players recklessly into a challenging, confusing world with unknown controls. Both are problems and are quick ways to lose users.</p>
<p>Our solution is one that I feel is optimal for all games if you can make it work. There is no tutorial. Players jump immediately into the game. However, the game restricts their movement as they try to solve puzzles to understand how to navigate the game. A quick mini-game opens the experience, and then, players find themselves locked in a dungeon with no way out. Both of these tasks allow the player to focus completely on a known problem as they understand the feel and objective of the game.</p>
<h2>The Story</h2>
<p>Don’t worry, no spoilers here, but know that the story is beautiful. There are a vibrant cast of characters, dropped hints, red herrings, and the satisfaction of solving puzzles to advance the story. And the twists, oh the twists! We hope that you will be engaged and brimming with emotion throughout.</p>
<p>To add more flavor to the experience, we have a number of minimalist mini games throughout the story. These will hopefully add action, fun, and excitement to the game. They also help bring the story to life. You can’t always just say you want something; sometimes you have to get it yourself!</p>
<h2>Conclusion</h2>
<p>Thanks so much for reading about our latest game, Escape &amp; Avenge. We hope that you enjoy playing the game as much as we enjoyed making it for you! You can see more about the game at our dedicated <a href="http://hangzone.com/escape-and-avenge/">Escape &amp; Avenge page</a>. If you have any questions about the game, please feel free to reach out to us. As always, thanks for reading the HangZone blog!</p>
<p>The post <a href="https://hangzone.com/escape-avenge-developer-preview/">Escape &#038; Avenge: A Developer Preview</a> appeared first on <a href="https://hangzone.com">HangZone</a>.</p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>How to Render a Superscript Registered Trademark in a Label</title>
		<link>https://hangzone.com/render-superscript-registered-trademark-label/</link>
		
		<dc:creator><![CDATA[Judson Bandy]]></dc:creator>
		<pubDate>Tue, 08 Aug 2017 17:36:15 +0000</pubDate>
				<category><![CDATA[Apps]]></category>
		<category><![CDATA[Code]]></category>
		<guid isPermaLink="false">http://hangzone.com/?p=1605</guid>

					<description><![CDATA[<p>Proper labels in your mobile apps are crucial in delivering a good experience for your users. Whether labels are used to provide information, instructions, high scores, titles, or anything else, it ...</p>
<p>The post <a href="https://hangzone.com/render-superscript-registered-trademark-label/">How to Render a Superscript Registered Trademark in a Label</a> appeared first on <a href="https://hangzone.com">HangZone</a>.</p>
]]></description>
										<content:encoded><![CDATA[<p>Proper labels in your mobile apps are crucial in delivering a good experience for your users. Whether labels are used to provide information, instructions, high scores, titles, or anything else, it is imperative to have your labels render in the correct size and format across all device types. Perfect labels are even more crucial when you are dealing with corporate branding. There is often a style code, which needs to be perfectly matched with no exceptions. When writing brandnames, this usually means that a superscript registered trademark will need to be written after the name. The ability to seamlessly include the symbol, ®, varies across different platforms and engines. Let’s take a look a how this could be accomplished.</p>
<h2>A Label in iOS</h2>
<p>Adding a superscript registered trademark symbol to a native iOS project is incredibly easy. All you need to do is include the symbol in your string. On a mac, you can press Option-R to get the symbol. If you’d like to write the symbol in unicode, in Swift you would write, “\u{00AE}” or in Objective-C, @“\u00AE”. That’s it! The UILabel will automatically format the registered trademark to be superscript. Native iOS labels make the process as painless as possible.</p>
<h2>A Label in Cocos2d-x</h2>
<p>If you are using labels with bitmap fonts in Cocos2d-x, the task is not as easy. First off, you need to include you own bitmap font files in Cocos2d-x. These include a .fnt and a .png file. Make sure that you are using an ASCII character set, or if it is something different, double check that the registered trademark is a symbol included in the file. The symbol has to be part of the character set to be displayed. Once you add your desired font to the project, try creating a label with the registered trademark symbol and running the app. The symbol appeared! Unfortunately, the symbol is not superscript, but it is the same size as the rest of the characters in the label. To make matters worse, there is no way to superscript a single letter in the label. You could try to make the registered trademark symbol a separate label or sprite and hardcode it to a specific position, but that is hardly ideal. We need a solution that can seamlessly work at any spot in a label and adjust with wrapping text. What can we do?</p>
<h2>Cocos2d-x Solution</h2>
<p>My favorite solution to this predicament is to resize the symbol in the font file’s .png file. I did this in Gimp, a free open-source raster graphics editor that we have talked about before. I simply resized the registered trademark symbol to half its size and kept the image with the exact same top left alignment. Then, in the .fnt file, find where the symbol is located. Change the width to the new width of the symbol, change the xadvance to the width of the new symbol with a small amount of padding, and leave the height the same since we are working with the same text size. That’s it! Try running the project again with the edited font file, and the registered trademark symbol should appear correctly superscripted.</p>
<h2>Conclusion</h2>
<p>Although displaying a superscript registered trademark symbol is simple in some cases, the process can be much trickier. Don’t let that hold you back as there are always clever solutions that will get you back on the road in no time. I hope this helps anyone stuck in this situation. Until next time, thanks for reading the HangZone blog.</p>
<p>The post <a href="https://hangzone.com/render-superscript-registered-trademark-label/">How to Render a Superscript Registered Trademark in a Label</a> appeared first on <a href="https://hangzone.com">HangZone</a>.</p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>Gacha Mobile App Monetization</title>
		<link>https://hangzone.com/gacha-mobile-app-monetization/</link>
		
		<dc:creator><![CDATA[Tyler Bandy]]></dc:creator>
		<pubDate>Tue, 02 May 2017 10:35:30 +0000</pubDate>
				<category><![CDATA[Apps]]></category>
		<category><![CDATA[Game Industry]]></category>
		<guid isPermaLink="false">http://hangzone.com/?p=1554</guid>

					<description><![CDATA[<p>We’ve written extensively about different mobile game monetization models. While certain monetization techniques lend themselves more naturally to different genres, the majority of the top grossing games focus on consumable ...</p>
<p>The post <a href="https://hangzone.com/gacha-mobile-app-monetization/">Gacha Mobile App Monetization</a> appeared first on <a href="https://hangzone.com">HangZone</a>.</p>
]]></description>
										<content:encoded><![CDATA[<p>We’ve written extensively about <a href="http://hangzone.com/how-to-choose-the-right-monetization-model-for-a-mobile-game/">different mobile game monetization models</a>. While certain monetization techniques lend themselves more naturally to different genres, the majority of the top grossing games focus on consumable in-app purchases (IAP). Games like Candy Crush sell players extra lives and power-ups, while town building games like Clash of Clans sell players gems to speed up production times.</p>
<p>Although these are the most familiar freemium models in the US market, there’s another category in Japan that’s wildly successful: gacha. While gacha was once isolated to the eastern markets, games like Cash Royale have taken this model to the top of the US charts. Nintendo’s recent release of Fire Emblem Heroes, a gacha title from a traditional Japanese franchise, has held fast in the top 10 grossing apps in the US, further confirming a domestic appetite for gacha.</p>
<h2>What is Gacha</h2>
<p>Gacha is an abbreviated name from the Japanese gachapon, a specialized toy vending machine. The catch is that you don’t know exactly what the toy is going to be, only that it comes from a specific set. Perhaps you’re pulling different characters from an anime. You may want a specific character, or if you’re a serious collector, you might want the entire set!</p>
<p>There are multiple reasons this dispensing method is compelling for both the buyer and seller. As the buyer makes several pulls trying to get specific characters, he will inevitably get a bunch of duplicates that he doesn&#8217;t want. Clearly, this is advantageous for the seller. There aren’t too many opportunities to sell someone something he doesn’t want! When the buyer is trying to get the last character in a set, the odds become especially good for the seller!</p>
<p>Despite stacking the odds against the buyer, it’s still an exhilarating experience to pull a character that you want! Furthermore, the cost of each individual pull is generally low enough relative to the value of what you’re hoping to get that it’s a tempting proposition. If this sounds similar to the rush a gambler gets when placing a bet, you’ve got the right idea!</p>
<h2>Gacha in Mobile Games — Puzzle and Dragons</h2>
<p>One of the first gacha games in the US market was Puzzle and Dragons (PaD). It was originally a Japanese game, and still earns the bulk of its revenue in the Japanese market. Perhaps it came to the US market too early or maybe it just helped prime the US market for the current wave of gacha games. Nevertheless, it’s still going strong.</p>
<p>The primary revenue driver in PaD is the Rare Egg Machine (REM). Players can spend five magic stones to pull the REM in hopes of getting a good character for their team. Generally, only a specific set of characters will be featured in the REM at a given time. As players collect more characters in a given set, the odds of pulling one of the remaining characters instead of a duplicate become increasingly stacked against the player. Many of the elite characters also have lower probabilities of being drawn, many at less than one percent. New characters are regularly released, and they often have better stats than existing characters. Therefore, players chase after the new characters, despite a tremendous risk of pulling duplicates of old characters. It’s not unusual for top-spending players to drop hundreds of dollars chasing after a specific new character.</p>
<p><a href="http://hangzone.com/wp-content/uploads/2017/05/Puzzle-And-Dragons-REM.png"><img decoding="async" class="alignnone wp-image-1556 size-medium" src="http://hangzone.com/wp-content/uploads/2017/05/Puzzle-And-Dragons-REM-169x300.png" alt="Puzzle And Dragons REM" width="169" height="300" srcset="https://hangzone.com/wp-content/uploads/2017/05/Puzzle-And-Dragons-REM-169x300.png 169w, https://hangzone.com/wp-content/uploads/2017/05/Puzzle-And-Dragons-REM-576x1024.png 576w, https://hangzone.com/wp-content/uploads/2017/05/Puzzle-And-Dragons-REM.png 750w, https://hangzone.com/wp-content/uploads/2017/05/Puzzle-And-Dragons-REM-169x300@2x.png 338w" sizes="(max-width: 169px) 100vw, 169px" /></a></p>
<h2>Gacha in the US Market — Clash Royale</h2>
<p>Although Puzzle and Dragons has a significant following the US, Clash Royale has been the most successful gacha title in this market. The game has regularly camped atop the top grossing list since its release in January 2016. Its monetization model is a little different than PaD, though. First of all, there are only around 50 characters in Clash Royale compared to over 3,000 in PaD. While this seems like it’s much less conducive to getting your players to chase after low probability characters, Clash Royale requires you to draw several duplicates of a character to keep leveling it up. Ultimately, this keeps players opening more chests to get the their desired characters.</p>
<p>Second, Clash Royale actually manages to include a double layer of gacha in its core game loop. Players earn a chest from winning a battle, assuming they have room to hold a new chest. Usually, they get a silver chest. Somewhat less frequently, players get a gold chest, which has more cards in it. On very rare occasion, players get a magical or super magical chest. These chests have a ton of cards in them! That doesn&#8217;t necessarily mean they&#8217;re good cards, though. Nevertheless, players get to experience the high of finding out what kind of chest they won, only to get a new rush when they&#8217;re allowed to open the chest after a timer. So much gacha!</p>
<h2>Final Gacha Thoughts</h2>
<p>Ultimately, the key to both of these games is that you can’t buy exactly what you want. You have to take a chance. Just like pulling a slot machine, your expectations are fairly low, but it might be your lucky day! If you do pull what you want, that’s a rush that players of all demographics and skill levels can enjoy. Japan has known about this for years. The US knows about it now too.</p>
<p>In addition to the techniques utilized by these two games, there are several other forms of gacha that have seen great success. <a href="http://www.gamasutra.com/blogs/YevgenGrishenko/20170309/292989/Gacha_for_Beginners.php">Gamasutra wrote extensively about different types of gacha</a>, including the now banned kompu gacha. It turns out that when you require players to collect every character in a set to unlock a new character (this is the essence of kompu or complete gacha), it&#8217;s simply too powerful of a money making technique. Even with restrictions in place, gacha yields incredible results when integrated in fun games. Expect to see a lot more gacha in the US market as developers and players alike get more comfortable with the model.</p>
<p>The post <a href="https://hangzone.com/gacha-mobile-app-monetization/">Gacha Mobile App Monetization</a> appeared first on <a href="https://hangzone.com">HangZone</a>.</p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>How to Make a Simple iPhone Game with Gestures</title>
		<link>https://hangzone.com/make-simple-iphone-game-gestures/</link>
		
		<dc:creator><![CDATA[Tyler Bandy]]></dc:creator>
		<pubDate>Mon, 17 Apr 2017 16:15:42 +0000</pubDate>
				<category><![CDATA[Apps]]></category>
		<category><![CDATA[Code]]></category>
		<category><![CDATA[Tutorials]]></category>
		<guid isPermaLink="false">http://hangzone.com/?p=1534</guid>

					<description><![CDATA[<p>Apple makes it easy to recognize gestures on iPhone and iPad. Today, we’re going to make a game that detects taps, pinches, and swipes. Much like the classic game Bop ...</p>
<p>The post <a href="https://hangzone.com/make-simple-iphone-game-gestures/">How to Make a Simple iPhone Game with Gestures</a> appeared first on <a href="https://hangzone.com">HangZone</a>.</p>
]]></description>
										<content:encoded><![CDATA[<p>Apple makes it easy to recognize gestures on iPhone and iPad. Today, we’re going to make a game that detects taps, pinches, and swipes. Much like the classic game Bop It, players will have to quickly perform a specified touch gesture on command.</p>
<p>Let’s get started! Create a new Single View Xcode project, and give your app a fun name. I’m calling mine <i>TapIt</i>. If you need some help starting a new Xcode project, be sure to check out my <a href="http://hangzone.com/beginner-ios-tutorial-choose-date-destination-part-1/">previous tutorial</a> that outlines the basic introductory steps in detail.</p>
<h2>Storyboard Layout</h2>
<p>Head to the <i>Main.storyboard</i>, and drag a label to the middle of the canvas. This will be our label that gives the player different commands. Change the text to <i>Tap It!</i>. You’re going to want that exclamation point at the end to really drive the point home. Control drag from the label to the canvas, and add a constraint to<i> Center Horizontally in Container</i>. Control drag from the label again, but this time choose <i>Center Vertically in Container</i>. In the Attributes Inspector, change <i>Font</i> to <i>System 45.0</i>. Center the text alignment. As a precaution, change <i>Autoshrink</i> to <i>Minimum Font Size</i>, and set the minimum to 10. Our command label should be ready to go!</p>
<p>Now we need a button to start a new game. Drag a button to the bottom-middle of the screen, and change the text to <i>New Game</i>. Set <i>Font</i> to <i>System 20.0</i>. We also need to add a constraint to center the button horizontally in the container, just like the command label. For the button’s vertical constraint, control drag from the button to the bottom of the canvas. Select <i>Vertical Spacing to Bottom Layout Guide</i>. That takes care of the button!</p>
<p>Finally, we want a label to show how much time the player has to make a move. You didn’t think we were going to give him all day, did you? Drag another label onto the canvas. It doesn&#8217;t really matter where you put it yet. Change the text to <i>Timer</i>, although the player will never see that written. It just makes things easier for you to visualize on the storyboard. Change <i>Font </i>to <i>System 20.0</i>. Center the text alignment. We want this label to display right where the new game button is. Don’t worry, they won’t be visible at the same time. Give the timer label a <i>Center Horizontally in Container </i>constraint. Now control drag from the timer label to the button, and give it a <i>Center Vertically</i> constraint. If you click the warning triangle, and select <i>Update Frames</i>, the timer label will move right on top of the button. We’re done laying out our objects! They should look something like this.</p>
<p><a href="http://hangzone.com/wp-content/uploads/2017/04/Tap-It-Storyboard.png"><img decoding="async" class="alignnone wp-image-1541 size-large" src="http://hangzone.com/wp-content/uploads/2017/04/Tap-It-Storyboard-1024x646.png" alt="Tap It Storyboard" width="800" height="505" srcset="https://hangzone.com/wp-content/uploads/2017/04/Tap-It-Storyboard-1024x646.png 1024w, https://hangzone.com/wp-content/uploads/2017/04/Tap-It-Storyboard-300x189.png 300w, https://hangzone.com/wp-content/uploads/2017/04/Tap-It-Storyboard.png 1505w, https://hangzone.com/wp-content/uploads/2017/04/Tap-It-Storyboard-300x189@2x.png 600w" sizes="(max-width: 800px) 100vw, 800px" /></a></p>
<h2>Hook up the Storyboard to the Code</h2>
<p>While you’re still in <i>Main.storyboard</i>, open up the<i> Assistant Editor</i>. It’s the button with the two circles at the top-right of your Xcode window. You should see <i>ViewController.swift</i> appear next to <i>Main.storyboard</i>. Control drag from the command label into <i>ViewController.swift</i>, just under the first open brace. Make the connection an outlet, and name it <i>commandLabel</i>. Now connect the button in the same manner, and call it <i>newGameButton</i>. Connect the timer label, and name it <i>remainingTimeLabel</i>.</p>
<p>After you have your three outlets, control drag from the button into <i>ViewController.swift</i> again. This time, make the connection an action, and name it <i>newGameButtonTapped</i>. Make its type <i>UIButton</i>. You’re done making connections! Your code should look like this.</p>
<pre><code>@IBOutlet weak var commandLabel: UILabel!
@IBOutlet weak var newGameButton: UIButton!
@IBOutlet weak var remainingTimeLabel: UILabel!

@IBAction func newGameButtonTapped(_ sender: UIButton) {

}
</code></pre>
<h2>Some Initial Variables</h2>
<p>Return to the <i>Standard Editor</i>, and go to <i>ViewController.swift</i>.  Let’s add some variables at the top of the file to set the stage.</p>
<pre><code>var commandIndex = 0
var gameMode = false

let maxMoveTime = 50 // move time for first move
var adjustedMaxMoveTime = 50 // move time for subsequent moves
var remainingMoveTime = 50 // move time remaining during move
</code></pre>
<p>The first variable, <i>commandIndex</i>, keeps track of what command the user is assigned. It can be 0, 1, or 2, corresponding to tap, pinch, or swipe, respectively.</p>
<p>The bool <i>gameMode</i> keeps track of whether the player is currently playing or waiting to start a new game. This is used to determine whether to process gestures.</p>
<p>The next three variables deal with the timer. The constant <i>maxMoveTime</i> equals 50. This is how long you have for your first move. We will use a variable <i>adjustedMaxMoveTime</i> to track how long you will have for each subsequent move. It will keep getting smaller! Finally, <i>remainingMoveTime</i> will always be counting down while the player is playing. If the player successfully makes a move, it will adjust back up to <i>adjustedMaxMoveTime</i>. If<i> remainingMoveTime</i> reaches zero, the player will lose.</p>
<h2>Setting Up <i>viewDidLoad</i></h2>
<p>We want to make some programmatic adjustments to our layout when the app launches. This code belongs in <i>viewDidLoad</i>.</p>
<pre><code>// hide commandLabel but don't hide button
commandLabel.isHidden = true
remainingTimeLabel.isHidden = true
newGameButton.isHidden = false

// set-up remaining time label
remainingTimeLabel.text = String(remainingMoveTime)
</code></pre>
<p>Notice that the first few lines hide the labels and display the new game button, since the player isn’t  currently playing. Then we go ahead and set <i>remainingTimeLabel</i> to equal the units of time remaining.</p>
<h2>The New Game Button</h2>
<p>Let’s return to <i>newGameButtonTapped</i> and add some code to it.</p>
<pre><code>// determine command
commandIndex = Int(arc4random_uniform(3))

// update command Label
updateCommandLabel()

// adjust label and button visibility
newGameButton.isHidden = true
commandLabel.isHidden = false
remainingTimeLabel.isHidden = false

// turn on game mode
gameMode = true
</code></pre>
<p>First, we randomly choose a command, designated as 0, 1, or 2. Then we call a separate function called <i>updateCommandLabel()</i> to display the appropriate command for that number. Then, we adjust the label and button visibility, followed by setting <em>gameMode</em> to true. The game has begun!</p>
<p>Let’s go ahead and add the <i>updateCommandLabel() </i>function. You can add it below the other functions in the class, but inside the last closing brace.</p>
<pre><code>func updateCommandLabel() {
    switch commandIndex {
    case 0:
        commandLabel.text = "Tap It!"
    case 1:
        commandLabel.text = "Pinch It!"
    case 2:
        commandLabel.text = "Swipe It!"
    default:
        commandLabel.text = "Tap It!"
    }
}
</code></pre>
<p>This is just a basic switch statement that displays the different commands based on <i>commandIndex</i>. The default case is trivial, since <i>commandIndex</i> can only equal 0, 1, or 2, but it is included since switch statements have to cover all values.</p>
<h2>The Gesture Recognizers</h2>
<p>Now it’s time for the heart of the project—the gesture recognizer code! Return to <i>viewDidLoad</i>, and add the following lines of code at the bottom.</p>
<pre><code>// listen for taps, pinches, and swipes
let tapGesture = UITapGestureRecognizer(target: self, action:  #selector (self.touchAction (_:)))
self.view.addGestureRecognizer(tapGesture)

let pinchGesture = UIPinchGestureRecognizer(target: self, action: #selector (self.pinchAction(_:)))
self.view.addGestureRecognizer(pinchGesture)

let swipeGesture = UISwipeGestureRecognizer(target: self, action: #selector (self.swipeAction(_:)))
self.view.addGestureRecognizer(swipeGesture)
</code></pre>
<p>Apple has built-in classes to recognize gestures. We just have to create an instance of these classes, and add them to the view to keep track of the gestures. Notice that we call different selectors when these gestures are recognized. Let’s add those functions to the class. Put them below your other functions, but above the <i>ViewController’s</i> bottom brace.</p>
<pre><code>func touchAction(_ sender:UITapGestureRecognizer){
    // if game mode, check if it was a good move
    if gameMode {
        if commandIndex == 0 {
            goodMove()
        } else {
            badMove()
        }
    }
}

func pinchAction(_ sender:UIPinchGestureRecognizer){
    // if game mode, check if it was a good move
    if gameMode {
        if commandIndex == 1 {
            goodMove()
        }
        // don't call bad move if it's wrong, because pinch will continue to be called several times during the gesture after the command index has changed to a different command
    }
}

func swipeAction(_ sender:UISwipeGestureRecognizer){
    // if game mode, check if it was a good move
    if gameMode {
        if commandIndex == 2 {
            goodMove()
        } else {
            badMove()
        }
    }
}
</code></pre>
<p>For all of these functions, we first check to see if <i>gameMode</i> is true. When <em>gameMode</em> is false, we don’t care about processing any gestures. If it is true, we check to see if the gesture’s index (0 for tap, 1 for pinch, 2 for swipe) corresponds to the current value of <i>commandIndex</i>. If it does, we call a new function, <i>goodMove()</i>. Otherwise, we call <i>badMove()</i>.</p>
<p>There is a notable exception with the pinch gesture. We don’t call <i>badMove() </i>if we detect a different gesture while the user is pinching. Unlike tap and swipe that only get triggered once per gesture, pinching continues to trigger over and over throughout the gesture. Unfortunately, this means that even as we switch to a new <i>commandIndex</i> after a successful pinch, the user will still be completing a pinch, and the gesture recognizer will continue to trigger. Simply not penalizing the user for pinches during a tap or swipe prompt is the easiest way to avoid this dilemma.</p>
<h2>Good Move / Bad Move</h2>
<p>We need to define the <i>goodMove()</i> and <i>badMove()</i> functions we just called. They look like this.</p>
<pre><code>func goodMove() {
    // find new command that is not equal to the current command
    if commandIndex == 0 {
        commandIndex = Int(arc4random_uniform(2)) + 1
    } else if commandIndex == 1 {
        commandIndex = Int(arc4random_uniform(2))
        if commandIndex == 1 {
            commandIndex = 2
        }
    } else {
        commandIndex = Int(arc4random_uniform(2))
    }
    // update the label
    updateCommandLabel()

    // reset the clock
    resetTheClock(true)
}

func badMove() {
    // turn off game mode
    gameMode = false

    // adjust label and button visibility
    newGameButton.isHidden = false
    commandLabel.isHidden = true
    remainingTimeLabel.isHidden = true

    // reset the clock
    resetTheClock(false)
}
</code></pre>
<p>If the user makes a good move, then we need a new command. The first bit of code does just that, while making sure we don’t give the user the same command twice in a row. After updating <i>commandLabel</i> for the new command, then we call <i>resetTheClock()</i>. We haven’t defined this function yet, but ultimately, the user will have a certain amount of time per move, and this function will refresh the timer.</p>
<p>If the user has the misfortune of playing a bad move, we flip <i>gameMode</i> to false, hide our labels, and redisplay the button to start a new game. We also refresh the clock, so the player will have a new timer for the next game.</p>
<h2>Reset the Clock</h2>
<p>Here’s the clock reset code that we call after each move.</p>
<pre><code>func resetTheClock(_ winning: Bool) {
    if winning {
        adjustedMaxMoveTime -= 5

        // don't let the timer go below 3
        if adjustedMaxMoveTime &lt; 3 {
            adjustedMaxMoveTime = 3
        }
    } else {
        adjustedMaxMoveTime = maxMoveTime
    }

    remainingMoveTime = adjustedMaxMoveTime
    remainingTimeLabel.text = String(remainingMoveTime)
}
</code></pre>
<p>The point of this function is to refresh the player’s timer, but to give the player slightly less time for each subsequent move. If the user made a good move, we decrement the user’s adjusted max time per move by 5 units. We never let this number get below 3 units. That&#8217;s too fast! Then we reset the remaining time back to this adjusted max time and update the timer label. If the player makes a bad move, then we return the adjusted max time back to its original unadjusted level of 500 units.</p>
<p>So how long is a unit you’re asking? We’ll see in our final piece of code.</p>
<h2>The Timer</h2>
<p>Return one last time to <i>viewDidLoad</i>. We need to add some timer code at the bottom.</p>
<pre><code>// schedule function in background to run down remaining move time
Timer.scheduledTimer(timeInterval: 0.1, target: self, selector: #selector(self.update), userInfo: nil, repeats: true);
</code></pre>
<p>We schedule a function called <i>update()</i> to fire every tenth of a second. This is to update the time, meaning the units of time we just discussed are in fact tenths of a second. You could change this schedule’s time interval if you want to adjust the length of our time units. Here’s what the <i>update() </i>function should look like. Add it below your other functions.</p>
<pre><code>func update() {
    // only decrement the timer during game mode
    if gameMode {
        remainingMoveTime -= 1
        remainingTimeLabel.text = String(remainingMoveTime)

        // the game is over if the player runs out of time
        if remainingMoveTime &lt; 0 {
            badMove()
        }
    }
}
</code></pre>
<p>We only want this function to do anything if the player is actually playing. Inside the if statement, we decrement the timer 1 unit every time this function is called, which is every tenth of a second. Then, we adjust the label accordingly.</p>
<p>If the timer drops below zero, then we call <i>badMove()</i>. This executes the same code that gets called when a player uses the wrong gesture. The result is the same—game over—so this way we don’t have to write the same code twice.</p>
<h2>Putting it All Together</h2>
<p>Here’s the entire <i>ViewController.swift</i>. Your functions don’t have to be in the same order.</p>
<pre><code>import UIKit

class ViewController: UIViewController {

    var commandIndex = 0
    var gameMode = false

    let maxMoveTime = 50 // move time for first move
    var adjustedMaxMoveTime = 50 // move time for subsequent moves
    var remainingMoveTime = 50 // move time remaining during move

    @IBOutlet weak var commandLabel: UILabel!
    @IBOutlet weak var newGameButton: UIButton!
    @IBOutlet weak var remainingTimeLabel: UILabel!

    @IBAction func newGameButtonTapped(_ sender: UIButton) {
        // determine command
        commandIndex = Int(arc4random_uniform(3))
        
        // update command Label
        updateCommandLabel()

        // adjust label and button visibility
        newGameButton.isHidden = true
        commandLabel.isHidden = false
        remainingTimeLabel.isHidden = false

        // turn on game mode
       gameMode = true
     }

    override func viewDidLoad() {
        super.viewDidLoad()

        // Do any additional setup after loading the view, typically from a nib.

        // hide commandLabel but don't hide button
        commandLabel.isHidden = true
        remainingTimeLabel.isHidden = true
        newGameButton.isHidden = false

        // set-up remaining time label
        remainingTimeLabel.text = String(remainingMoveTime)

        // listen for taps, pinches, and swipes
        let tapGesture = UITapGestureRecognizer(target: self, action: #selector (self.touchAction (_:)))
        self.view.addGestureRecognizer(tapGesture)

        let pinchGesture = UIPinchGestureRecognizer(target: self, action: #selector (self.pinchAction(_:)))
        self.view.addGestureRecognizer(pinchGesture)

        let swipeGesture = UISwipeGestureRecognizer(target: self, action: #selector (self.swipeAction(_:)))
        self.view.addGestureRecognizer(swipeGesture)

        // schedule function in background to run down remaining move time
        Timer.scheduledTimer(timeInterval: 0.1, target: self, selector: #selector(self.update), userInfo: nil, repeats: true);
    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }

    func updateCommandLabel() {
        switch commandIndex {
        case 0:
            commandLabel.text = "Tap It!"
        case 1:
            commandLabel.text = "Pinch It!"
        case 2:
            commandLabel.text = "Swipe It!"
        default:
            commandLabel.text = "Tap It!"
        }
    }

    func touchAction(_ sender:UITapGestureRecognizer){
        // if game mode, check if it was a good move
        if gameMode {
            if commandIndex == 0 {
                goodMove()
            } else {
                badMove()
            }
        }
    }

    func pinchAction(_ sender:UIPinchGestureRecognizer){
        // if game mode, check if it was a good move
        if gameMode {
            if commandIndex == 1 {
                goodMove()
            }
            // don't call bad move if it's wrong, because pinch will continue to be called several times during the gesture after the command index has changed to a different command
        }
    }

    func swipeAction(_ sender:UISwipeGestureRecognizer){
        // if game mode, check if it was a good move
        if gameMode {
            if commandIndex == 2 {
                goodMove()
            } else {
                badMove()
            }
        }
    }

</code><code>    func goodMove() {
        // find new command that is not equal to the current command
        if commandIndex == 0 {
            commandIndex = Int(arc4random_uniform(2)) + 
        } else if commandIndex == 1{
            commandIndex = Int(arc4random_uniform(2))
            if commandIndex == 1 {
                commandIndex = 2
            }
        } else {
            commandIndex = Int(arc4random_uniform(2))
        }

        // update the label
        updateCommandLabel()

        // reset the clock
        resetTheClock(true)
    }

    func badMove() {
        // turn off game mode
        gameMode = false

        // adjust label and button visibility
        newGameButton.isHidden = false
        commandLabel.isHidden = true
        remainingTimeLabel.isHidden = true

        // reset the clock
        resetTheClock(false)
    }

    func resetTheClock(_ winning: Bool) {
        if winning {
            adjustedMaxMoveTime -= 5

            // don't let the timer go below 3
            if adjustedMaxMoveTime &lt; 3 {
                adjustedMaxMoveTime = 3
            }
        } else {
            adjustedMaxMoveTime = maxMoveTime
        }
        remainingMoveTime = adjustedMaxMoveTime
        remainingTimeLabel.text = String(remainingMoveTime)
    }

    func update() {
        // only decrement the timer during game mode
        if gameMode {
            remainingMoveTime -= 1
            remainingTimeLabel.text = String(remainingMoveTime) 

            // the game is over if the player runs out of time
            if remainingMoveTime &lt; 0 {
                badMove()
            }
        }
    }
}
</code></pre>
<h2>Final Thoughts</h2>
<p>Run your project, and see how it works. The app could certainly use some polish, but it&#8217;s functional. Were you able to make 10 moves before it got too fast? Get some practice, because we may add a high score tracker some day!</p>
<p>You may notice that swipes only register left to right. If you want to swipe in a different direction, this presents a good opportunity to get acquainted with Apple’s iOS documentation. Here’s the <a href="https://developer.apple.com/reference/uikit/uiswipegesturerecognizerdirection">UISwipeGestureRecognizerDirection page</a>. Good luck!</p>
<p>The post <a href="https://hangzone.com/make-simple-iphone-game-gestures/">How to Make a Simple iPhone Game with Gestures</a> appeared first on <a href="https://hangzone.com">HangZone</a>.</p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>The Three Free Image Tools You Need for App Development</title>
		<link>https://hangzone.com/three-free-image-tools-need-app-development/</link>
		
		<dc:creator><![CDATA[Tyler Bandy]]></dc:creator>
		<pubDate>Tue, 04 Apr 2017 19:09:25 +0000</pubDate>
				<category><![CDATA[Apps]]></category>
		<category><![CDATA[Developer Insights]]></category>
		<guid isPermaLink="false">http://hangzone.com/?p=1530</guid>

					<description><![CDATA[<p>Let’s say you want to make your own app. If you’re a developer, you might have a good idea of how to use Xcode and write some elegant Swift code. ...</p>
<p>The post <a href="https://hangzone.com/three-free-image-tools-need-app-development/">The Three Free Image Tools You Need for App Development</a> appeared first on <a href="https://hangzone.com">HangZone</a>.</p>
]]></description>
										<content:encoded><![CDATA[<p>Let’s say you want to make your own app. If you’re a developer, you might have a good idea of how to use Xcode and write some elegant Swift code. You might not know, however, what program to use to create your images. You could always hire an artist. It’s often nice to create your own filler art during development, though. You may also need to tweak your artist’s images, or you may find it quicker to create some minor UI elements yourself. You might even want to develop your art skills, and do all aspects of the app development process yourself!</p>
<p>Regardless of how involved you want to get into the art element of app development, it’s helpful to have some basic skills with the different types of graphics you might require. You may think that you need expensive software, but there are some free alternatives that are worthy substitutes. Between the following three free programs, you’ll be equipped to handle whatever type of image you want to create.</p>
<h2>GIMP</h2>
<p>The most well-known image editing program is Adobe Photoshop, while the most well-known free counterpart is GIMP. These programs allow you to make raster graphics. You’re essentially drawing an image that’s composed of several pixels. This is ideal for drawing realistic images. You can handle intricate shading, run a variety of filters, and manage layers of complex art.</p>
<p>While GIMP is tremendous for making detailed art for a 2D game, it has two major limitations. First, you’re restricted to a 2D canvas, so you’re not going to make any models for a 3D game. Second, the raster graphics that you create in GIMP cannot be scaled up without losing quality. Since there are so many different device sizes to accommodate with your app, you need to create your images in a variety of sizes. If you’re making your images in GIMP, you want to make your images as large as possible, and scale down smaller copies as needed. If a device comes out in the future that needs a larger size image than your original, however, you’ll have to recreate the image.</p>
<p><a href="https://www.gimp.org">You can download GIMP here.</a></p>
<h2>Inkscape</h2>
<p>Unlike GIMP’s raster graphics, Inkscape (the free alternative to Adobe Illustrator) creates vector graphics. Instead of storing individual pixels, vector graphics store the shapes that compose the image as a series of equations. This makes for dramatically smaller file sizes, and it allows you to scale images up without distortion. Consequently, Inkscape is a fantastic tool to create images for your app. It is ideal for the cartoonish 2D artwork that’s popular in many classic mobile games.</p>
<p>On the negative side, you can’t create the same level of texture and realism that GIMP allows. That doesn’t necessarily mean you won’t use Inkscape for an app that requires detailed art. It’s often easier to create untextured images in Inkscape, then finish up the texture and detail in GIMP. Between these two programs, you’ve got 2D graphics covered.</p>
<p><a href="https://inkscape.org/en/">You can download Inkscape here.</a></p>
<h2>Blender</h2>
<p>When you want a 3D model, Blender is the solution. It has most of the same functionality as paid alternatives, such as Maya. You can rig your 3D models for animation and run physics simulations. If you’re creating a 3D game in Unity, this is a handy tool to have in your arsenal.</p>
<p>That’s not to say you should ignore the other graphic tools, just because you’re making a 3D app. You will likely have 2D interface elements that are better suited for GIMP or Inkscape. You also might want to apply a 2D texture to one of your 3D models. There’s a good chance you’ll make that in GIMP.</p>
<p><a href="https://www.blender.org">You can download Blender here.</a></p>
<h2>Free Art Software Recap</h2>
<p>If you’re into app development, you’re eventually going to want to create some art assets. These  three programs are all free. There’s no reason not to check them out. Even if you do have the paid version of one of these softwares, you might still want to check out the programs I highlighted here. Personally, I find Inkscape dramatically quicker than Illustrator for exporting a bunch of images stored in one project. Have fun with the artistic side of mobile app development!</p>
<p>The post <a href="https://hangzone.com/three-free-image-tools-need-app-development/">The Three Free Image Tools You Need for App Development</a> appeared first on <a href="https://hangzone.com">HangZone</a>.</p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>How to Display Updated Localized Prices for In-App Purchases</title>
		<link>https://hangzone.com/display-updated-localized-prices-app-purchases/</link>
		
		<dc:creator><![CDATA[Tyler Bandy]]></dc:creator>
		<pubDate>Mon, 27 Mar 2017 18:18:37 +0000</pubDate>
				<category><![CDATA[Apps]]></category>
		<category><![CDATA[Developer Insights]]></category>
		<guid isPermaLink="false">http://hangzone.com/?p=1525</guid>

					<description><![CDATA[<p>One of the great things about distributing your app through Apple’s App Store is the massive global audience that can download your app. Another useful aspect is that you can ...</p>
<p>The post <a href="https://hangzone.com/display-updated-localized-prices-app-purchases/">How to Display Updated Localized Prices for In-App Purchases</a> appeared first on <a href="https://hangzone.com">HangZone</a>.</p>
]]></description>
										<content:encoded><![CDATA[<p>One of the great things about distributing your app through Apple’s App Store is the massive global audience that can download your app. Another useful aspect is that you can dynamically change the price of your in-app purchases through iTunes Connect. This allows you to experiment with different price points in order to maximize your revenue. From a business standpoint, this is great. You must be careful, however, to integrate code that properly displays localized in-app purchase prices and accounts for price changes.</p>
<h2>The International Dilemma</h2>
<p>Let’s consider an example. Assume your app has a $4.99 in-app purchase. Your app probably displays some sort of storefront for selling your various in-app purchases. Although Apple displays a confirmation popup that includes the price, you most likely want to display the price on the button that initiates the transaction. Otherwise, users will be suspicious and unlikely to make the mystery purchase. Accordingly, you add a label that states the extra content costs $4.99.</p>
<p>Let’s further assume that you never change the price of the product. For your US customers, everything will be fine! The product will always cost $4.99, just like the button says. Your international users will have a bit of an issue, though. The price will be displayed in dollars, and there’s a good chance they don’t know the conversion rate to their own currency. At the very least, they don’t want to do the math! Sure, they can find out the price on the confirmation popup, but that’s not ideal.</p>
<h2>The Local Problem with Dynamic Pricing</h2>
<p>While there’s no problem for US users in the example above, what if you want to change the price to $2.99? Maybe you’ll sell enough incremental in-app purchases to offset the lower price. It’s easy enough to make the change on Apple’s servers via iTunes Connect. If you hard-coded $4.99 on the button, however, your users won’t know about the cheaper pricing until they see the confirmation.</p>
<p>Even worse, you might want to change the price to $6.99. If users tap on the $4.99 button, then see a $6.99 confirmation, they won’t be happy. It may lead to negative reviews.</p>
<h2>The Solution</h2>
<p>You need to query your available in-app purchases from Apple’s server, then grab the localized prices from the response. Specifically, here is the callback method you receive as part of the <i>SKProductsRequestDelegate</i>, along with the code to get each localized price.</p>
<pre><code>- (void)productsRequest:(SKProductsRequest *)request didReceiveResponse:(SKProductsResponse *)response {

     skProducts = response.products;

     for (SKProduct * skProduct in skProducts) {
          NSNumberFormatter *numberFormatter = [[NSNumberFormatter alloc] init];
          [numberFormatter setFormatterBehavior:NSNumberFormatterBehavior10_4];
          [numberFormatter setNumberStyle:NSNumberFormatterCurrencyStyle];
          [numberFormatter setLocale:skProduct.priceLocale];
          NSString *formattedString = [numberFormatter stringFromNumber:skProduct.price];
     }
}
</code></pre>
<p>Note that at the end of the loop, you have a property formatted and localized string of the updated in-app purchase price. You could store these prices in an array for later or go ahead and place them on buttons now.</p>
<h2>Final Thoughts</h2>
<p>Dynamic in-app purchase pricing is pretty straightforward, but it’s easy to overlook. If you don’t set things up correctly from your app’s first release, you’re really in a bind. You may adjust your code in the future to grab pricing from the server, but not all of your users will necessarily update to your new version. That leaves you worrying about whether you can start changing your prices, or if your users that haven’t updated will have a bad experience. Save yourself the trouble. Make sure to use this code from the start!</p>
<p>The post <a href="https://hangzone.com/display-updated-localized-prices-app-purchases/">How to Display Updated Localized Prices for In-App Purchases</a> appeared first on <a href="https://hangzone.com">HangZone</a>.</p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>A Beginner iOS Tutorial: Choose your Date Destination Part 2</title>
		<link>https://hangzone.com/beginner-ios-tutorial-choose-date-destination-part-2/</link>
		
		<dc:creator><![CDATA[Tyler Bandy]]></dc:creator>
		<pubDate>Tue, 21 Mar 2017 13:17:17 +0000</pubDate>
				<category><![CDATA[Apps]]></category>
		<category><![CDATA[Code]]></category>
		<category><![CDATA[Tutorials]]></category>
		<guid isPermaLink="false">http://hangzone.com/?p=1493</guid>

					<description><![CDATA[<p>In Part 1 of this beginner iOS tutorial, we created the basic shell of our app to select random date locations. It’s a functional app, and you can bust it ...</p>
<p>The post <a href="https://hangzone.com/beginner-ios-tutorial-choose-date-destination-part-2/">A Beginner iOS Tutorial: Choose your Date Destination Part 2</a> appeared first on <a href="https://hangzone.com">HangZone</a>.</p>
]]></description>
										<content:encoded><![CDATA[<p>In Part 1 of this beginner iOS tutorial, we created the basic shell of our app to select random date locations. It’s a functional app, and you can bust it out at the start of the date if you want to make an ok impression. If you want to make an excellent impression, the app needs some images, formatting, and an app icon. That’s precisely what we’re going to do today!</p>
<p>Open up your RandomDate Xcode project. In case you’ve never opened an existing Xcode project, open up Finder and navigate to the RandomDate folder that Xcode created. Inside the folder, there is a file called RandomDate.xcodeproj. Double click that, and you’re back in action! Alternatively, you can simply open Xcode and find your existing projects in the right panel.</p>
<h2>Add the Images</h2>
<p>You’ll recall we added an <i>Image View</i> in the middle of our storyboard, so that we can display an image for each venue. This will make the app more colorful, interesting, and easier to understand for visual learners. I’ve drawn some images in <em>Inkscape</em>, a free vector graphic tool. <a href="http://hangzone.com/wp-content/uploads/2017/03/Random-Date-Assets.zip">Feel free to download the images here for use in this project.</a></p>
<p>Inside the downloaded folder, you will find that there are three versions of each image. This is to handle Apple’s different device sizes. For instance, there is a <i>Random-Date-Board-Game.png</i>, <i>Random-Date-Board-Game@2x.png</i>, and <i>Random-Date-Board-Game@3x.png</i>. The image with the @2x extension has twice the length and width of the smallest version. As you might expect, the image with the @3x extension has three times the length and width of the smallest one.</p>
<p>In the left panel in Xcode, click on <em>Assets.xcassets</em>. Drag all of the image files from a Finder window anywhere into the white area below where it says <i>AppIcon</i>. You can drag them all at once. Your screen should look something like this.</p>
<p><a href="http://hangzone.com/wp-content/uploads/2017/03/Random-Date-Images-Added.png"><img decoding="async" class="alignnone wp-image-1502 size-large" src="http://hangzone.com/wp-content/uploads/2017/03/Random-Date-Images-Added-1024x572.png" alt="Random Date Images Added" width="800" height="447" srcset="https://hangzone.com/wp-content/uploads/2017/03/Random-Date-Images-Added-1024x572.png 1024w, https://hangzone.com/wp-content/uploads/2017/03/Random-Date-Images-Added-300x168.png 300w, https://hangzone.com/wp-content/uploads/2017/03/Random-Date-Images-Added-1024x572@2x.png 2048w, https://hangzone.com/wp-content/uploads/2017/03/Random-Date-Images-Added-300x168@2x.png 600w" sizes="(max-width: 800px) 100vw, 800px" /></a></p>
<p>Xcode organized all of the image sets, because it recognizes the @2x and @3x extensions. In fact, we can omit those suffixes when we reference these images in the code, and Xcode will automatically use the correct version for the device in use. That’s pretty neat, huh? Let’s go do it!</p>
<h2>Cue the Images in the Code</h2>
<p>Go to <i>ViewController.swift</i>. You’ll recall that <i>dateButtonTapped</i> changes the label on the screen. We also want it to display a picture to go with the text. If the label says <i>Movies</i>, we can display our movies image with the following code:</p>
<pre><code>dateImage.image = UIImage(named: "Random-Date-Movies")</code></pre>
<p>We need to write code for each date outing. The easiest way to do this is by nesting the appropriate code in each case of the switch statement, just as we did for the label. Once you’re done, your code should look like this.</p>
<p><a href="http://hangzone.com/wp-content/uploads/2017/03/Random-Date-Switch-Statement-Images.png"><img decoding="async" class="alignnone wp-image-1509 size-large" src="http://hangzone.com/wp-content/uploads/2017/03/Random-Date-Switch-Statement-Images-1024x572.png" alt="Random Date Switch Statement Images" width="800" height="447" srcset="https://hangzone.com/wp-content/uploads/2017/03/Random-Date-Switch-Statement-Images-1024x572.png 1024w, https://hangzone.com/wp-content/uploads/2017/03/Random-Date-Switch-Statement-Images-300x168.png 300w, https://hangzone.com/wp-content/uploads/2017/03/Random-Date-Switch-Statement-Images-1024x572@2x.png 2048w, https://hangzone.com/wp-content/uploads/2017/03/Random-Date-Switch-Statement-Images-300x168@2x.png 600w" sizes="(max-width: 800px) 100vw, 800px" /></a></p>
<p>Once you have the code in place, go ahead and run the project on your device or simulator. It will probably look ok. The label is still pretty high. The images are stretched kind of wide, at least on the iPhone 6 simulator I’m using.</p>
<p><a href="http://hangzone.com/wp-content/uploads/2017/03/Random-Date-Stretched-Image.png"><img decoding="async" class="alignnone wp-image-1508 size-large" src="http://hangzone.com/wp-content/uploads/2017/03/Random-Date-Stretched-Image-1024x572.png" alt="Random Date Stretched Image" width="800" height="447" srcset="https://hangzone.com/wp-content/uploads/2017/03/Random-Date-Stretched-Image-1024x572.png 1024w, https://hangzone.com/wp-content/uploads/2017/03/Random-Date-Stretched-Image-300x168.png 300w, https://hangzone.com/wp-content/uploads/2017/03/Random-Date-Stretched-Image-1024x572@2x.png 2048w, https://hangzone.com/wp-content/uploads/2017/03/Random-Date-Stretched-Image-300x168@2x.png 600w" sizes="(max-width: 800px) 100vw, 800px" /></a></p>
<p>We’re going to fix these issues, but before we do, try rotating your device to a landscape orientation. If you’re using the simulator, select <i>Hardware</i> from the top menu, then <i>Rotate Left</i>.</p>
<p><a href="http://hangzone.com/wp-content/uploads/2017/03/Random-Date-Rotation-Error.png"><img decoding="async" class="alignnone wp-image-1506 size-large" src="http://hangzone.com/wp-content/uploads/2017/03/Random-Date-Rotation-Error-1024x572.png" alt="Random Date Rotation Error" width="800" height="447" srcset="https://hangzone.com/wp-content/uploads/2017/03/Random-Date-Rotation-Error-1024x572.png 1024w, https://hangzone.com/wp-content/uploads/2017/03/Random-Date-Rotation-Error-300x168.png 300w, https://hangzone.com/wp-content/uploads/2017/03/Random-Date-Rotation-Error-1024x572@2x.png 2048w, https://hangzone.com/wp-content/uploads/2017/03/Random-Date-Rotation-Error-300x168@2x.png 600w" sizes="(max-width: 800px) 100vw, 800px" /></a></p>
<p>Everything is positioned poorly now! You can’t even see the button on the screen. It’s time to head back to the storyboard to tidy things up.</p>
<h2>Introduction to Auto Layout</h2>
<p>There are a variety of techniques to handle positioning between different devices and to manage rotation. These days, Apple’s recommended approach is Auto Layout. This allows us to fix all of our layout issues from the storyboard without writing any extra code!</p>
<p>Click on <i>Main.storyboard</i> in the left panel to revisit our layout. Click on the <i>UIImageView</i> in the middle of the canvas. Then hold down the control key and drag from the <i>UIImageView</i> to a blank area on the canvas. You should see a popup with several options. Select <i>Center Horizontally in Container</i>. Then do another control drag to get the same popup, and select <i>Center Vertically in Container</i>. The image will now stay centered in the screen, no matter what you do!</p>
<p><a href="http://hangzone.com/wp-content/uploads/2017/03/Random-Date-Auto-Layout-DateImage.png"><img decoding="async" class="alignnone wp-image-1498 size-large" src="http://hangzone.com/wp-content/uploads/2017/03/Random-Date-Auto-Layout-DateImage-1024x572.png" alt="Random Date Auto Layout DateImage" width="800" height="447" srcset="https://hangzone.com/wp-content/uploads/2017/03/Random-Date-Auto-Layout-DateImage-1024x572.png 1024w, https://hangzone.com/wp-content/uploads/2017/03/Random-Date-Auto-Layout-DateImage-300x168.png 300w, https://hangzone.com/wp-content/uploads/2017/03/Random-Date-Auto-Layout-DateImage-1024x572@2x.png 2048w, https://hangzone.com/wp-content/uploads/2017/03/Random-Date-Auto-Layout-DateImage-300x168@2x.png 600w" sizes="(max-width: 800px) 100vw, 800px" /></a></p>
<p>Now, control drag from the label to any blank area in the canvas. Select <i>Center Horizontally in Container</i>. This will keep the label centered horizontally, as I’m sure you expected. The vertical placement is a little bit tricker though. Control drag from the label to the top of the canvas. Select <i>Vertical Spacing to Top Layout Guide</i>. This allows us to keep the label a fixed space from the top of the screen.</p>
<p><a href="http://hangzone.com/wp-content/uploads/2017/03/Random-Date-Auto-Layout-DateLabel.png"><img decoding="async" class="alignnone wp-image-1499 size-large" src="http://hangzone.com/wp-content/uploads/2017/03/Random-Date-Auto-Layout-DateLabel-1024x572.png" alt="Random Date Auto Layout DateLabel" width="800" height="447" srcset="https://hangzone.com/wp-content/uploads/2017/03/Random-Date-Auto-Layout-DateLabel-1024x572.png 1024w, https://hangzone.com/wp-content/uploads/2017/03/Random-Date-Auto-Layout-DateLabel-300x168.png 300w, https://hangzone.com/wp-content/uploads/2017/03/Random-Date-Auto-Layout-DateLabel-1024x572@2x.png 2048w, https://hangzone.com/wp-content/uploads/2017/03/Random-Date-Auto-Layout-DateLabel-300x168@2x.png 600w" sizes="(max-width: 800px) 100vw, 800px" /></a></p>
<p>We just have to do the button now. Center it horizontally, just like we did with the image and the label. To review, control drag from the button to a blank area in the canvas. Then select <i>Center Horizontally in Container</i>. Now control drag from the button to the bottom of the canvas and select <i>Vertical Spacing to Bottom Layout Guide</i>.</p>
<p><a href="http://hangzone.com/wp-content/uploads/2017/03/Random-Date-Auto-Layout-DateButton.png"><img decoding="async" class="alignnone wp-image-1497 size-large" src="http://hangzone.com/wp-content/uploads/2017/03/Random-Date-Auto-Layout-DateButton-1024x572.png" alt="Random Date Auto Layout DateButton" width="800" height="447" srcset="https://hangzone.com/wp-content/uploads/2017/03/Random-Date-Auto-Layout-DateButton-1024x572.png 1024w, https://hangzone.com/wp-content/uploads/2017/03/Random-Date-Auto-Layout-DateButton-300x168.png 300w, https://hangzone.com/wp-content/uploads/2017/03/Random-Date-Auto-Layout-DateButton-1024x572@2x.png 2048w, https://hangzone.com/wp-content/uploads/2017/03/Random-Date-Auto-Layout-DateButton-300x168@2x.png 600w" sizes="(max-width: 800px) 100vw, 800px" /></a></p>
<h2>Auto Layout Misplaced Views</h2>
<p>Great! It seems like we’ve given everything an x and y coordinate. Hold on a second, though! There’s a red circle next to <i>View Controller Scene</i> in the storyboard’s left panel.</p>
<p><a href="http://hangzone.com/wp-content/uploads/2017/03/Random-Date-Red-Circle.png"><img decoding="async" class="alignnone wp-image-1505 size-large" src="http://hangzone.com/wp-content/uploads/2017/03/Random-Date-Red-Circle-1024x572.png" alt="Random Date Red Circle" width="800" height="447" srcset="https://hangzone.com/wp-content/uploads/2017/03/Random-Date-Red-Circle-1024x572.png 1024w, https://hangzone.com/wp-content/uploads/2017/03/Random-Date-Red-Circle-300x168.png 300w, https://hangzone.com/wp-content/uploads/2017/03/Random-Date-Red-Circle-1024x572@2x.png 2048w, https://hangzone.com/wp-content/uploads/2017/03/Random-Date-Red-Circle-300x168@2x.png 600w" sizes="(max-width: 800px) 100vw, 800px" /></a></p>
<p>Red circles tend to indicate errors in Xcode. Click on the red circle to see what’s wrong.</p>
<p><a href="http://hangzone.com/wp-content/uploads/2017/03/Random-Date-Auto-Layout-Errors.png"><img decoding="async" class="alignnone wp-image-1500 size-large" src="http://hangzone.com/wp-content/uploads/2017/03/Random-Date-Auto-Layout-Errors-1024x572.png" alt="Random Date Auto Layout Errors" width="800" height="447" srcset="https://hangzone.com/wp-content/uploads/2017/03/Random-Date-Auto-Layout-Errors-1024x572.png 1024w, https://hangzone.com/wp-content/uploads/2017/03/Random-Date-Auto-Layout-Errors-300x168.png 300w, https://hangzone.com/wp-content/uploads/2017/03/Random-Date-Auto-Layout-Errors-1024x572@2x.png 2048w, https://hangzone.com/wp-content/uploads/2017/03/Random-Date-Auto-Layout-Errors-300x168@2x.png 600w" sizes="(max-width: 800px) 100vw, 800px" /></a></p>
<p>You can see that <i>dateImage</i> is missing constraints and <i>dateLabel</i> is considered a misplaced view. The <i>dateLabel</i> issue is just a warning, as noted by the yellow triangle. Those are usually easy to fix. Just click on the yellow triangle, then select <i>Update Frames</i>. Fixed!</p>
<p><a href="http://hangzone.com/wp-content/uploads/2017/03/Random-Date-Update-Frames.png"><img decoding="async" class="alignnone wp-image-1510 size-large" src="http://hangzone.com/wp-content/uploads/2017/03/Random-Date-Update-Frames-1024x572.png" alt="Random Date Update Frames" width="800" height="447" srcset="https://hangzone.com/wp-content/uploads/2017/03/Random-Date-Update-Frames-1024x572.png 1024w, https://hangzone.com/wp-content/uploads/2017/03/Random-Date-Update-Frames-300x168.png 300w, https://hangzone.com/wp-content/uploads/2017/03/Random-Date-Update-Frames-1024x572@2x.png 2048w, https://hangzone.com/wp-content/uploads/2017/03/Random-Date-Update-Frames-300x168@2x.png 600w" sizes="(max-width: 800px) 100vw, 800px" /></a></p>
<p>Just to explain what happened, sometimes the constraints that you make will generate a different layout than what you’ve created by dragging things on the canvas manually. We updated the placement of the label on the canvas, so now they’re the same. In general, you want to choose <i>Update Frames </i>instead of <i>Update Constraints</i>. The latter option makes Xcode create constraints to match your layout on the canvas, but it will often add constraints with undesirable effects. You should make your constraints manually.</p>
<h2>Auto Layout Missing Constraints</h2>
<p>Now we just need to deal with the <i>UIImageView</i>. Although our image is centered in the middle of the screen, it doesn’t have a defined shape. Recall that the image looked stretched too wide earlier. We can fix the stretching and the red circle by adding two more constraints and tweaking a setting. First control drag from the <i>UIImageView</i> to a blank area of the canvas. Select <i>Equal Heights</i>. Obviously, we don’t want the image to be the same heigh as the entire screen, but we want them to be proportional. Select the constraint from the storyboard’s left panel, then change its <i>Multiplier </i>to 0.5 in the right panel. That will make the image half the height of the device’s screen.</p>
<p><a href="http://hangzone.com/wp-content/uploads/2017/03/Random-Date-Image-Height-Multiplier.png"><img decoding="async" class="alignnone wp-image-1501 size-large" src="http://hangzone.com/wp-content/uploads/2017/03/Random-Date-Image-Height-Multiplier-1024x572.png" alt="Random Date Image Height Multiplier" width="800" height="447" srcset="https://hangzone.com/wp-content/uploads/2017/03/Random-Date-Image-Height-Multiplier-1024x572.png 1024w, https://hangzone.com/wp-content/uploads/2017/03/Random-Date-Image-Height-Multiplier-300x168.png 300w, https://hangzone.com/wp-content/uploads/2017/03/Random-Date-Image-Height-Multiplier-1024x572@2x.png 2048w, https://hangzone.com/wp-content/uploads/2017/03/Random-Date-Image-Height-Multiplier-300x168@2x.png 600w" sizes="(max-width: 800px) 100vw, 800px" /></a></p>
<p>Now control drag from the <i>UIImageView </i>again to some blank area. Select <i>Equal Widths</i>. Select this constraint from left panel and set the <i>Multiplier</i> to 0.9 in the right panel. We’ve now defined a width and height for the image. The red circle is gone, but we still have a yellow triangle warning. Take a look at it. It’s just another misplaced view warning. Simply click on the yellow triangle like we did earlier, and select <i>Update Frames</i>. There are no more errors or warnings!</p>
<h2>Finishing Touches in the Storyboard</h2>
<p>There are a couple minor things left to do while we’re in the storyboard. Select the <i>UIImageView</i>, and set the right panel to <i>Attributes Inspector</i> mode. In the <i>Content Mode</i> blank, choose <i>Aspect Fit</i>. That will prevent our image from stretching.</p>
<p><a href="http://hangzone.com/wp-content/uploads/2017/03/Random-Date-Aspect-Fit.png"><img decoding="async" class="alignnone wp-image-1514 size-large" src="http://hangzone.com/wp-content/uploads/2017/03/Random-Date-Aspect-Fit-1024x572.png" alt="Random Date Aspect Fit" width="800" height="447" srcset="https://hangzone.com/wp-content/uploads/2017/03/Random-Date-Aspect-Fit-1024x572.png 1024w, https://hangzone.com/wp-content/uploads/2017/03/Random-Date-Aspect-Fit-300x168.png 300w, https://hangzone.com/wp-content/uploads/2017/03/Random-Date-Aspect-Fit-1024x572@2x.png 2048w, https://hangzone.com/wp-content/uploads/2017/03/Random-Date-Aspect-Fit-300x168@2x.png 600w" sizes="(max-width: 800px) 100vw, 800px" /></a></p>
<p>Let’s put a few more finishing touches on the app. While we have the <i>Attributes Inspector</i> open, select the label and change the <i>Font</i> to <i>System 30.0</i>. Change the button’s font <i>System 30.0</i> as well. We should still slide the label down from the top a bit. We made a constraint to control that earlier. Select the constraint from the storyboard’s left panel, and change its <i>Constant</i> to 20. Let&#8217;s raise the button off of the bottom of the screen as well. Select the button&#8217;s bottom layout guide constraint at set its <em>Constant</em> to 20 as well.</p>
<p><a href="http://hangzone.com/wp-content/uploads/2017/03/Random-Date-Constraint-Constant.png"><img decoding="async" class="alignnone wp-image-1515 size-large" src="http://hangzone.com/wp-content/uploads/2017/03/Random-Date-Constraint-Constant-1024x572.png" alt="Random Date Constraint Constant" width="800" height="447" srcset="https://hangzone.com/wp-content/uploads/2017/03/Random-Date-Constraint-Constant-1024x572.png 1024w, https://hangzone.com/wp-content/uploads/2017/03/Random-Date-Constraint-Constant-300x168.png 300w, https://hangzone.com/wp-content/uploads/2017/03/Random-Date-Constraint-Constant-1024x572@2x.png 2048w, https://hangzone.com/wp-content/uploads/2017/03/Random-Date-Constraint-Constant-300x168@2x.png 600w" sizes="(max-width: 800px) 100vw, 800px" /></a></p>
<p>Let’s run the project and see what we’ve got.</p>
<p><a href="http://hangzone.com/wp-content/uploads/2017/03/Random-Date-Portrait-Device.png"><img decoding="async" class="alignnone wp-image-1504 size-large" src="http://hangzone.com/wp-content/uploads/2017/03/Random-Date-Portrait-Device-1024x572.png" alt="Random Date Portrait Device" width="800" height="447" srcset="https://hangzone.com/wp-content/uploads/2017/03/Random-Date-Portrait-Device-1024x572.png 1024w, https://hangzone.com/wp-content/uploads/2017/03/Random-Date-Portrait-Device-300x168.png 300w, https://hangzone.com/wp-content/uploads/2017/03/Random-Date-Portrait-Device-1024x572@2x.png 2048w, https://hangzone.com/wp-content/uploads/2017/03/Random-Date-Portrait-Device-300x168@2x.png 600w" sizes="(max-width: 800px) 100vw, 800px" /></a></p>
<p>Perfect! It looks good in landscape orientation too!</p>
<p><a href="http://hangzone.com/wp-content/uploads/2017/03/Random-Date-Landscape-Device.png"><img decoding="async" class="alignnone wp-image-1503 size-large" src="http://hangzone.com/wp-content/uploads/2017/03/Random-Date-Landscape-Device-1024x572.png" alt="Random Date Landscape Device" width="800" height="447" srcset="https://hangzone.com/wp-content/uploads/2017/03/Random-Date-Landscape-Device-1024x572.png 1024w, https://hangzone.com/wp-content/uploads/2017/03/Random-Date-Landscape-Device-300x168.png 300w, https://hangzone.com/wp-content/uploads/2017/03/Random-Date-Landscape-Device-1024x572@2x.png 2048w, https://hangzone.com/wp-content/uploads/2017/03/Random-Date-Landscape-Device-300x168@2x.png 600w" sizes="(max-width: 800px) 100vw, 800px" /></a></p>
<h2>Adding the App Icon</h2>
<p>This is a fabulous app, but it doesn’t have an app icon yet. We should give it a cool icon, so it looks nice on your iPhone. Different iOS devices require different size icons. <a href="http://hangzone.com/wp-content/uploads/2017/03/Random-Date-Icons.zip">I put all the sizes you need in this folder for you to download.</a> Click on <i>Assets.xcassets.</i> Now click on AppIcon, which is located above all of the other image sets you added earlier. You should see blanks for all of the different app icon sizes you need.</p>
<p><a href="http://hangzone.com/wp-content/uploads/2017/03/Random-Date-App-Icon-Blanks.png"><img decoding="async" class="alignnone wp-image-1495 size-large" src="http://hangzone.com/wp-content/uploads/2017/03/Random-Date-App-Icon-Blanks-1024x572.png" alt="Random Date App Icon Blanks" width="800" height="447" srcset="https://hangzone.com/wp-content/uploads/2017/03/Random-Date-App-Icon-Blanks-1024x572.png 1024w, https://hangzone.com/wp-content/uploads/2017/03/Random-Date-App-Icon-Blanks-300x168.png 300w, https://hangzone.com/wp-content/uploads/2017/03/Random-Date-App-Icon-Blanks-1024x572@2x.png 2048w, https://hangzone.com/wp-content/uploads/2017/03/Random-Date-App-Icon-Blanks-300x168@2x.png 600w" sizes="(max-width: 800px) 100vw, 800px" /></a></p>
<p>The first two blanks are for 2x and 3x images with a length and width of 20 points. That means the app icons should be 40&#215;40 pixels and 60&#215;60 pixels, respectively (20 times 2 and 20 times 3). In the images folder you downloaded, you can find the corresponding image files, titled <i>Random-Date-Icon-20@2x.png</i> and <i>Random-Date-Icon-20@3x.png</i>, respectively. The other images follow the same naming convention. Drag each of the images to its corresponding blank in Xcode. When you’re finished, your screen should look like this.</p>
<p><a href="http://hangzone.com/wp-content/uploads/2017/03/Random-Date-App-Icons.png"><img decoding="async" class="alignnone wp-image-1496 size-large" src="http://hangzone.com/wp-content/uploads/2017/03/Random-Date-App-Icons-1024x572.png" alt="Random Date App Icons" width="800" height="447" srcset="https://hangzone.com/wp-content/uploads/2017/03/Random-Date-App-Icons-1024x572.png 1024w, https://hangzone.com/wp-content/uploads/2017/03/Random-Date-App-Icons-300x168.png 300w, https://hangzone.com/wp-content/uploads/2017/03/Random-Date-App-Icons-1024x572@2x.png 2048w, https://hangzone.com/wp-content/uploads/2017/03/Random-Date-App-Icons-300x168@2x.png 600w" sizes="(max-width: 800px) 100vw, 800px" /></a></p>
<p>Now when you run this app on your iPhone or iPad, it will have a custom app icon! If you want to see it on a simulator, click <em>Hardware</em> from the top menu, then select <em>Home</em>. This will take you to the device&#8217;s home screen.</p>
<p><a href="http://hangzone.com/wp-content/uploads/2017/03/Random-Date-Home-Screen.png"><img decoding="async" class="alignnone wp-image-1516 size-large" src="http://hangzone.com/wp-content/uploads/2017/03/Random-Date-Home-Screen-1024x572.png" alt="Random Date Home Screen" width="800" height="447" srcset="https://hangzone.com/wp-content/uploads/2017/03/Random-Date-Home-Screen-1024x572.png 1024w, https://hangzone.com/wp-content/uploads/2017/03/Random-Date-Home-Screen-300x168.png 300w, https://hangzone.com/wp-content/uploads/2017/03/Random-Date-Home-Screen-1024x572@2x.png 2048w, https://hangzone.com/wp-content/uploads/2017/03/Random-Date-Home-Screen-300x168@2x.png 600w" sizes="(max-width: 800px) 100vw, 800px" /></a></p>
<h2>Wrap-Up</h2>
<p>Congratulations! You’ve finished the tutorial and have your own iOS app. Never again do you have to worry about where you’re going to go on a date. It may very well be impossible to have a subpar date with technology like this on your iPhone. We will have to test out that theory in the field. Until then, good luck with your new app!</p>
<p>The post <a href="https://hangzone.com/beginner-ios-tutorial-choose-date-destination-part-2/">A Beginner iOS Tutorial: Choose your Date Destination Part 2</a> appeared first on <a href="https://hangzone.com">HangZone</a>.</p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>A Beginner iOS Tutorial: Choose your Date Destination Part 1</title>
		<link>https://hangzone.com/beginner-ios-tutorial-choose-date-destination-part-1/</link>
		
		<dc:creator><![CDATA[Tyler Bandy]]></dc:creator>
		<pubDate>Mon, 13 Mar 2017 08:37:13 +0000</pubDate>
				<category><![CDATA[Apps]]></category>
		<category><![CDATA[Code]]></category>
		<category><![CDATA[Tutorials]]></category>
		<guid isPermaLink="false">http://hangzone.com/?p=1462</guid>

					<description><![CDATA[<p>This will be a very simple native iOS app tutorial geared toward beginners. I’ll assume you have no experience making apps, so this should be approachable for everyone. This will ...</p>
<p>The post <a href="https://hangzone.com/beginner-ios-tutorial-choose-date-destination-part-1/">A Beginner iOS Tutorial: Choose your Date Destination Part 1</a> appeared first on <a href="https://hangzone.com">HangZone</a>.</p>
]]></description>
										<content:encoded><![CDATA[<p>This will be a very simple native iOS app tutorial geared toward beginners. I’ll assume you have no experience making apps, so this should be approachable for everyone. This will be a two part tutorial. Today, we will make the app roughly functional. Next time, we will fill out the features and polish things up.</p>
<h2>The Idea</h2>
<p>One of my friends used to play an interesting game of chance to determine where he went on dates. He would write several date destinations on pieces of paper, then let the girl randomly draw one of the options to determine their date for the evening. I could write an entire article on the merits of this system, but instead I’ll modernize the idea into app form. I witnessed this system during the archaic year of 2006. It was a simpler time. These days people need apps to complement the dating experience, so let’s get started!</p>
<h2>Create the Project in Xcode</h2>
<p>If you don’t already have Xcode on your computer, go ahead and download it. You can find it in the Mac App Store. You have to have a Mac to make apps for iPhone and iPad. I’ll wait while you go buy a Mac and/or download Xcode.</p>
<p>Open up Xcode. You’ll see a few choices. Select <em>Create a new Xcode project</em>. On the top navigation bar of the open window, select <em>iOS</em>. Then choose <em>Single View Application</em>, and hit the <em>Next</em> button.</p>
<p><a href="http://hangzone.com/wp-content/uploads/2017/03/Random-Date-Single-View-Application.png"><img decoding="async" class="alignnone wp-image-1463 size-large" src="http://hangzone.com/wp-content/uploads/2017/03/Random-Date-Single-View-Application-1024x572.png" alt="Random Date Single View Application" width="800" height="447" srcset="https://hangzone.com/wp-content/uploads/2017/03/Random-Date-Single-View-Application-1024x572.png 1024w, https://hangzone.com/wp-content/uploads/2017/03/Random-Date-Single-View-Application-300x168.png 300w, https://hangzone.com/wp-content/uploads/2017/03/Random-Date-Single-View-Application-1024x572@2x.png 2048w, https://hangzone.com/wp-content/uploads/2017/03/Random-Date-Single-View-Application-300x168@2x.png 600w" sizes="(max-width: 800px) 100vw, 800px" /></a></p>
<p>I’ll fill out the next set of blanks as follows:</p>
<ul>
<li>Product Name: RandomDate</li>
<li>Team: HangZone, LLC (You can leave it blank, unless you have a team.)</li>
<li>Organization Name: HangZone (You can put your own name here if you like.)</li>
<li>Organization Identifier: com.HangZone (You generally put <em>com.</em> before your organization name.)</li>
<li>Bundle Identifier: com.HangZone.RandomDate (This will be generated automatically from your product name and organization identifier.)</li>
<li>Language: Swift (This tutorial will be in Swift, Apple’s newest native language.)</li>
<li>Devices: Universal (This allows us to deploy to both iPhone and iPad.)</li>
<li>Uncheck the bottom options. We’re keeping this simple.</li>
</ul>
<p>Once you proceed to the next menu, you’ll have to select where you want to save the project. I have a folder where I keep all my iOS projects, so I’m going to navigate there and click the <em>Create</em> button. Feel free to save your project wherever you like.</p>
<h2>The Anatomy of an iOS Project</h2>
<p>You now have a new project in front of you. In case you haven’t used Xcode, let me quickly review the different files you’ll see on the left side of the screen. If you don’t see a menu of files on the left side of the screen, click the corresponding button in the top right (see the image below) to display the files.</p>
<p><a href="http://hangzone.com/wp-content/uploads/2017/03/Random-Date-Blank-Project.png"><img decoding="async" class="alignnone wp-image-1466 size-large" src="http://hangzone.com/wp-content/uploads/2017/03/Random-Date-Blank-Project-1024x572.png" alt="Random Date Blank Project" width="800" height="447" srcset="https://hangzone.com/wp-content/uploads/2017/03/Random-Date-Blank-Project-1024x572.png 1024w, https://hangzone.com/wp-content/uploads/2017/03/Random-Date-Blank-Project-300x168.png 300w, https://hangzone.com/wp-content/uploads/2017/03/Random-Date-Blank-Project-1024x572@2x.png 2048w, https://hangzone.com/wp-content/uploads/2017/03/Random-Date-Blank-Project-300x168@2x.png 600w" sizes="(max-width: 800px) 100vw, 800px" /></a></p>
<p>The <em>RandomDate</em> project file with the blue icon next to it lets you adjust various project settings. <em>AppDelegate.swift</em> has a set of methods for handling operations when your app starts up or closes down. <em>ViewController.swift</em> includes methods for controlling what’s on the screen. We selected a single view app, so we only have one view controller. More complex apps will have more views which are controlled by more view controllers. <em>Main.storyboard</em> lays out the views that will be controlled by the view controllers. Note that it is a blank white rectangle now, since we haven’t done anything yet. <em>Assets.xcassets</em> will hold all of our image files. <em>LaunchScreen.storyboard</em> is for laying out the screen that displays while our app is loading. <em>Info.plist</em> has some additional app settings. We will go into more detail with these different files as needed.</p>
<h2>Lay Out the Screen</h2>
<p>Click on <em>Main.storyboard</em>. You should see a white canvas that says <em>View Controller</em> at the top. You should also have a panel on the right with different objects for us to drag into the canvas. If you don’t see the right panel, there is a button at the top right of the screen, two buttons to the right of the button that reveals the left panel. In the bottom half of the right panel, make sure you’re displaying the <em>Object Library</em>, the third button over.</p>
<p><a href="http://hangzone.com/wp-content/uploads/2017/03/Random-Date-Storyboard.png"><img decoding="async" class="alignnone wp-image-1467 size-large" src="http://hangzone.com/wp-content/uploads/2017/03/Random-Date-Storyboard-1024x572.png" alt="Random Date Storyboard" width="800" height="447" srcset="https://hangzone.com/wp-content/uploads/2017/03/Random-Date-Storyboard-1024x572.png 1024w, https://hangzone.com/wp-content/uploads/2017/03/Random-Date-Storyboard-300x168.png 300w, https://hangzone.com/wp-content/uploads/2017/03/Random-Date-Storyboard-1024x572@2x.png 2048w, https://hangzone.com/wp-content/uploads/2017/03/Random-Date-Storyboard-300x168@2x.png 600w" sizes="(max-width: 800px) 100vw, 800px" /></a></p>
<p>Scroll through the <em>Object Library</em> until you find an <em>Image View</em>. Drag it into your canvas. If you’re too zoomed out, Xcode may not let you drop the object onto the canvas. Let’s place it in the middle of the canvas. This image will be a visual representation of the activity your date has randomly selected. Perhaps we could use a lion to represent the zoo.</p>
<p>We would also like a button that we can press to randomly select the date. Find a <em>Button</em> in the <em>Object Library</em> and drag it to the bottom-middle of the canvas. I’m not actually putting it at the very bottom of the canvas. Xcode provides some helpful guiding lines that show you an appropriate margin to keep your objects away from the edges. Don’t worry. We’ll place these objects more precisely later. After you’ve placed the button, double click the text and change it to <em>Select a Date</em>. That’s more self-explanatory than <em>Button</em>.</p>
<p>We also need a label to clarify the nature of the date, just in case the picture isn’t clear enough. Did that lion mean you’re going to the zoo or going big game hunting? In this current political climate, you might not want to bring up a hot button issue right off the bat (or maybe you do—I’m just here to teach you about apps).</p>
<p>Find a <em>Label</em> in the <em>Object Library</em> and drag it to the top-middle of your canvas. Stretch out the label so its box reaches the left and right guiding lines of the canvas. Now, double click the label and change the text to <em>?????</em>. That will heighten the sense of mystery. We also want the text centered. At the top of the right panel, there are 6 buttons. The fourth one from the left is the Attributes Inspector. Click that, then you should see an option to center the text. Great! Your storyboard now has all the basic objects your app needs to operate. Your screen should look something like this.</p>
<p><a href="http://hangzone.com/wp-content/uploads/2017/03/Random-Date-Initial-Layout.png"><img decoding="async" class="alignnone wp-image-1468 size-large" src="http://hangzone.com/wp-content/uploads/2017/03/Random-Date-Initial-Layout-1024x572.png" alt="Random Date Initial Layout" width="800" height="447" srcset="https://hangzone.com/wp-content/uploads/2017/03/Random-Date-Initial-Layout-1024x572.png 1024w, https://hangzone.com/wp-content/uploads/2017/03/Random-Date-Initial-Layout-300x168.png 300w, https://hangzone.com/wp-content/uploads/2017/03/Random-Date-Initial-Layout-1024x572@2x.png 2048w, https://hangzone.com/wp-content/uploads/2017/03/Random-Date-Initial-Layout-300x168@2x.png 600w" sizes="(max-width: 800px) 100vw, 800px" /></a></p>
<h2>Connecting to the Code</h2>
<p>Although we have a label, a placeholder for an image, and a button, they don’t do anything yet. They need some logic to make our app do its thing. That’s going to take some code in our <em>ViewController.swift</em> file. First, we need to let <em>ViewController.swift</em> know about these great objects we just made, so it can manipulate them. We will do that by using Assistant Editor mode. While still in <em>Main.storyboard</em>, select <em>View Controller</em> from the outline on the left. Then we will activate the Assistant Editor by tapping the button at the top with the two circles.</p>
<p><a href="http://hangzone.com/wp-content/uploads/2017/03/Random-Date-Assistant-Editor.png"><img decoding="async" class="alignnone wp-image-1469 size-large" src="http://hangzone.com/wp-content/uploads/2017/03/Random-Date-Assistant-Editor-1024x572.png" alt="Random Date Assistant Editor" width="800" height="447" srcset="https://hangzone.com/wp-content/uploads/2017/03/Random-Date-Assistant-Editor-1024x572.png 1024w, https://hangzone.com/wp-content/uploads/2017/03/Random-Date-Assistant-Editor-300x168.png 300w, https://hangzone.com/wp-content/uploads/2017/03/Random-Date-Assistant-Editor-1024x572@2x.png 2048w, https://hangzone.com/wp-content/uploads/2017/03/Random-Date-Assistant-Editor-300x168@2x.png 600w" sizes="(max-width: 800px) 100vw, 800px" /></a></p>
<p>If for some reason you don’t see the <em>ViewController.swift</em> code, make sure you have <em>View Controller</em> selected in the storyboard. If that’s not the problem, go to the <em>Product</em> dropdown menu at the top of the screen and select <em>Clean</em>. I had to do that as I was making this app. If all else fails, try restarting Xcode. Hopefully, everything worked fine and you don&#8217;t need any troubleshooting.</p>
<p>Now that we have the storyboard and code open at the same time, hold down the control key on your keyboard and drag from the storyboard label to the line below the first brace in the code.</p>
<p>You’ll get a popup box that allows you to name the object. Name it <em>dateLabel</em>. Leave the other options as their defaults.</p>
<p><a href="http://hangzone.com/wp-content/uploads/2017/03/Random-Date-DateLabel-Connection.png"><img decoding="async" class="alignnone wp-image-1470 size-large" src="http://hangzone.com/wp-content/uploads/2017/03/Random-Date-DateLabel-Connection-1024x572.png" alt="Random Date DateLabel Connection" width="800" height="447" srcset="https://hangzone.com/wp-content/uploads/2017/03/Random-Date-DateLabel-Connection-1024x572.png 1024w, https://hangzone.com/wp-content/uploads/2017/03/Random-Date-DateLabel-Connection-300x168.png 300w, https://hangzone.com/wp-content/uploads/2017/03/Random-Date-DateLabel-Connection-1024x572@2x.png 2048w, https://hangzone.com/wp-content/uploads/2017/03/Random-Date-DateLabel-Connection-300x168@2x.png 600w" sizes="(max-width: 800px) 100vw, 800px" /></a></p>
<p>Do a control drag for the image as well. Drag it right below where you dragged the label. We will use <em>dateImage</em> for its name.</p>
<p>Now control drag the button. On the <em>Connection</em> choice, change it from <em>Outlet</em> to <em>Action</em>. Name the action <em>dateButtonTapped</em>. Change the <em>Type</em> from <em>Any</em> to <em>UIButton</em>. Now hit C<em>onnect</em>.</p>
<p><a href="http://hangzone.com/wp-content/uploads/2017/03/Random-Date-DateButtonTapped-Connection.png"><img decoding="async" class="alignnone wp-image-1471 size-large" src="http://hangzone.com/wp-content/uploads/2017/03/Random-Date-DateButtonTapped-Connection-1024x572.png" alt="" width="800" height="447" srcset="https://hangzone.com/wp-content/uploads/2017/03/Random-Date-DateButtonTapped-Connection-1024x572.png 1024w, https://hangzone.com/wp-content/uploads/2017/03/Random-Date-DateButtonTapped-Connection-300x168.png 300w, https://hangzone.com/wp-content/uploads/2017/03/Random-Date-DateButtonTapped-Connection-1024x572@2x.png 2048w, https://hangzone.com/wp-content/uploads/2017/03/Random-Date-DateButtonTapped-Connection-300x168@2x.png 600w" sizes="(max-width: 800px) 100vw, 800px" /></a></p>
<p>Your code should look something like this. I added some line breaks to separate the <em>dateButtonTapped</em> connection from the other two connections, but line breaks are purely cosmetic.</p>
<p><a href="http://hangzone.com/wp-content/uploads/2017/03/Random-Date-Connections.png"><img decoding="async" class="alignnone wp-image-1472 size-large" src="http://hangzone.com/wp-content/uploads/2017/03/Random-Date-Connections-1024x572.png" alt="Random Date Connections" width="800" height="447" srcset="https://hangzone.com/wp-content/uploads/2017/03/Random-Date-Connections-1024x572.png 1024w, https://hangzone.com/wp-content/uploads/2017/03/Random-Date-Connections-300x168.png 300w, https://hangzone.com/wp-content/uploads/2017/03/Random-Date-Connections-1024x572@2x.png 2048w, https://hangzone.com/wp-content/uploads/2017/03/Random-Date-Connections-300x168@2x.png 600w" sizes="(max-width: 800px) 100vw, 800px" /></a></p>
<p>We’re done making connections now, so let’s close the Assistant Editor. The button to the left of the Assistant Editor button returns you to the Standard Editor. You should see a full screen of your storyboard. On the left side of the screen, select ViewController.swift. You should see the code where you were just making connections.</p>
<p>Before we write some code, let me explain the the purpose of the connections we added into the code. <em>dateLabel</em> and <em>dateImage</em> are variables. When we determine the random date, we’re going set the appropriate text into <em>dateLabel</em> and the corresponding image into <em>dateImage</em>. <em>dateButtonTapped</em> is a method. When the button is tapped, the code written in this method will execute. There’s no code here yet, so let’s add some!</p>
<h2>Time to Code</h2>
<p>Between the braces of <em>buttonTapped</em>, write the following code:</p>
<pre><code>let randomDateIndex = arc4random_uniform(5)
switch randomDateIndex {
case 0:
    dateLabel.text = "Movies"
case 1:
    dateLabel.text = "Bowling"
case 2:
    dateLabel.text = "Board Game"
case 3:
    dateLabel.text = "Museum"
case 4:
    dateLabel.text = "Zoo"
default:
    dateLabel.text = "?????"
}
</code></pre>
<p>Xcode should help you out and autocomplete some of the structure. Let me explain what it all does. First we create a constant called <em>randomDateIndex</em>. It will be a random nonnegative integer that doesn’t exceed 5. In other words, it will equal 0, 1, 2, 3, or 4, with a uniform probability of being any of those numbers.</p>
<p>The next bit of code is called a switch statement. Based on what value we stored in <em>randomDateIndex</em>, we will execute the code in the corresponding case of the switch statement. Notice that each case has a different potential date. There’s also a default case. Switch statements in Swift have to cover every possible case. Using default is a catch-all for all of the other cases. It’s not actually possible for our <em>randomDateIndex</em> to equal anything other than 0, 1, 2, 3, or 4, so it doesn’t particularly matter what we write in the default case in this situation.</p>
<p>Our <em>dateLabel</em> has a property called <em>text</em>. We can access it by writing <em>dateLabel.text</em>. Let’s say our <em>randomDateIndex</em> is 4. In this case, we set <em>dateLabel&#8217;s</em> text to <em>Zoo</em>. In other words, the text will change to <em>Zoo</em> when you tap the button. Your code should now look like this.</p>
<p><a href="http://hangzone.com/wp-content/uploads/2017/03/Random-Date-Switch-Statement.png"><img decoding="async" class="alignnone wp-image-1474 size-large" src="http://hangzone.com/wp-content/uploads/2017/03/Random-Date-Switch-Statement-1024x572.png" alt="Random Date Switch Statement" width="800" height="447" srcset="https://hangzone.com/wp-content/uploads/2017/03/Random-Date-Switch-Statement-1024x572.png 1024w, https://hangzone.com/wp-content/uploads/2017/03/Random-Date-Switch-Statement-300x168.png 300w, https://hangzone.com/wp-content/uploads/2017/03/Random-Date-Switch-Statement-1024x572@2x.png 2048w, https://hangzone.com/wp-content/uploads/2017/03/Random-Date-Switch-Statement-300x168@2x.png 600w" sizes="(max-width: 800px) 100vw, 800px" /></a></p>
<h2>Wrap-up</h2>
<p>Now, this is hardly the final product. We still need pictures to go with all of these dates. That includes different size pictures for different devices. We also need to position our label, image, and button a bit more elegantly. We need an app icon. There are steps to take in order for all of this to work on Apple’s various device types.</p>
<p>That’s a lot of stuff!</p>
<p>Don’t worry, though. We’ll get to that next time. Until then, you can run our incomplete project on your device or a simulator to see how it’s coming. You probably see the big triangular play button at the top left of the screen. That runs the app. The square button next to that stops the app from running. To the right of that, you’ll see a bunch of simulator choices you can choose from, or you can select your own device if it’s plugged into your computer. Choose one of the options and run it!</p>
<p><a href="http://hangzone.com/wp-content/uploads/2017/03/Random-Date-Initial-Simulator.png"><img decoding="async" class="alignnone wp-image-1473 size-large" src="http://hangzone.com/wp-content/uploads/2017/03/Random-Date-Initial-Simulator-1024x572.png" alt="Random Date Initial Simulator" width="800" height="447" srcset="https://hangzone.com/wp-content/uploads/2017/03/Random-Date-Initial-Simulator-1024x572.png 1024w, https://hangzone.com/wp-content/uploads/2017/03/Random-Date-Initial-Simulator-300x168.png 300w, https://hangzone.com/wp-content/uploads/2017/03/Random-Date-Initial-Simulator-1024x572@2x.png 2048w, https://hangzone.com/wp-content/uploads/2017/03/Random-Date-Initial-Simulator-300x168@2x.png 600w" sizes="(max-width: 800px) 100vw, 800px" /></a></p>
<p>Did you press the button? Riveting stuff. We’ll get things fully operational next time. Until then, have fun at the zoo or whatever other venue fate throws your way!</p>
<p>The post <a href="https://hangzone.com/beginner-ios-tutorial-choose-date-destination-part-1/">A Beginner iOS Tutorial: Choose your Date Destination Part 1</a> appeared first on <a href="https://hangzone.com">HangZone</a>.</p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>How to Reduce your App Bundle Size with ImageAlpha and ImageOptim</title>
		<link>https://hangzone.com/reduce-app-bundle-size-imagealpha-imageoptim/</link>
		
		<dc:creator><![CDATA[Tyler Bandy]]></dc:creator>
		<pubDate>Mon, 06 Mar 2017 14:09:24 +0000</pubDate>
				<category><![CDATA[Apps]]></category>
		<category><![CDATA[Developer Insights]]></category>
		<guid isPermaLink="false">http://hangzone.com/?p=1456</guid>

					<description><![CDATA[<p>Have you ever tried to download a large app in the App Store, only to see Apple’s 100MB warning? In order to download apps from the App Store that exceed ...</p>
<p>The post <a href="https://hangzone.com/reduce-app-bundle-size-imagealpha-imageoptim/">How to Reduce your App Bundle Size with ImageAlpha and ImageOptim</a> appeared first on <a href="https://hangzone.com">HangZone</a>.</p>
]]></description>
										<content:encoded><![CDATA[<p>Have you ever tried to download a large app in the App Store, only to see Apple’s 100MB warning?</p>
<p><a href="http://hangzone.com/wp-content/uploads/2017/03/App_Store_100MB_Limit.png"><img decoding="async" class="alignnone size-medium wp-image-1457" src="http://hangzone.com/wp-content/uploads/2017/03/App_Store_100MB_Limit-169x300.png" alt="App Store 100MB Limit" width="169" height="300" srcset="https://hangzone.com/wp-content/uploads/2017/03/App_Store_100MB_Limit-169x300.png 169w, https://hangzone.com/wp-content/uploads/2017/03/App_Store_100MB_Limit-576x1024.png 576w, https://hangzone.com/wp-content/uploads/2017/03/App_Store_100MB_Limit.png 750w, https://hangzone.com/wp-content/uploads/2017/03/App_Store_100MB_Limit-169x300@2x.png 338w" sizes="(max-width: 169px) 100vw, 169px" /></a></p>
<p>In order to download apps from the App Store that exceed 100MB, you have to use a Wi-Fi network instead of a cellular network. It’s a rule designed to help you save cellular data, but it’s kind of a nuisance. Sure, you can download the app later once you find some Wi-Fi, but what if you want satisfaction now? Moreover, what if you forget to download it later?</p>
<p>That’s the worry for many app developers, who know just how hard it is to get downloads in the first place. You don’t want to have any extra obstacles between your app and its potential users. Unfortunately, it has become harder and harder to keep apps under the 100MB threshold. As Apple keeps introducing newer devices with larger retina displays, developers have to include larger images in their app bundles. This is especially troubling for games, which often have hundreds of image assets. It doesn’t take long before you have a wealth of PNG files (with at least two duplicates of each image in different sizes to handle different devices) totaling a couple hundred MB in size.</p>
<p>This once seemed like an insurmountable challenge, but it’s a lot easier to manage than you probably expect. We’ll just cut the file sizes by about 75% with negligible downside!</p>
<h2>ImageAlpha</h2>
<p>ImageAlpha allows you to reduce the file size of PNG images with lossy compression by reducing the number of colors. Just saving everything at 256 colors will probably reduce your file sizes by around 70% with barely any discernible difference. For large background images, I like to try reducing to 128 colors and see if the image still looks good. If you still need to shrink your app bundle size, you can get creative and strategically reduce the colors on other images. Even if you stick to 256 colors, this is truly a game changing amount of file size reduction. <a href="https://pngmini.com">You can download ImageAlpha here.</a></p>
<p>Since you’ll want to use ImageAlpha on every image in your project, it may be easier to process all of your images at once. If you know you’re going to set everything to 256 colors, batch processing is certainly the way to go. If you’re comfortable with the command line, open up Terminal.</p>
<p>Assuming ImageAlpha is in your Applications folder, type in the following, but don’t hit enter yet.</p>
<pre><code>/Applications/ImageAlpha.app/Contents/MacOS/pngquant --ext .png --force 256
</code></pre>
<p>We’re going to run pngquant, the file size reduction tool behind ImageAlpha. The rest of the command notes that we want to use .png for our new file extensions and overwrite the old files with 256 color images. Before hitting enter, highlight all of the files in finder that you want to shrink and drag them into the terminal window. You’ll see a list of all their file paths appended to the command you just wrote. Finally, press enter. Your images have now been converted!</p>
<h2>ImageOptim</h2>
<p>ImageOptim further reduces file sizes by removing metadata, comments, and other unnecessary information stored in the PNG files. This doesn’t reduce your image quality at all, so there’s no downside here. You won’t get the same file size savings that ImageAlpha generates—usually only 3 to 6%—but every little bit helps. Note that you can go to preferences to set how aggressive you want the optimization to be. More savings takes more time. You can even run ImageOptim multiple times and sometimes save a little more space on subsequent runs. <a href="https://imageoptim.com">You can download ImageOptim here.</a></p>
<p>Once you have both programs downloaded, ImageAlpha and ImageOptim are designed to run in concert with each other. When you’re finished saving your image with ImageAlpha, you will see an option to run ImageOptim. It’s space saving extravaganza! Your images are now probably a quarter of their original size, and you should have a much easier time staying under the 100MB limit.</p>
<h2>Required Xcode Setting</h2>
<p>There’s one more thing you need to do to maintain all your newfound savings. Xcode has its own PNG compression tool that saves a minimal amount of space. By default, it will convert all of your images, and, in the process, negate your file size savings. Don’t let Xcode do this to you. Go to your project’s “Build Settings” and change “Compress PNG Files” to “No.” There you have it! Now your users can get your app even when they don’t have access to Wi-Fi.</p>
<p>The post <a href="https://hangzone.com/reduce-app-bundle-size-imagealpha-imageoptim/">How to Reduce your App Bundle Size with ImageAlpha and ImageOptim</a> appeared first on <a href="https://hangzone.com">HangZone</a>.</p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>Monetize your App with the Best Ad Networks</title>
		<link>https://hangzone.com/monetize-app-best-ad-networks/</link>
		
		<dc:creator><![CDATA[Tyler Bandy]]></dc:creator>
		<pubDate>Wed, 22 Feb 2017 15:43:30 +0000</pubDate>
				<category><![CDATA[Apps]]></category>
		<category><![CDATA[Developer Insights]]></category>
		<guid isPermaLink="false">http://hangzone.com/?p=1446</guid>

					<description><![CDATA[<p>Ads play a crucial role in virtually all forms of media. There are commercials on the television, pages of ads throughout magazines, and previews before the movies. You might even get ...</p>
<p>The post <a href="https://hangzone.com/monetize-app-best-ad-networks/">Monetize your App with the Best Ad Networks</a> appeared first on <a href="https://hangzone.com">HangZone</a>.</p>
]]></description>
										<content:encoded><![CDATA[<p>Ads play a crucial role in virtually all forms of media. There are commercials on the television, pages of ads throughout magazines, and previews before the movies. You might even get some not so discreet product placement during the show.</p>
<p>Ads have stood the test of time, so it should come as no surprise that they’re an important part of app monetization. With literally dozens of ad networks to choose from, each providing multiple ad formats, where do you even start? Today we will examine the different types of mobile ads in the market place.</p>
<h2>Banner Ads</h2>
<p>If you’re familiar with the Internet, you’ve most likely seen your fair share of banner ads. While websites use them in all sorts of places, banner ads on mobile apps are traditionally placed at the bottom of the screen. This was the standard ad format in the early days of the App Store. Apple actually ran an ad network called iAd, which monetized better than any other banner ads in the market. They generally looked the nicest too, due to Apple’s high design standards, so filling your banner ad space with iAds was an easy decision.</p>
<p>The ad market has changed dramatically since then. Other ad networks started showing full-screen interstitial ads, which monetized better than banner ads. Banner ads have continued to hang around, but they’re largely a relic of the early App Store. In 2016, Apple discontinued iAds. Likewise, I wouldn’t recommend banner ads.</p>
<h2>Static Interstitial Ads</h2>
<p>Known to some as pop-up ads (although that name has a bit of a negative stigma), static interstitial ads pause your app and display across the entire screen. They’re more intrusive than banner ads, but generally look nicer and aren’t on the screen the whole time. If used in moderation, I think they make for a better user experience than banner ads do. They also usually monetize better, since users are more like to tap them. Most mobile ad revenue is based on users actually installing whatever app is featured in the ad. Therefore, the higher click-through rate of interstitial ads is critical.</p>
<p>There are many players in the static interstitial ad field. TapJoy and Flurry have been among the largest players for years. Chartboost is another large player, who is one of my favorites. Their interstitial ads don’t take up quite the whole screen, and you can design a custom frame around the ad. It’s a nice feature for making the ad blend naturally into your app.</p>
<p>There are also tons of smaller players. It’s not unusual for one of these small players to offer outrageous revenue potential compared to the other networks, although this is often a short-lived phenomenon. When I first got into mobile app development, Revmob was that high-return network (I never actually used them, as their advantage was fading by the time I started to work with ads). They were delivering $10 CPMs (cost per impression) when nobody else seemed to be above $3 CPMs. The mobile ad market was and still is rather inefficient, so it’s worth staying abreast of which networks can make you the most money.</p>
<h2>Rewarded Video Ads</h2>
<p>In more recent years, rewarded video ads have become one of the most popular ad formats. The idea is that users voluntarily choose to watch a video ad in exchange for some sort of reward, generally in-game currency. These ads have the highest CPMs, often around $10. Unlike other ads, users actually want to see these, so they can get rewards. It’s a win-win situation for both you and your users!</p>
<p>There are a couple downsides to consider. Streaming video ads in your app does use cellular data, and your users might not like that. Whenever you incorporate third-party ad networks into your app, you increase the risk of bugs from different libraries not playing nicely with each other. Rewarded video ads tend to be a little more complex than other ads, and have a greater chance of error. Most notably, however, you need to be careful not to cannibalize your in-app purchase revenue. If you’re giving away too many rewards from watching ads, your users might not be as incentivized to buy things. In general, there’s more money to be made from in-app purchases than ads, so be careful.</p>
<p>There are several ad networks to consider in the rewarded video ad space. AdColony, Vungle, and Unity only do video ads, and they’re the first video ad networks people generally integrate. They each have their benefits. AdColony is nice, because revenue is based on views instead of installs. That gives you a smoother revenue steam. Vungle has a good ad inventory outside of the US, which is good for making sure you always have an ad to deliver your international users. Unity specializes in game ads, so if you think game ads are a good thematic fit for your app, they’re a good choice.</p>
<p>In addition to the major video ad networks, there are a number of small players that focus on different niches with high CPMs. MediaBrix only shows ads for major US companies, not the usual sort of ads for other apps. Their ads are more similar to the ads you see on television, except that these are sometimes interactive. They delivered us $20 CPMs, so it’s worth taking a look at some of these smaller players. Keep in mind that small networks don’t have as much ad inventory, so fill-rates won’t be as good.</p>
<h2>Ad Waterfalls</h2>
<p>So how do you stay on top of the rapidly changing ad landscape and know which network to integrate in your app? Make an ad waterfall! You can integrate several networks into your app at once, then show whichever ads are performing best. If your ad inventory with your best networks runs out, then you can show an ad from a different network. By combining multiple networks, you can effectively get the best CPM and a near 100% fill-rate. Some ad networks provide APIs for this waterfall functionality. If you’re setting up a rewarded video ad waterfall, I recommend Fyber. They’re equipped to show ads from all of the other rewarded video ad networks I mentioned earlier.</p>
<p>The sheer number of ad networks is daunting. If you’re a developer, you probably get emails on a regular basis from new ad networks promising you the best CPMs you’ve ever seen. Despite all of the noise, as long as you have a waterfall with the major players plus one or two smaller high CPM networks, you’re doing great!</p>
<p>The post <a href="https://hangzone.com/monetize-app-best-ad-networks/">Monetize your App with the Best Ad Networks</a> appeared first on <a href="https://hangzone.com">HangZone</a>.</p>
]]></content:encoded>
					
		
		
			</item>
	</channel>
</rss>
