<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
xmlns:content="http://purl.org/rss/1.0/modules/content/"
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/">
	<channel>
		<title>How to Prevent Traveling through Time on iOS | Infinum</title>
		<atom:link href="https://infinum.com/blog/how-to-prevent-traveling-through-time-on-ios/feed/" rel="self" type="application/rss+xml" />
		<link>https://infinum.com/blog/how-to-prevent-traveling-through-time-on-ios/</link>
		<description>Building digital products</description>
		<lastBuildDate>Fri, 17 Apr 2026 13:59:15 +0000</lastBuildDate>
		<sy:updatePeriod>hourly</sy:updatePeriod>
		<sy:updateFrequency>1</sy:updateFrequency>

					<item>
				<image>
					<url>7893https://infinum.com/uploads/2020/02/how-to-prevent-traveling-through-time-on-ios-0.webp</url>
				</image>
				<title>How to Prevent Traveling through Time on iOS</title>
				<link>https://infinum.com/blog/how-to-prevent-traveling-through-time-on-ios/</link>
				<pubDate>Thu, 27 Feb 2020 12:45:00 +0000</pubDate>
				<dc:creator>Nikola Šimunko</dc:creator>
				<guid isPermaLink="false">https://infinum.com/the-capsized-eight/how-to-prevent-traveling-through-time-on-ios/</guid>
				<description>
					<![CDATA[<p>What if I told you smartphones can be manipulated to access content which was only supposed to be available for a limited period of time?</p>
<p>The post <a href="https://infinum.com/blog/how-to-prevent-traveling-through-time-on-ios/">How to Prevent Traveling through Time on iOS</a> appeared first on <a href="https://infinum.com">Infinum</a>.</p>
]]>
				</description>
				<content:encoded>
					<![CDATA[<div
	class="wrapper"
	data-id="es-156"
	 data-animation-target='inner-items'>
		
			<div class="wrapper__inner">
			<div class="block-blog-content js-block-blog-content">
	
<div class="block-blog-content-sidebar" data-id="es-92">
	</div>

<div class="block-blog-content-main">
	
<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-95"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-93">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-94'
	>
	If you’ve ever worked on an app with time-sensitive content, you know that working with date-time objects can be problematic.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-98"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-96">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-97'
	>
	Most common issues rise from working with timezones. But what if the content we are working on is supposed to only be available for a limited period of time, without the possibility to access it afterwards?</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-101"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-99">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-100'
	>
	Since time is constantly incrementing, the logical assumption would be that it’s necessary to store the time when the content first becomes available and measure the difference between right now and that point.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-104"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-102">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-103'
	>
	Pretty trivial solution, right?</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-107"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-105">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-106'
	>
	I thought the same until I came across this revelatory <a href="https://twitter.com/vixentael/status/1130944726386040834">Twitter thread</a> pointing out that it’s possible to turn back time to access time-limited content which got my attention.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-110"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-heading" data-id="es-108">
	<h2	class='typography typography--size-52-default js-typography block-heading__heading'
	data-id='es-109'
	>
	Catch 24-hours</h2></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-113"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-111">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-112'
	>
	When you type <code>Date()</code> in Swift, you get an object containing the current date, time and timezone that is set in the <code>iOS Settings -&gt; General -&gt; Date &amp;#038; time</code> menu.<br>Most users probably have the “Set automatically” option checked, which is great.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-116"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-114">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-115'
	>
	However, users who dig deep enough might discover that it is possible to set device time manually, and then, as far as your phone is concerned, you can basically travel through time.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-119"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-117">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-118'
	>
	Let’s assume that an app restricts some piece of content to be available only for 60 seconds. Could be a self-destructing message, a limited time promotional offer, or a sensitive picture (wink wink).</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-122"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-120">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-121'
	>
	You simply store the time when the content was accessed and then measure the difference in seconds on each access, but a resourceful user who knows what they are looking for can easily set the device time back to what it was when the content was initially accessed, making the content available again.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-125"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-123">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-124'
	>
	Assuming some malicious tech-savvy users could try to use this for the greater bad, let’s look at how this could be prevented.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-128"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-heading" data-id="es-126">
	<h2	class='typography typography--size-52-default js-typography block-heading__heading'
	data-id='es-127'
	>
	Boot time to the rescue</h2></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-131"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-129">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-130'
	>
	Instead of storing <code>Date</code> objects (or <code>timeIntervalSince1970</code>), you should store the device “boot time”, or to simply put it, a unit of time (ie. seconds) elapsed since the operating system was last booted.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-133"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-code">
	<pre class="phiki language-swift github-light" data-language="swift" style="background-color: #fff;color: #24292e;"><code><span class="line"><span class="token">
</span></span><span class="line"><span class="token">func uptime</span><span class="token">(</span><span class="token">)</span><span class="token"> </span><span class="token" style="color: #d73a49;">-&gt;</span><span class="token"> </span><span class="token" style="color: #005cc5;">Int</span><span class="token"> </span><span class="token">{</span><span class="token">
</span></span><span class="line"><span class="token">    </span><span class="token" style="color: #d73a49;">var</span><span class="token"> uptime </span><span class="token" style="color: #d73a49;">=</span><span class="token"> </span><span class="token">timespec(</span><span class="token">)</span><span class="token">
</span></span><span class="line"><span class="token">    </span><span class="token" style="color: #d73a49;">if</span><span class="token"> </span><span class="token">clock_gettime(</span><span class="token">CLOCK_MONOTONIC_RAW</span><span class="token">, </span><span class="token" style="color: #d73a49;">&amp;</span><span class="token">uptime</span><span class="token">)</span><span class="token"> </span><span class="token" style="color: #d73a49;">!=</span><span class="token"> </span><span class="token" style="color: #005cc5;">0</span><span class="token"> </span><span class="token">{</span><span class="token">
</span></span><span class="line"><span class="token">        </span><span class="token" style="color: #005cc5;">fatalError</span><span class="token">(</span><span class="token" style="color: #032f62;">&quot;</span><span class="token" style="color: #032f62;">Could not execute &amp;#8217;clock_gettime()&amp;#8217;</span><span class="token" style="color: #032f62;">&quot;</span><span class="token">)</span><span class="token">
</span></span><span class="line"><span class="token">    </span><span class="token">}</span><span class="token">
</span></span><span class="line"><span class="token">
</span></span><span class="line"><span class="token">    </span><span class="token" style="color: #d73a49;">return</span><span class="token"> uptime.</span><span class="token">tv_sec</span><span class="token">
</span></span><span class="line"><span class="token">}</span><span class="token">
</span></span><span class="line"><span class="token">
</span></span></code></pre></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-136"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-134">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-135'
	>
	There is a flaw in this approach.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-139"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-137">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-138'
	>
	Boot time will reset every time the device resets, which usually happens after a system update these days. That means you can still “travel through time”, but on the bright side, it does put a significant barrier on malicious users.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-142"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-140">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-141'
	>
	You could still access sensitive content, but you’d need to reset the device and measure the elapsed time from system boot to its access.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-145"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-143">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-144'
	>
	Most users wouldn’t even bother with setting the device time manually, but of those that would, I reckon most of them wouldn’t bother with boot time, even if they knew about it.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-148"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-heading" data-id="es-146">
	<h2	class='typography typography--size-52-default js-typography block-heading__heading'
	data-id='es-147'
	>
	Just to be on the safe side</h2></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-151"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-149">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-150'
	>
	For absolute certainty, you should offload this responsibility to the server and use <a href="https://searchnetworking.techtarget.com/definition/Network-Time-Protocol">Network Time Protocol</a>. It’s a great solution because no one can (hopefully) mess with the server’s boot time.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-154"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-152">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-153'
	>
	However, in cases when you cannot use NTP, eg. your app should only work offline, or you need backup for when there is no internet access, the method described earlier will be your best bet to really make access to time-limited content – limited.</p></div>	</div>
</div>
</div>		</div>
	</div><p>The post <a href="https://infinum.com/blog/how-to-prevent-traveling-through-time-on-ios/">How to Prevent Traveling through Time on iOS</a> appeared first on <a href="https://infinum.com">Infinum</a>.</p>
]]>
				</content:encoded>
			</item>
		
	</channel>
</rss>