mirror of https://github.com/lukechilds/docs.git
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
1171 lines
67 KiB
1171 lines
67 KiB
<!DOCTYPE html>
|
|
<html lang="en">
|
|
|
|
<head>
|
|
<meta charset="utf-8">
|
|
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
|
<!-- Begin Jekyll SEO tag v2.5.0 -->
|
|
<title>iOS SDK Tutorial (Pre-release) | Blockstack</title>
|
|
<meta name="generator" content="Jekyll v3.8.3" />
|
|
<meta property="og:title" content="iOS SDK Tutorial (Pre-release)" />
|
|
<meta name="author" content="Blockstack" />
|
|
<meta property="og:locale" content="en_US" />
|
|
<meta name="description" content="iOS SDK Tutorial (Pre-release)" />
|
|
<meta property="og:description" content="iOS SDK Tutorial (Pre-release)" />
|
|
<link rel="canonical" href="https://zbabystack.netlify.com/ios/tutorial.html" />
|
|
<meta property="og:url" content="https://zbabystack.netlify.com/ios/tutorial.html" />
|
|
<meta property="og:site_name" content="Blockstack" />
|
|
<meta property="og:type" content="article" />
|
|
<meta property="article:published_time" content="2018-09-10T15:18:11-07:00" />
|
|
<script type="application/ld+json">
|
|
{"description":"iOS SDK Tutorial (Pre-release)","author":{"@type":"Person","name":"Blockstack"},"@type":"BlogPosting","url":"https://zbabystack.netlify.com/ios/tutorial.html","headline":"iOS SDK Tutorial (Pre-release)","dateModified":"2018-09-10T15:18:11-07:00","datePublished":"2018-09-10T15:18:11-07:00","mainEntityOfPage":{"@type":"WebPage","@id":"https://zbabystack.netlify.com/ios/tutorial.html"},"@context":"http://schema.org"}</script>
|
|
<!-- End Jekyll SEO tag -->
|
|
|
|
<!-- <meta property="og:image" content="https://zbabystack.netlify.com/assets/posts/logo.png"/> -->
|
|
<meta property="og:image" content="/assets/posts/logo.png"/>
|
|
<link rel="stylesheet" href="/assets/css/main.css">
|
|
<link rel="shortcut icon" type="image/png" href="/assets/img/touch-icon.png" >
|
|
<link rel="alternate" type="application/rss+xml" title="Blockstack" href="/feed.xml">
|
|
<script src="/assets/js/main.js"></script>
|
|
|
|
</head>
|
|
|
|
|
|
<body>
|
|
|
|
<header class="uk-background-secondary">
|
|
<div data-uk-sticky="sel-target: .uk-navbar-container; cls-active: uk-navbar-sticky" class="uk-sticky uk-sticky-fixed" style="position: fixed; top: 0px; width: 1904px;">
|
|
<nav class="uk-navbar-container">
|
|
<div class="uk-container">
|
|
<div data-uk-navbar>
|
|
<div class="uk-navbar-left">
|
|
|
|
<!-- <a class="uk-navbar-item uk-logo" href="/"><img src="https://zbabystack.netlify.com/assets/posts/logo.png" alt="Docs"></a> -->
|
|
<a class="uk-navbar-item uk-logo" href="/"><img src="/assets/posts/logo.png" alt="Docs"></a>
|
|
|
|
</div>
|
|
<div class="uk-navbar-right">
|
|
<ul class="uk-navbar-nav uk-visible@m">
|
|
|
|
|
|
|
|
|
|
<li><a href="https://blockstack.org" target="_blank" >Blockstack.org</a></li>
|
|
|
|
|
|
|
|
|
|
|
|
<li><a href="https://forum.blockstack.org/" target="_blank" >Forums</a></li>
|
|
|
|
|
|
|
|
|
|
|
|
<li><a href="https://github.com/blockstack" target="_blank" >GitHub</a></li>
|
|
|
|
|
|
</ul>
|
|
|
|
|
|
<div>
|
|
<a class="uk-navbar-toggle" uk-search-icon href="#"></a>
|
|
<div class="uk-drop uk-background-default uk-border-rounded" uk-drop="mode: click; pos: left-center; offset: 0">
|
|
<form class="uk-search uk-search-navbar uk-width-1-1" onsubmit="return false;">
|
|
<input id="searchBox" class="uk-search-input" type="search" placeholder="Search..." autofocus>
|
|
</form>
|
|
<ul id="searchBox-results" class="uk-position-absolute uk-width-1-1 uk-list"></ul>
|
|
</div>
|
|
</div>
|
|
|
|
|
|
<a class="uk-navbar-toggle uk-hidden@m" href="#offcanvas" data-uk-navbar-toggle-icon data-uk-toggle></a>
|
|
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
</nav>
|
|
</div>
|
|
</header>
|
|
|
|
|
|
|
|
|
|
<div class="uk-section">
|
|
<div class="uk-container">
|
|
<div class="uk-grid-large" data-uk-grid>
|
|
|
|
<div class="sidebar-fixed-width uk-visible@m">
|
|
<div class="sidebar-docs uk-position-fixed">
|
|
<!-- -->
|
|
|
|
|
|
<h5>Try a tutorial</h5>
|
|
|
|
<ul class="uk-nav uk-nav-default doc-nav">
|
|
|
|
|
|
<!-- -->
|
|
|
|
<li class=""><a href="/browser/hello-blockstack.html">Hello, Blockstack Tutorial</a></li>
|
|
|
|
|
|
<!-- -->
|
|
|
|
<li class=""><a href="/browser/multi-player-storage.html">Manage Data with Gaia</a></li>
|
|
|
|
</ul>
|
|
|
|
|
|
<h5>Work with an SDK</h5>
|
|
|
|
<ul class="uk-nav uk-nav-default doc-nav">
|
|
|
|
|
|
<!-- -->
|
|
|
|
<li class=""><a href="/android/tutorial.html">Android SDK Tutorial (Pre-release)</a></li>
|
|
|
|
|
|
<!-- -->
|
|
|
|
<li class="uk-active"><a href="/ios/tutorial.html">iOS SDK Tutorial (Pre-release)</a></li>
|
|
|
|
</ul>
|
|
|
|
|
|
<h5>Reference</h5>
|
|
|
|
<ul class="uk-nav uk-nav-default doc-nav">
|
|
|
|
|
|
<!-- -->
|
|
|
|
<li class=""><a href="/core/faq_developer.html">Developer FAQs</a></li>
|
|
|
|
|
|
<!-- -->
|
|
|
|
<li class=""><a href="/common/javascript_ref.html">Blockstack Javascript Reference</a></li>
|
|
|
|
</ul>
|
|
|
|
<!-- -->
|
|
</div>
|
|
</div>
|
|
|
|
<div class="uk-width-1-1 uk-width-expand@m">
|
|
|
|
<article class="uk-article">
|
|
|
|
<h1 class="uk-article-title">iOS SDK Tutorial (Pre-release)</h1>
|
|
|
|
|
|
|
|
|
|
<div class="uk-article-meta uk-margin-top uk-margin-medium-bottom">
|
|
|
|
|
|
|
|
<!-- <img class="avatar avatar-small" alt="Blockstack" width="32" height="32" data-proofer-ignore="true" src="https://avatars2.githubusercontent.com/Blockstack?v=3&s=32" srcset="https://avatars2.githubusercontent.com/Blockstack?v=3&s=32 1x, https://avatars2.githubusercontent.com/Blockstack?v=3&s=64 2x, https://avatars2.githubusercontent.com/Blockstack?v=3&s=96 3x, https://avatars2.githubusercontent.com/Blockstack?v=3&s=128 4x" /> -->
|
|
|
|
|
|
|
|
<!-- Written by <span itemprop="author" itemscope itemtype="http://schema.org/Person"><span itemprop="name">Blockstack</span></span><br> -->
|
|
|
|
|
|
<time datetime="2018-09-10T15:18:11-07:00" itemprop="datePublished">
|
|
|
|
|
|
|
|
<a "target="_blank" href="https://github.com/blockstack/blockstack-ios/blob/master/docs/tutorial.md" class="btn btn-default githubEditButton" role="button">
|
|
<span data-uk-icon="icon: pencil; ratio: 1.2"></span> Edit this page on Github</a>
|
|
<span style="font-family:Wingdings">w</span> Sep 10, 2018
|
|
</time>
|
|
|
|
</div>
|
|
|
|
<div class="article-content">
|
|
|
|
<p class="no_toc">This tutorial teaches you how to create a decentralized application using
|
|
Blockstack’s iOS SDK using the following content:</p>
|
|
|
|
<ul id="markdown-toc">
|
|
<li><a href="#understand-the-sample-application-flow" id="markdown-toc-understand-the-sample-application-flow">Understand the sample application flow</a></li>
|
|
<li><a href="#set-up-your-environment" id="markdown-toc-set-up-your-environment">Set up your environment</a> <ul>
|
|
<li><a href="#install-xcode" id="markdown-toc-install-xcode">Install XCode</a></li>
|
|
<li><a href="#do-you-have-npm" id="markdown-toc-do-you-have-npm">Do you have npm?</a></li>
|
|
<li><a href="#install-the-cocoapods-160beta1-dependency-manager" id="markdown-toc-install-the-cocoapods-160beta1-dependency-manager">Install the CocoaPods 1.6.0.beta.1 dependency manager</a></li>
|
|
<li><a href="#use-npm-to-install-yeoman-and-the-blockstack-app-generator" id="markdown-toc-use-npm-to-install-yeoman-and-the-blockstack-app-generator">Use npm to install Yeoman and the Blockstack App Generator</a></li>
|
|
</ul>
|
|
</li>
|
|
<li><a href="#build-the-blockstack-hello-world" id="markdown-toc-build-the-blockstack-hello-world">Build the Blockstack hello-world</a> <ul>
|
|
<li><a href="#generate-and-launch-your-hello-blockstack-application" id="markdown-toc-generate-and-launch-your-hello-blockstack-application">Generate and launch your hello-blockstack application</a></li>
|
|
<li><a href="#add-a-redirect-end-point-to-your-application" id="markdown-toc-add-a-redirect-end-point-to-your-application">Add a redirect end point to your application</a></li>
|
|
</ul>
|
|
</li>
|
|
<li><a href="#build-the-hello-blockstack-ios" id="markdown-toc-build-the-hello-blockstack-ios">Build the hello-blockstack-ios</a> <ul>
|
|
<li><a href="#create-an-xcode-project" id="markdown-toc-create-an-xcode-project">Create an XCode Project</a></li>
|
|
<li><a href="#add-and-edit-a-podfile" id="markdown-toc-add-and-edit-a-podfile">Add and edit a Podfile</a></li>
|
|
<li><a href="#install-blockstack-sdk-and-open-the-pod-project" id="markdown-toc-install-blockstack-sdk-and-open-the-pod-project">Install Blockstack SDK and open the pod project</a></li>
|
|
<li><a href="#choose-a-custom-protocol-handler" id="markdown-toc-choose-a-custom-protocol-handler">Choose a custom protocol handler</a></li>
|
|
<li><a href="#add-a-splash-screen" id="markdown-toc-add-a-splash-screen">Add a splash screen</a></li>
|
|
<li><a href="#update-the-mainstoryboard" id="markdown-toc-update-the-mainstoryboard">Update the Main.storyboard</a></li>
|
|
<li><a href="#add-the-ui-variables-to-the-viewcontroller-file" id="markdown-toc-add-the-ui-variables-to-the-viewcontroller-file">Add the UI variables to the ViewController file.</a></li>
|
|
<li><a href="#edit-the-viewcontrollerswift-file" id="markdown-toc-edit-the-viewcontrollerswift-file">Edit the ViewController.swift file</a></li>
|
|
</ul>
|
|
</li>
|
|
<li><a href="#troubleshooting-your-build-in-xcode" id="markdown-toc-troubleshooting-your-build-in-xcode">Troubleshooting your build in XCode</a></li>
|
|
</ul>
|
|
|
|
<p>This tutorial was extensively tested using XCode 9.3 on a MacBook Air
|
|
running High Sierra 10.13.4. If your environment is different, you may encounter
|
|
slight or even major discrepancies when performing the procedures in this
|
|
tutorial. Please <a href="https://slofile.com/slack/blockstack">join the Blockstack community Slack</a> and post questions or comments to
|
|
the <code class="highlighter-rouge">#support</code> channel.</p>
|
|
|
|
<p>Finally, this tutorial is written for all levels from the beginner to the most
|
|
experienced. For best results, beginners should follow the guide as written. It
|
|
is expected that the fast or furiously brilliant will skip ahead and improvise
|
|
on this material at will. God speed one and all.</p>
|
|
|
|
<p>If you prefer, you can skip working through the tutorial all together. Instead,
|
|
you can <a href="#">download the final project code</a> and import it
|
|
into XCode to review it.</p>
|
|
|
|
<h2 id="understand-the-sample-application-flow">Understand the sample application flow</h2>
|
|
|
|
<p>When complete, the sample application is a simple <code class="highlighter-rouge">hello-world</code> intended for use
|
|
on an iOS phone.</p>
|
|
|
|
<p><img src="images/final-app.png" alt="" /></p>
|
|
|
|
<p>Only users with an existing <code class="highlighter-rouge">blockstack.id</code> can run your
|
|
final sample application. When complete, users interact with the sample
|
|
application by doing the following:</p>
|
|
|
|
<p><img src="images/app-flow.png" alt="" /></p>
|
|
|
|
<h2 id="set-up-your-environment">Set up your environment</h2>
|
|
|
|
<p>This sample application requires two code bases, a Blockstack <code class="highlighter-rouge">hello-blockstack</code> web
|
|
application and a <code class="highlighter-rouge">hello-ios</code> iOS application. You use the iOS application to run the
|
|
web application on an iOS device.</p>
|
|
|
|
<p>Before you start developing the sample, there are a few elements you need in
|
|
your environment.</p>
|
|
|
|
<h3 id="install-xcode">Install XCode</h3>
|
|
|
|
<p>If you are an experienced iOS developer and already have an iOS
|
|
development environment on your workstation, you can use that and skip this
|
|
step. However, you may need to adjust the remaining instructions for your
|
|
environment.</p>
|
|
|
|
<p>Follow the installation instructions to <a href="https://developer.apple.com/xcode/">download and XCode</a> for your operating system.
|
|
Depending on your network connection, this can take between 15-30 minutes.</p>
|
|
|
|
<h3 id="do-you-have-npm">Do you have npm?</h3>
|
|
|
|
<p>The Blockstack code in this tutorial relies on the <code class="highlighter-rouge">npm</code> dependency manager.
|
|
Before you begin, verify you have installed <code class="highlighter-rouge">npm</code> using the <code class="highlighter-rouge">which</code> command to
|
|
verify.</p>
|
|
|
|
<div class="language-bash highlighter-rouge"><pre class="highlight"><code><span class="gp">$ </span>which npm
|
|
/usr/local/bin/npm
|
|
</code></pre>
|
|
</div>
|
|
|
|
<p>If you don’t find <code class="highlighter-rouge">npm</code> in your system, <a href="https://www.npmjs.com/get-npm">install
|
|
it</a>.</p>
|
|
|
|
<h3 id="install-the-cocoapods-160beta1-dependency-manager">Install the CocoaPods 1.6.0.beta.1 dependency manager</h3>
|
|
|
|
<p>The sample application only runs on devices with iOS 11.0 or higher. You install
|
|
the Blockstack iOS SDK through the CocoaPods. Cocoapods is a dependency manager
|
|
for Swift and Objective-C Cocoa projects. It’s a simple, user friendly way to
|
|
use libraries from the community in your project.</p>
|
|
|
|
<p>You must use the <code class="highlighter-rouge">1.6.0.beta.1</code> version of CocoaPods or newer to avoid an
|
|
incapability between Cocoapods and XCode. Before starting the tutorial, confirm
|
|
you have installed CocoaPods.</p>
|
|
|
|
<div class="language-bash highlighter-rouge"><pre class="highlight"><code><span class="gp">$ </span>pod --version
|
|
1.6.0.beta.1
|
|
</code></pre>
|
|
</div>
|
|
|
|
<p>If you don’t have the CocoaPods beta version, install it:</p>
|
|
|
|
<div class="language-bash highlighter-rouge"><pre class="highlight"><code>sudo gem install cocoapods -v 1.6.0.beta.1
|
|
</code></pre>
|
|
</div>
|
|
|
|
<h3 id="use-npm-to-install-yeoman-and-the-blockstack-app-generator">Use npm to install Yeoman and the Blockstack App Generator</h3>
|
|
|
|
<p>You use <code class="highlighter-rouge">npm</code> to install Yeoman. Yeoman is a generic scaffolding system that
|
|
helps users rapidly start new projects and streamline the maintenance of
|
|
existing projects.</p>
|
|
|
|
<ol>
|
|
<li>
|
|
<p>Install Yeoman.</p>
|
|
|
|
<div class="language-bash highlighter-rouge"><pre class="highlight"><code> npm install -g yo
|
|
</code></pre>
|
|
</div>
|
|
</li>
|
|
<li>
|
|
<p>Install the Blockstack application generator.</p>
|
|
|
|
<div class="language-bash highlighter-rouge"><pre class="highlight"><code> npm install -g generator-blockstack
|
|
</code></pre>
|
|
</div>
|
|
<h2 id="build-the-blockstack-hello-world">Build the Blockstack hello-world</h2>
|
|
</li>
|
|
</ol>
|
|
|
|
<p>In this section, you build a Blockstack <code class="highlighter-rouge">hello-world</code> application. Then, you
|
|
modify the <code class="highlighter-rouge">hello-world</code> to interact with the iOS app via a redirect.</p>
|
|
|
|
<h3 id="generate-and-launch-your-hello-blockstack-application">Generate and launch your hello-blockstack application</h3>
|
|
|
|
<p>In this section, you build an initial React.js application called
|
|
<code class="highlighter-rouge">hello-blockstack</code>.</p>
|
|
|
|
<ol>
|
|
<li>
|
|
<p>Create a <code class="highlighter-rouge">hello-blockstack</code> directory.</p>
|
|
|
|
<div class="language-bash highlighter-rouge"><pre class="highlight"><code> mkdir hello-blockstack
|
|
</code></pre>
|
|
</div>
|
|
</li>
|
|
<li>
|
|
<p>Change into your new directory.</p>
|
|
|
|
<div class="language-bash highlighter-rouge"><pre class="highlight"><code> <span class="nb">cd </span>hello-blockstack
|
|
</code></pre>
|
|
</div>
|
|
</li>
|
|
<li>
|
|
<p>Use Yeoman and the Blockstack application generator to create your initial <code class="highlighter-rouge">hello-blockstack</code> application.</p>
|
|
|
|
<div class="language-bash highlighter-rouge"><pre class="highlight"><code> yo blockstack:react
|
|
</code></pre>
|
|
</div>
|
|
|
|
<p>You should see several interactive prompts.</p>
|
|
|
|
<div class="language-bash highlighter-rouge"><pre class="highlight"><code> <span class="nv">$ </span>yo blockstack:react
|
|
<span class="o">==========================================================================</span>
|
|
We are constantly looking <span class="k">for </span>ways to make yo better!
|
|
May we anonymously report usage statistics to improve the tool over <span class="nb">time</span>?
|
|
More info: https://github.com/yeoman/insight & http://yeoman.io
|
|
<span class="o">==========================================================================</span> No
|
|
|
|
_-----_ ╭──────────────────────────╮
|
|
| | │ Welcome to the │
|
|
|--<span class="o">(</span>o<span class="o">)</span>--| │ Blockstack app │
|
|
<span class="sb">`</span>---------´ │ generator! │
|
|
<span class="o">(</span> _´U<span class="sb">`</span>_ <span class="o">)</span> ╰──────────────────────────╯
|
|
/___A___<span class="se">\ </span> /
|
|
| ~ |
|
|
__<span class="s1">'.___.'</span>__
|
|
´ <span class="sb">`</span> |° ´ Y <span class="sb">`</span>
|
|
|
|
? Are you ready to build a Blockstack app <span class="k">in </span>React? <span class="o">(</span>Y/n<span class="o">)</span>
|
|
</code></pre>
|
|
</div>
|
|
</li>
|
|
<li>
|
|
<p>Respond to the prompts to populate the initial app.</p>
|
|
|
|
<p>After the process completes successfully, you see a prompt similar to the following:</p>
|
|
|
|
<div class="language-bash highlighter-rouge"><pre class="highlight"><code> <span class="o">[</span>fsevents] Success:
|
|
<span class="s2">"/Users/theuser/repos/hello-blockstack/node_modules/fsevents/lib/binding/Release/node-v59-darwin-x64/fse.node"</span>
|
|
is installed via remote npm notice created a lockfile as package-lock.json.
|
|
You should commit this file. added 1060 packages <span class="k">in </span>26.901s
|
|
</code></pre>
|
|
</div>
|
|
</li>
|
|
<li>
|
|
<p>Run the initial application.</p>
|
|
|
|
<div class="language-bash highlighter-rouge"><pre class="highlight"><code> npm start
|
|
|
|
> hello-blockstack@0.0.0 start /Users/moxiegirl/repos/hello-blockstack
|
|
> webpack-dev-server
|
|
|
|
Project is running at http://localhost:8080/
|
|
webpack output is served from /
|
|
404s will fallback to /index.html
|
|
Hash: 4d2312ba236a4b95dc3a
|
|
Version: webpack 2.7.0
|
|
Time: 2969ms
|
|
Asset Size Chunks Chunk Names
|
|
....
|
|
Child html-webpack-plugin <span class="k">for</span> <span class="s2">"index.html"</span>:
|
|
chunk <span class="o">{</span>0<span class="o">}</span> index.html 541 kB <span class="o">[</span>entry] <span class="o">[</span>rendered]
|
|
<span class="o">[</span>0] ./~/lodash/lodash.js 540 kB <span class="o">{</span>0<span class="o">}</span> <span class="o">[</span>built]
|
|
<span class="o">[</span>1] ./~/html-webpack-plugin/lib/loader.js!./src/index.html 533 bytes <span class="o">{</span>0<span class="o">}</span> <span class="o">[</span>built]
|
|
<span class="o">[</span>2] <span class="o">(</span>webpack<span class="o">)</span>/buildin/global.js 509 bytes <span class="o">{</span>0<span class="o">}</span> <span class="o">[</span>built]
|
|
<span class="o">[</span>3] <span class="o">(</span>webpack<span class="o">)</span>/buildin/module.js 517 bytes <span class="o">{</span>0<span class="o">}</span> <span class="o">[</span>built]
|
|
webpack: Compiled successfully.
|
|
</code></pre>
|
|
</div>
|
|
|
|
<p>At this point, the browser is running a Blockstack server on your local host.</p>
|
|
</li>
|
|
<li>
|
|
<p>Navigate to <code class="highlighter-rouge">https://localhost:8080</code> with your browser to display the
|
|
application.</p>
|
|
|
|
<p><img src="images/blockstack-signin.png" alt="" /></p>
|
|
|
|
<p>This local instances is for testing your applications only.</p>
|
|
</li>
|
|
<li>
|
|
<p>Choose <strong>Sign in with Blockstack</strong></p>
|
|
|
|
<p>The system displays a prompt allowing you to create a new Blockstack ID or restore an existing one.</p>
|
|
|
|
<p><img src="images/create-restore.png" alt="" /></p>
|
|
</li>
|
|
<li>
|
|
<p>Follow the prompts appropriate to your situation.</p>
|
|
|
|
<p>If you are restoring an existing ID, you may see a prompt about your user
|
|
being nameless, ignore it. At this point you have only a single application
|
|
on your test server. So, you should see this single application, with your
|
|
own <code class="highlighter-rouge">blockstack.id</code> display name, once you are signed in:</p>
|
|
|
|
<p><img src="images/running-app.png" alt="" /></p>
|
|
</li>
|
|
</ol>
|
|
|
|
<h3 id="add-a-redirect-end-point-to-your-application">Add a redirect end point to your application</h3>
|
|
|
|
<p>When a user opens the webapp from the Blockstack browser on an iOS phone,
|
|
you want the web app to redirect the user to your iOS application. The work
|
|
you do here will allow it.</p>
|
|
|
|
<ol>
|
|
<li>
|
|
<p>From the terminal command line, change directory to your web
|
|
application directory.</p>
|
|
</li>
|
|
<li>
|
|
<p>Create a <code class="highlighter-rouge">public</code> directory.</p>
|
|
|
|
<div class="language-bash highlighter-rouge"><pre class="highlight"><code> <span class="nv">$ </span>mkdir public
|
|
</code></pre>
|
|
</div>
|
|
</li>
|
|
<li>
|
|
<p>Use the <code class="highlighter-rouge">touch</code> command to add a redirect endpoint to your application.</p>
|
|
|
|
<p>This endpoint on the web version of your app will redirect iOS users back
|
|
to your mobile app.</p>
|
|
|
|
<div class="language-bash highlighter-rouge"><pre class="highlight"><code> <span class="nv">$ </span>touch public/redirect.html
|
|
</code></pre>
|
|
</div>
|
|
</li>
|
|
<li>
|
|
<p>Open <code class="highlighter-rouge">redirect.html</code> and add code to the endpoint.</p>
|
|
|
|
<div class="highlighter-rouge"><pre class="highlight"><code> <span class="cp"><!DOCTYPE html></span>
|
|
<span class="nt"><html></span>
|
|
<span class="nt"><head></span>
|
|
<span class="nt"><title></span>Hello, Blockstack!<span class="nt"></title></span>
|
|
<span class="nt"><script></span>
|
|
<span class="kd">function</span> <span class="nx">getParameterByName</span><span class="p">(</span><span class="nx">name</span><span class="p">)</span> <span class="p">{</span>
|
|
<span class="kd">var</span> <span class="nx">match</span> <span class="o">=</span> <span class="nb">RegExp</span><span class="p">(</span><span class="s1">'[?&]'</span> <span class="o">+</span> <span class="nx">name</span> <span class="o">+</span> <span class="s1">'=([^&]*)'</span><span class="p">).</span><span class="nx">exec</span><span class="p">(</span><span class="nb">window</span><span class="p">.</span><span class="nx">location</span><span class="p">.</span><span class="nx">search</span><span class="p">);</span>
|
|
<span class="k">return</span> <span class="nx">match</span> <span class="o">&&</span> <span class="nb">decodeURIComponent</span><span class="p">(</span><span class="nx">match</span><span class="p">[</span><span class="mi">1</span><span class="p">].</span><span class="nx">replace</span><span class="p">(</span><span class="sr">/</span><span class="se">\+</span><span class="sr">/g</span><span class="p">,</span> <span class="s1">' '</span><span class="p">));</span>
|
|
<span class="p">}</span>
|
|
|
|
<span class="kd">var</span> <span class="nx">authResponse</span> <span class="o">=</span> <span class="nx">getParameterByName</span><span class="p">(</span><span class="s1">'authResponse'</span><span class="p">)</span>
|
|
<span class="nb">window</span><span class="p">.</span><span class="nx">location</span><span class="o">=</span><span class="s2">"myblockstackapp://?authResponse="</span> <span class="o">+</span> <span class="nx">authResponse</span>
|
|
<span class="nt"></script></span>
|
|
<span class="nt"><body></span>
|
|
<span class="nt"></body></span>
|
|
<span class="nt"></html></span>
|
|
</code></pre>
|
|
</div>
|
|
|
|
<p>Blockstack apps are identified by their domain names. The endpoint will
|
|
receive a get request with the query parameter <code class="highlighter-rouge">authResponse=XXXX</code> and
|
|
should redirect the browser to <code class="highlighter-rouge">myblockstackapp:XXXX</code>.</p>
|
|
|
|
<p><code class="highlighter-rouge">myblockstackapp:</code> is custom protocol handler. The handler should be unique
|
|
to your application. Your app’s web-based authentication uses this handler
|
|
to redirect the user back to your iOS app. Later, you’ll add a reference
|
|
to this handler in your iOS application.</p>
|
|
</li>
|
|
<li>Close and save the <code class="highlighter-rouge">redirect.html</code> file.</li>
|
|
<li>
|
|
<p>Ensure your Blockstack app compiles successfully.</p>
|
|
|
|
<p>The <code class="highlighter-rouge">npm</code> process should detect and compile your change.</p>
|
|
</li>
|
|
</ol>
|
|
|
|
<h2 id="build-the-hello-blockstack-ios">Build the hello-blockstack-ios</h2>
|
|
|
|
<p>Now, you build an iOS application that can access and run your Blockstack web
|
|
application on a mobile device.</p>
|
|
|
|
<h3 id="create-an-xcode-project">Create an XCode Project</h3>
|
|
|
|
<p>This tutorial uses XCode 9.3, you can use another version but be aware that some
|
|
menu items and therefore these procedures may be differœent on your version.</p>
|
|
|
|
<ol>
|
|
<li>Launch the XCode interface.</li>
|
|
<li>Choose <strong>Create new XCode project</strong>.</li>
|
|
<li>Select <strong>iOS</strong>.</li>
|
|
<li>
|
|
<p>Select <strong>Single View App</strong>.</p>
|
|
|
|
<p><img src="images/single-view-app.png" alt="" /></p>
|
|
</li>
|
|
<li>
|
|
<p><strong>Choose options for your new project</strong> for your project.</p>
|
|
|
|
<p><img src="images/choose-new-options.png" alt="" /></p>
|
|
</li>
|
|
<li>
|
|
<p>Press <strong>Next</strong>.</p>
|
|
|
|
<p>The system prompts you for a location to store your code.</p>
|
|
</li>
|
|
<li>Save your project.</li>
|
|
<li>Close XCode.</li>
|
|
</ol>
|
|
|
|
<h3 id="add-and-edit-a-podfile">Add and edit a Podfile</h3>
|
|
|
|
<p>To use CocoaPods you need to define the XCode target to link them to.
|
|
So for example if you are writing an iOS app, it would be the name of your app.
|
|
Create a target section by writing target ‘$TARGET_NAME’ do and an end a few
|
|
lines after.</p>
|
|
|
|
<ol>
|
|
<li>Open a terminal window on your workstation.</li>
|
|
<li>
|
|
<p>Navigate to and change directory into the root of your project directory.</p>
|
|
|
|
<div class="language-swift highlighter-rouge"><pre class="highlight"><code> <span class="err">$</span> <span class="n">cd</span> <span class="n">hello</span><span class="o">-</span><span class="n">blockstack</span><span class="o">-</span><span class="n">ios</span>
|
|
</code></pre>
|
|
</div>
|
|
</li>
|
|
<li>
|
|
<p>Create a Podfile.</p>
|
|
|
|
<div class="language-bash highlighter-rouge"><pre class="highlight"><code> <span class="nv">$ </span>pod init
|
|
</code></pre>
|
|
</div>
|
|
|
|
<p>The command creates a <code class="highlighter-rouge">Podfile</code> in the directory.</p>
|
|
</li>
|
|
<li>Open the <code class="highlighter-rouge">Podfile</code> for editing.</li>
|
|
<li>
|
|
<p>Add a line stating the Blockstack dependency.</p>
|
|
|
|
<div class="highlighter-rouge"><pre class="highlight"><code># Uncomment the next line to define a global platform for your project
|
|
# platform :ios, '9.0'
|
|
|
|
target 'hello-blockstack-ios' do
|
|
# Comment the next line if you're not using Swift and don't want to use dynamic frameworks
|
|
use_frameworks!
|
|
|
|
# Pods for hello-blockstack-ios
|
|
pod 'Blockstack'
|
|
|
|
target 'hello-blockstack-iosTests' do
|
|
inherit! :search_paths
|
|
# Pods for testing
|
|
end
|
|
end
|
|
</code></pre>
|
|
</div>
|
|
</li>
|
|
<li>Save and close the <code class="highlighter-rouge">Podfile</code>.</li>
|
|
</ol>
|
|
|
|
<h3 id="install-blockstack-sdk-and-open-the-pod-project">Install Blockstack SDK and open the pod project</h3>
|
|
|
|
<ol>
|
|
<li>Close your new XCode project.</li>
|
|
<li>Change to the root of your <code class="highlighter-rouge">hello-blockstack-is</code> project.</li>
|
|
<li>
|
|
<p>Initialize the project with Cocoapods.</p>
|
|
|
|
<div class="highlighter-rouge"><pre class="highlight"><code> $ pod install
|
|
Analyzing dependencies
|
|
Downloading dependencies
|
|
Installing Blockstack (0.2.0)
|
|
Installing CryptoSwift (0.11.0)
|
|
Generating Pods project
|
|
Integrating client project
|
|
|
|
[!] Please close any current XCode sessions and use `hello-blockstack-ios.xcworkspace` for this project from now on.
|
|
Sending stats
|
|
Pod installation complete! There is 1 dependency from the Podfile and 2 total pods installed.
|
|
|
|
[!] Automatically assigning platform `ios` with version `11.4` on target `hello-blockstack-ios` because no platform was specified. Please specify a platform for this target in your Podfile. See `https://guides.cocoapods.org/syntax/podfile.html#platform`.
|
|
</code></pre>
|
|
</div>
|
|
|
|
<p>This command creates a number of files</p>
|
|
</li>
|
|
<li>
|
|
<p>Review the files that the <code class="highlighter-rouge">pod</code> installation created:</p>
|
|
|
|
<div class="language-bash highlighter-rouge"><pre class="highlight"><code><span class="gp">$ </span>ls
|
|
Podfile hello-blockstack-ios hello-blockstack-iosTests
|
|
Podfile.lock hello-blockstack-ios.xcodeproj
|
|
Pods hello-blockstack-ios.xcworkspace
|
|
</code></pre>
|
|
</div>
|
|
</li>
|
|
<li>Start XCode and choose <strong>Open another project</strong>.</li>
|
|
<li>
|
|
<p>Choose the <code class="highlighter-rouge">.xcworkspace</code> file created in your project folder.</p>
|
|
|
|
<p><img src="images/open-xcworkspace.png" alt="" /></p>
|
|
|
|
<p>When you open the workspace you’ll see a warning indicator at the top in the
|
|
project title.</p>
|
|
</li>
|
|
<li>Click the signal to reveal the warning.</li>
|
|
<li>
|
|
<p>Click <strong>Update to recommented settings</strong>.</p>
|
|
|
|
<p><img src="images/indicator.png" alt="" /></p>
|
|
</li>
|
|
<li>
|
|
<p>Choose <strong>Perform Changes</strong> and <strong>Continue</strong> when prompted.</p>
|
|
|
|
<p>The indicator disappears.</p>
|
|
</li>
|
|
</ol>
|
|
|
|
<h3 id="choose-a-custom-protocol-handler">Choose a custom protocol handler</h3>
|
|
|
|
<p>You’ll need to choose a custom protocol handler that is unique to your app. This
|
|
is so that your app’s web-based authentication <code class="highlighter-rouge">redirect.html</code> endpoint can redirect
|
|
the user back to your iOS app. In this example, you use <code class="highlighter-rouge">myblockstackapp://</code>.</p>
|
|
|
|
<ol>
|
|
<li>Open the <code class="highlighter-rouge">.xcworkspace</code> file in XCode if it isn’t open already.</li>
|
|
<li>Select the top node of your project.</li>
|
|
<li>Select the <strong>Info</strong> tab in XCode.</li>
|
|
<li>Scroll to <strong>URL Types</strong> and press <strong>+</strong> (plus) sign.</li>
|
|
<li>Enter an <strong>Identifier</strong> and <strong>URL Schemes</strong> value.</li>
|
|
<li>
|
|
<p>Set the <strong>Role</strong> to <strong>Editor</strong>.</p>
|
|
|
|
<p>When you are done the type appears as follows:</p>
|
|
|
|
<p><img src="images/url-type.png" alt="" /></p>
|
|
</li>
|
|
</ol>
|
|
|
|
<h3 id="add-a-splash-screen">Add a splash screen</h3>
|
|
|
|
<p>All iOS applications require a splash page.</p>
|
|
|
|
<ol>
|
|
<li>Select <code class="highlighter-rouge">Assets.xcassets</code></li>
|
|
<li>Move your cursor into the area below Appicon.</li>
|
|
<li>
|
|
<p>Right click and choose <strong>New Image Set</strong></p>
|
|
|
|
<p><img src="images/image-set-0.png" alt="" /></p>
|
|
</li>
|
|
<li>
|
|
<p>Download the Blockstack icon.</p>
|
|
|
|
<p><img src="images/blockstack-icon.png" alt="" /></p>
|
|
</li>
|
|
<li>
|
|
<p>Drag the downloaded file into the <strong>3X</strong> position in your new Images folder.</p>
|
|
|
|
<p><img src="images/image-set-1.png" alt="" /></p>
|
|
</li>
|
|
<li>Select the <code class="highlighter-rouge">LaunchScreen.storyboard</code>.</li>
|
|
<li>
|
|
<p>Choose <strong>Open As > Source Code</strong>.</p>
|
|
|
|
<p><img src="images/open-as.png" alt="" /></p>
|
|
</li>
|
|
<li>
|
|
<p>Replace the content of the <code class="highlighter-rouge"><scenes></code> element with the following:</p>
|
|
|
|
<div class="highlighter-rouge"><pre class="highlight"><code><scenes>
|
|
<!--View Controller-->
|
|
<scene sceneID="EHf-IW-A2E">
|
|
<objects>
|
|
<viewController id="01J-lp-oVM" sceneMemberID="viewController">
|
|
<view key="view" contentMode="scaleToFill" id="Ze5-6b-2t3">
|
|
<rect key="frame" x="0.0" y="0.0" width="375" height="667"/>
|
|
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
|
<subviews>
|
|
<imageView userInteractionEnabled="NO" contentMode="scaleToFill" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="Image" translatesAutoresizingMaskIntoConstraints="NO" id="SpU-hA-y2f">
|
|
<rect key="frame" x="155.5" y="273" width="64" height="64"/>
|
|
</imageView>
|
|
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Hello Blockstack iOS" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="Wfj-A6-BZM">
|
|
<rect key="frame" x="108" y="432" width="158" height="21"/>
|
|
<fontDescription key="fontDescription" type="system" pointSize="17"/>
|
|
<nil key="textColor"/>
|
|
<nil key="highlightedColor"/>
|
|
</label>
|
|
</subviews>
|
|
<color key="backgroundColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
|
<constraints>
|
|
<constraint firstItem="Wfj-A6-BZM" firstAttribute="centerX" secondItem="6Tk-OE-BBY" secondAttribute="centerX" id="AZy-qf-xHq"/>
|
|
<constraint firstItem="Wfj-A6-BZM" firstAttribute="top" secondItem="6Tk-OE-BBY" secondAttribute="top" constant="412" id="SwP-qV-1RP"/>
|
|
<constraint firstItem="SpU-hA-y2f" firstAttribute="centerX" secondItem="6Tk-OE-BBY" secondAttribute="centerX" id="XdI-Db-fDo"/>
|
|
<constraint firstItem="SpU-hA-y2f" firstAttribute="top" secondItem="6Tk-OE-BBY" secondAttribute="top" constant="253" id="xc5-po-W1E"/>
|
|
</constraints>
|
|
<viewLayoutGuide key="safeArea" id="6Tk-OE-BBY"/>
|
|
</view>
|
|
</viewController>
|
|
<placeholder placeholderIdentifier="IBFirstResponder" id="iYj-Kq-Ea1" userLabel="First Responder" sceneMemberID="firstResponder"/>
|
|
</objects>
|
|
<point key="canvasLocation" x="52" y="374.66266866566718"/>
|
|
</scene>
|
|
</scenes>
|
|
</code></pre>
|
|
</div>
|
|
</li>
|
|
<li>
|
|
<p>Immediately after scenes but before the close of the <code class="highlighter-rouge"></document></code> tag add the following <code class="highlighter-rouge"><resources></code>.</p>
|
|
|
|
<div class="language-xml highlighter-rouge"><pre class="highlight"><code> <span class="nt"><resources></span>
|
|
<span class="nt"><image</span> <span class="na">name=</span><span class="s">"Image"</span> <span class="na">width=</span><span class="s">"64"</span> <span class="na">height=</span><span class="s">"64"</span><span class="nt">/></span>
|
|
<span class="nt"></resources></span>
|
|
<span class="nt"></document></span>
|
|
</code></pre>
|
|
</div>
|
|
</li>
|
|
<li>
|
|
<p>Choose <strong>Run > Run app</strong> in the emulator.</p>
|
|
|
|
<p>The emulator now contains a new splash screen.</p>
|
|
|
|
<p><img src="images/splash.png" alt="" /></p>
|
|
</li>
|
|
</ol>
|
|
|
|
<h3 id="update-the-mainstoryboard">Update the Main.storyboard</h3>
|
|
|
|
<p>Rather than have you build up your own UI, this section has you copy and paste a layout into the XML file source code for the <strong>Main.storyboard</strong> file.</p>
|
|
|
|
<ol>
|
|
<li>Select the <code class="highlighter-rouge">Main.storyboard</code> file.</li>
|
|
<li>
|
|
<p>Chooose <strong>Open As > Source Code</strong></p>
|
|
|
|
<p>The <code class="highlighter-rouge">blockstack-example/blockstack-example/Base.lproj/Main.storyboard</code> file
|
|
defines the graphical elements. Some elements are required before you can
|
|
functionality to your code.</p>
|
|
</li>
|
|
<li>
|
|
<p>Within the <code class="highlighter-rouge"><viewController></code> element, replace the existing <code class="highlighter-rouge"><view></code> subelement with the following:</p>
|
|
|
|
<div class="language-xml highlighter-rouge"><pre class="highlight"><code><span class="nt"><view</span> <span class="na">key=</span><span class="s">"view"</span> <span class="na">contentMode=</span><span class="s">"scaleToFill"</span> <span class="na">id=</span><span class="s">"8bC-Xf-vdC"</span><span class="nt">></span>
|
|
<span class="nt"><rect</span> <span class="na">key=</span><span class="s">"frame"</span> <span class="na">x=</span><span class="s">"0.0"</span> <span class="na">y=</span><span class="s">"0.0"</span> <span class="na">width=</span><span class="s">"375"</span> <span class="na">height=</span><span class="s">"667"</span><span class="nt">/></span>
|
|
<span class="nt"><autoresizingMask</span> <span class="na">key=</span><span class="s">"autoresizingMask"</span> <span class="na">widthSizable=</span><span class="s">"YES"</span> <span class="na">heightSizable=</span><span class="s">"YES"</span><span class="nt">/></span>
|
|
<span class="nt"><subviews></span>
|
|
<span class="nt"><label</span> <span class="na">opaque=</span><span class="s">"NO"</span> <span class="na">userInteractionEnabled=</span><span class="s">"NO"</span> <span class="na">contentMode=</span><span class="s">"left"</span> <span class="na">horizontalHuggingPriority=</span><span class="s">"251"</span> <span class="na">verticalHuggingPriority=</span><span class="s">"251"</span> <span class="na">text=</span><span class="s">"hello-blockstack-ios"</span> <span class="na">textAlignment=</span><span class="s">"center"</span> <span class="na">lineBreakMode=</span><span class="s">"tailTruncation"</span> <span class="na">baselineAdjustment=</span><span class="s">"alignBaselines"</span> <span class="na">adjustsFontSizeToFit=</span><span class="s">"NO"</span> <span class="na">translatesAutoresizingMaskIntoConstraints=</span><span class="s">"NO"</span> <span class="na">id=</span><span class="s">"9eE-ZS-LU9"</span><span class="nt">></span>
|
|
<span class="nt"><rect</span> <span class="na">key=</span><span class="s">"frame"</span> <span class="na">x=</span><span class="s">"0.0"</span> <span class="na">y=</span><span class="s">"101"</span> <span class="na">width=</span><span class="s">"375"</span> <span class="na">height=</span><span class="s">"50"</span><span class="nt">/></span>
|
|
<span class="nt"><color</span> <span class="na">key=</span><span class="s">"backgroundColor"</span> <span class="na">red=</span><span class="s">"0.44735813140000003"</span> <span class="na">green=</span><span class="s">"0.1280144453"</span> <span class="na">blue=</span><span class="s">"0.57268613580000005"</span> <span class="na">alpha=</span><span class="s">"1"</span> <span class="na">colorSpace=</span><span class="s">"custom"</span> <span class="na">customColorSpace=</span><span class="s">"sRGB"</span><span class="nt">/></span>
|
|
<span class="nt"><constraints></span>
|
|
<span class="nt"><constraint</span> <span class="na">firstAttribute=</span><span class="s">"height"</span> <span class="na">constant=</span><span class="s">"50"</span> <span class="na">id=</span><span class="s">"U5v-13-4Ux"</span><span class="nt">/></span>
|
|
<span class="nt"></constraints></span>
|
|
<span class="nt"><fontDescription</span> <span class="na">key=</span><span class="s">"fontDescription"</span> <span class="na">type=</span><span class="s">"system"</span> <span class="na">pointSize=</span><span class="s">"17"</span><span class="nt">/></span>
|
|
<span class="nt"><color</span> <span class="na">key=</span><span class="s">"textColor"</span> <span class="na">white=</span><span class="s">"1"</span> <span class="na">alpha=</span><span class="s">"1"</span> <span class="na">colorSpace=</span><span class="s">"custom"</span> <span class="na">customColorSpace=</span><span class="s">"genericGamma22GrayColorSpace"</span><span class="nt">/></span>
|
|
<span class="nt"><nil</span> <span class="na">key=</span><span class="s">"highlightedColor"</span><span class="nt">/></span>
|
|
<span class="nt"></label></span>
|
|
<span class="nt"><button</span> <span class="na">opaque=</span><span class="s">"NO"</span> <span class="na">contentMode=</span><span class="s">"scaleToFill"</span> <span class="na">contentHorizontalAlignment=</span><span class="s">"center"</span> <span class="na">contentVerticalAlignment=</span><span class="s">"center"</span> <span class="na">buttonType=</span><span class="s">"roundedRect"</span> <span class="na">lineBreakMode=</span><span class="s">"middleTruncation"</span> <span class="na">translatesAutoresizingMaskIntoConstraints=</span><span class="s">"NO"</span> <span class="na">id=</span><span class="s">"Lfp-KX-BDb"</span><span class="nt">></span>
|
|
<span class="nt"><rect</span> <span class="na">key=</span><span class="s">"frame"</span> <span class="na">x=</span><span class="s">"100"</span> <span class="na">y=</span><span class="s">"382"</span> <span class="na">width=</span><span class="s">"175"</span> <span class="na">height=</span><span class="s">"40"</span><span class="nt">/></span>
|
|
<span class="nt"><color</span> <span class="na">key=</span><span class="s">"backgroundColor"</span> <span class="na">red=</span><span class="s">"0.1215686275"</span> <span class="na">green=</span><span class="s">"0.12941176469999999"</span> <span class="na">blue=</span><span class="s">"0.14117647059999999"</span> <span class="na">alpha=</span><span class="s">"1"</span> <span class="na">colorSpace=</span><span class="s">"custom"</span> <span class="na">customColorSpace=</span><span class="s">"sRGB"</span><span class="nt">/></span>
|
|
<span class="nt"><constraints></span>
|
|
<span class="nt"><constraint</span> <span class="na">firstAttribute=</span><span class="s">"height"</span> <span class="na">constant=</span><span class="s">"40"</span> <span class="na">id=</span><span class="s">"8fN-Ro-Krn"</span><span class="nt">/></span>
|
|
<span class="nt"></constraints></span>
|
|
<span class="nt"><color</span> <span class="na">key=</span><span class="s">"tintColor"</span> <span class="na">white=</span><span class="s">"0.0"</span> <span class="na">alpha=</span><span class="s">"1"</span> <span class="na">colorSpace=</span><span class="s">"calibratedWhite"</span><span class="nt">/></span>
|
|
<span class="nt"><state</span> <span class="na">key=</span><span class="s">"normal"</span> <span class="na">title=</span><span class="s">"Sign into Blocksack"</span><span class="nt">></span>
|
|
<span class="nt"><color</span> <span class="na">key=</span><span class="s">"titleColor"</span> <span class="na">white=</span><span class="s">"1"</span> <span class="na">alpha=</span><span class="s">"1"</span> <span class="na">colorSpace=</span><span class="s">"custom"</span> <span class="na">customColorSpace=</span><span class="s">"genericGamma22GrayColorSpace"</span><span class="nt">/></span>
|
|
<span class="nt"></state></span>
|
|
<span class="nt"><connections></span>
|
|
<span class="nt"><action</span> <span class="na">selector=</span><span class="s">"signIn:"</span> <span class="na">destination=</span><span class="s">"BYZ-38-t0r"</span> <span class="na">eventType=</span><span class="s">"touchUpInside"</span> <span class="na">id=</span><span class="s">"nV7-rt-euZ"</span><span class="nt">/></span>
|
|
<span class="nt"></connections></span>
|
|
<span class="nt"></button></span>
|
|
<span class="nt"></subviews></span>
|
|
<span class="nt"><color</span> <span class="na">key=</span><span class="s">"backgroundColor"</span> <span class="na">red=</span><span class="s">"1"</span> <span class="na">green=</span><span class="s">"1"</span> <span class="na">blue=</span><span class="s">"1"</span> <span class="na">alpha=</span><span class="s">"1"</span> <span class="na">colorSpace=</span><span class="s">"custom"</span> <span class="na">customColorSpace=</span><span class="s">"sRGB"</span><span class="nt">/></span>
|
|
<span class="nt"><constraints></span>
|
|
<span class="nt"><constraint</span> <span class="na">firstItem=</span><span class="s">"9eE-ZS-LU9"</span> <span class="na">firstAttribute=</span><span class="s">"leading"</span> <span class="na">secondItem=</span><span class="s">"6Tk-OE-BBY"</span> <span class="na">secondAttribute=</span><span class="s">"leading"</span> <span class="na">id=</span><span class="s">"2ZP-tU-h9Y"</span><span class="nt">/></span>
|
|
<span class="nt"><constraint</span> <span class="na">firstItem=</span><span class="s">"9eE-ZS-LU9"</span> <span class="na">firstAttribute=</span><span class="s">"top"</span> <span class="na">secondItem=</span><span class="s">"6Tk-OE-BBY"</span> <span class="na">secondAttribute=</span><span class="s">"top"</span> <span class="na">constant=</span><span class="s">"81"</span> <span class="na">id=</span><span class="s">"DBh-q0-pAV"</span><span class="nt">/></span>
|
|
<span class="nt"><constraint</span> <span class="na">firstItem=</span><span class="s">"6Tk-OE-BBY"</span> <span class="na">firstAttribute=</span><span class="s">"trailing"</span> <span class="na">secondItem=</span><span class="s">"Lfp-KX-BDb"</span> <span class="na">secondAttribute=</span><span class="s">"trailing"</span> <span class="na">constant=</span><span class="s">"100"</span> <span class="na">id=</span><span class="s">"MHO-ew-4Bd"</span><span class="nt">/></span>
|
|
<span class="nt"><constraint</span> <span class="na">firstItem=</span><span class="s">"Lfp-KX-BDb"</span> <span class="na">firstAttribute=</span><span class="s">"leading"</span> <span class="na">secondItem=</span><span class="s">"6Tk-OE-BBY"</span> <span class="na">secondAttribute=</span><span class="s">"leading"</span> <span class="na">constant=</span><span class="s">"100"</span> <span class="na">id=</span><span class="s">"Rsm-LP-ya7"</span><span class="nt">/></span>
|
|
<span class="nt"><constraint</span> <span class="na">firstItem=</span><span class="s">"Lfp-KX-BDb"</span> <span class="na">firstAttribute=</span><span class="s">"top"</span> <span class="na">secondItem=</span><span class="s">"6Tk-OE-BBY"</span> <span class="na">secondAttribute=</span><span class="s">"top"</span> <span class="na">constant=</span><span class="s">"362"</span> <span class="na">id=</span><span class="s">"chE-B7-ya6"</span><span class="nt">/></span>
|
|
<span class="nt"><constraint</span> <span class="na">firstItem=</span><span class="s">"6Tk-OE-BBY"</span> <span class="na">firstAttribute=</span><span class="s">"trailing"</span> <span class="na">secondItem=</span><span class="s">"9eE-ZS-LU9"</span> <span class="na">secondAttribute=</span><span class="s">"trailing"</span> <span class="na">id=</span><span class="s">"j0x-8j-04u"</span><span class="nt">/></span>
|
|
<span class="nt"></constraints></span>
|
|
<span class="nt"><viewLayoutGuide</span> <span class="na">key=</span><span class="s">"safeArea"</span> <span class="na">id=</span><span class="s">"6Tk-OE-BBY"</span><span class="nt">/></span>
|
|
<span class="nt"></view></span>
|
|
</code></pre>
|
|
</div>
|
|
</li>
|
|
</ol>
|
|
|
|
<h3 id="add-the-ui-variables-to-the-viewcontroller-file">Add the UI variables to the ViewController file.</h3>
|
|
|
|
<p>In this section, you edit the <code class="highlighter-rouge">ViewController.swift</code> file using the storyboard as a starting point.</p>
|
|
|
|
<ol>
|
|
<li>
|
|
<p>Select the <strong>Main.storyboard</strong> and choose <strong>Open As > Interface Builder - storyboard</strong>.</p>
|
|
|
|
<p><img src="images/main-storyboard.png" alt="" /></p>
|
|
</li>
|
|
<li>
|
|
<p>With the interface builder open, display the <code class="highlighter-rouge">ViewController.swift</code> file in the rigth panel.</p>
|
|
|
|
<p><img src="images/view-editors.gif" alt="" /></p>
|
|
</li>
|
|
<li>
|
|
<p>In the storyboard, select the <strong>Sign into Blockstack</strong> button.</p>
|
|
</li>
|
|
<li>
|
|
<p>Control-drag from the button to the code display in the editor on the right, stopping the drag at the line below controller’s opening statement.</p>
|
|
|
|
<p><img src="images/add-action.gif" alt="" /></p>
|
|
</li>
|
|
<li>
|
|
<p>Repeat this process with the storyboard’s purple <strong>hello-blockstack-ios</strong> label.</p>
|
|
|
|
<p>When you are done, your ‘ViewController’ file contains the following variables:</p>
|
|
|
|
<div class="language-swift highlighter-rouge"><pre class="highlight"><code> <span class="kd">class</span> <span class="kt">ViewController</span><span class="p">:</span> <span class="kt">UIViewController</span> <span class="p">{</span>
|
|
|
|
<span class="kd">@IBOutlet</span> <span class="k">var</span> <span class="nv">nameLabel</span><span class="p">:</span> <span class="kt">UILabel</span><span class="o">!</span>
|
|
<span class="kd">@IBOutlet</span> <span class="k">var</span> <span class="nv">signInButton</span><span class="p">:</span> <span class="kt">UIButton</span><span class="o">!</span>
|
|
</code></pre>
|
|
</div>
|
|
|
|
<p>And XCode has added two outlines to the <code class="highlighter-rouge">Main.storyboard</code> source.</p>
|
|
|
|
<div class="language-xml highlighter-rouge"><pre class="highlight"><code> <span class="nt"><connections></span>
|
|
<span class="nt"><outlet</span> <span class="na">property=</span><span class="s">"nameLabel"</span> <span class="na">destination=</span><span class="s">"9eE-ZS-LU9"</span> <span class="na">id=</span><span class="s">"Ahv-Te-ZZo"</span><span class="nt">/></span>
|
|
<span class="nt"><outlet</span> <span class="na">property=</span><span class="s">"signInButton"</span> <span class="na">destination=</span><span class="s">"Lfp-KX-BDb"</span> <span class="na">id=</span><span class="s">"yef-Jj-uPt"</span><span class="nt">/></span>
|
|
<span class="nt"></connections></span>
|
|
</code></pre>
|
|
</div>
|
|
|
|
<p>Your connectors will have their own <code class="highlighter-rouge">destination</code> and <code class="highlighter-rouge">id</code> values.</p>
|
|
</li>
|
|
</ol>
|
|
|
|
<h3 id="edit-the-viewcontrollerswift-file">Edit the ViewController.swift file</h3>
|
|
|
|
<p>Now, you are ready to connect your application with your Blockstack Web
|
|
Application. Normally, after building your Web application you would have
|
|
registred it with Blockstack and the app would be available on the Web. This
|
|
example skips this registration step and uses an example application we’ve
|
|
already created for you:</p>
|
|
|
|
<p><code class="highlighter-rouge">https://heuristic-brown-7a88f8.netlify.com/redirect.html</code></p>
|
|
|
|
<p>This web application already has a redirect in place for you. You’ll reference
|
|
this application in your mobile add for now. In XCode, do the following;</p>
|
|
|
|
<ol>
|
|
<li>Open the <code class="highlighter-rouge">ViewController.swift</code> file.</li>
|
|
<li>
|
|
<p>Add an import both for <code class="highlighter-rouge">Blockstack</code> and for <code class="highlighter-rouge">SafariServices</code>.</p>
|
|
|
|
<div class="highlighter-rouge"><pre class="highlight"><code> import UIKit
|
|
import Blockstack
|
|
import SafariServices
|
|
</code></pre>
|
|
</div>
|
|
</li>
|
|
<li>
|
|
<p>Just before the <code class="highlighter-rouge">didReceiveMemoryWarning</code> function a private <code class="highlighter-rouge">updateUI()</code> function.</p>
|
|
|
|
<p>This function takes care of loading the user data from Blockstack.</p>
|
|
|
|
<div class="language-swift highlighter-rouge"><pre class="highlight"><code><span class="kd">private</span> <span class="kd">func</span> <span class="nf">updateUI</span><span class="p">()</span> <span class="p">{</span>
|
|
<span class="kt">DispatchQueue</span><span class="o">.</span><span class="n">main</span><span class="o">.</span><span class="n">async</span> <span class="p">{</span>
|
|
<span class="k">if</span> <span class="kt">Blockstack</span><span class="o">.</span><span class="n">shared</span><span class="o">.</span><span class="nf">isSignedIn</span><span class="p">()</span> <span class="p">{</span>
|
|
<span class="c1">// Read user profile data</span>
|
|
<span class="k">let</span> <span class="nv">retrievedUserData</span> <span class="o">=</span> <span class="kt">Blockstack</span><span class="o">.</span><span class="n">shared</span><span class="o">.</span><span class="nf">loadUserData</span><span class="p">()</span>
|
|
<span class="nf">print</span><span class="p">(</span><span class="n">retrievedUserData</span><span class="p">?</span><span class="o">.</span><span class="n">profile</span><span class="p">?</span><span class="o">.</span><span class="n">name</span> <span class="k">as</span> <span class="kt">Any</span><span class="p">)</span>
|
|
<span class="k">let</span> <span class="nv">name</span> <span class="o">=</span> <span class="n">retrievedUserData</span><span class="p">?</span><span class="o">.</span><span class="n">profile</span><span class="p">?</span><span class="o">.</span><span class="n">name</span> <span class="p">??</span> <span class="s">"Nameless Person"</span>
|
|
<span class="k">self</span><span class="o">.</span><span class="n">nameLabel</span><span class="p">?</span><span class="o">.</span><span class="n">text</span> <span class="o">=</span> <span class="s">"Hello, </span><span class="se">\(</span><span class="n">name</span><span class="se">)</span><span class="s">"</span>
|
|
<span class="k">self</span><span class="o">.</span><span class="n">nameLabel</span><span class="p">?</span><span class="o">.</span><span class="n">isHidden</span> <span class="o">=</span> <span class="kc">false</span>
|
|
<span class="k">self</span><span class="o">.</span><span class="n">signInButton</span><span class="p">?</span><span class="o">.</span><span class="nf">setTitle</span><span class="p">(</span><span class="s">"Sign Out"</span><span class="p">,</span> <span class="nv">for</span><span class="p">:</span> <span class="o">.</span><span class="n">normal</span><span class="p">)</span>
|
|
<span class="nf">print</span><span class="p">(</span><span class="s">"UI update SIGNED_IN"</span><span class="p">)</span>
|
|
<span class="p">}</span> <span class="k">else</span> <span class="p">{</span>
|
|
<span class="k">self</span><span class="o">.</span><span class="n">nameLabel</span><span class="p">?</span><span class="o">.</span><span class="n">text</span> <span class="o">=</span> <span class="s">"hello-blockstack-ios"</span>
|
|
<span class="k">self</span><span class="o">.</span><span class="n">signInButton</span><span class="p">?</span><span class="o">.</span><span class="nf">setTitle</span><span class="p">(</span><span class="s">"Sign into Blockstack"</span><span class="p">,</span> <span class="nv">for</span><span class="p">:</span> <span class="o">.</span><span class="n">normal</span><span class="p">)</span>
|
|
<span class="nf">print</span><span class="p">(</span><span class="s">"UI update SIGNED_OUT"</span><span class="p">)</span>
|
|
<span class="p">}</span>
|
|
<span class="p">}</span>
|
|
<span class="p">}</span>
|
|
</code></pre>
|
|
</div>
|
|
|
|
<p>The function uses the <code class="highlighter-rouge">Blockstack.shared.isSignedIn()</code> method to determine if
|
|
the user is already logged into Blockstack or not. It then uses the
|
|
<code class="highlighter-rouge">Blockstack.shared.loadUserData()</code> method to load the user data and update
|
|
the application display with the username.</p>
|
|
</li>
|
|
<li>
|
|
<p>Replace the content of the <code class="highlighter-rouge">viewDidLoad()</code> function so that it calls this private function.</p>
|
|
|
|
<div class="language-swift highlighter-rouge"><pre class="highlight"><code><span class="k">override</span> <span class="kd">func</span> <span class="nf">viewDidLoad</span><span class="p">()</span> <span class="p">{</span>
|
|
<span class="k">super</span><span class="o">.</span><span class="nf">viewDidLoad</span><span class="p">()</span>
|
|
<span class="c1">// Do any additional setup after loading the view, typically from a nib.</span>
|
|
<span class="k">self</span><span class="o">.</span><span class="nf">updateUI</span><span class="p">()</span>
|
|
<span class="p">}</span>
|
|
</code></pre>
|
|
</div>
|
|
</li>
|
|
<li>
|
|
<p>Create a ‘signIn()’ function that handles both sign in and out.</p>
|
|
|
|
<p>The function uses the <code class="highlighter-rouge">Blockstack.shared.signIn()</code> and
|
|
<code class="highlighter-rouge">Blockstack.shared.signOut()</code> methods to sign the user into the application.</p>
|
|
|
|
<div class="language-swift highlighter-rouge"><pre class="highlight"><code> <span class="kd">@IBAction</span> <span class="kd">func</span> <span class="nf">signIn</span><span class="p">(</span><span class="n">_</span> <span class="nv">sender</span><span class="p">:</span> <span class="kt">UIButton</span><span class="p">)</span> <span class="p">{</span>
|
|
<span class="k">if</span> <span class="kt">Blockstack</span><span class="o">.</span><span class="n">shared</span><span class="o">.</span><span class="nf">isSignedIn</span><span class="p">()</span> <span class="p">{</span>
|
|
<span class="nf">print</span><span class="p">(</span><span class="s">"Currently signed in so signing out."</span><span class="p">)</span>
|
|
<span class="kt">Blockstack</span><span class="o">.</span><span class="n">shared</span><span class="o">.</span><span class="nf">signOut</span><span class="p">()</span>
|
|
<span class="k">self</span><span class="o">.</span><span class="nf">updateUI</span><span class="p">()</span>
|
|
<span class="p">}</span> <span class="k">else</span> <span class="p">{</span>
|
|
<span class="nf">print</span><span class="p">(</span><span class="s">"Currently signed out so signing in."</span><span class="p">)</span>
|
|
<span class="c1">// Address of deployed example web app</span>
|
|
<span class="kt">Blockstack</span><span class="o">.</span><span class="n">shared</span><span class="o">.</span><span class="nf">signIn</span><span class="p">(</span><span class="nv">redirectURI</span><span class="p">:</span> <span class="s">"https://heuristic-brown-7a88f8.netlify.com/redirect.html"</span><span class="p">,</span>
|
|
<span class="nv">appDomain</span><span class="p">:</span> <span class="kt">URL</span><span class="p">(</span><span class="nv">string</span><span class="p">:</span> <span class="s">"https://heuristic-brown-7a88f8.netlify.com"</span><span class="p">)</span><span class="o">!</span><span class="p">)</span> <span class="p">{</span> <span class="n">authResult</span> <span class="k">in</span>
|
|
<span class="k">switch</span> <span class="n">authResult</span> <span class="p">{</span>
|
|
<span class="k">case</span> <span class="o">.</span><span class="nf">success</span><span class="p">(</span><span class="k">let</span> <span class="nv">userData</span><span class="p">):</span>
|
|
<span class="nf">print</span><span class="p">(</span><span class="s">"Sign in SUCCESS"</span><span class="p">,</span> <span class="n">userData</span><span class="o">.</span><span class="n">profile</span><span class="p">?</span><span class="o">.</span><span class="n">name</span> <span class="k">as</span> <span class="kt">Any</span><span class="p">)</span>
|
|
<span class="k">self</span><span class="o">.</span><span class="nf">updateUI</span><span class="p">()</span>
|
|
<span class="k">case</span> <span class="o">.</span><span class="nv">cancelled</span><span class="p">:</span>
|
|
<span class="nf">print</span><span class="p">(</span><span class="s">"Sign in CANCELLED"</span><span class="p">)</span>
|
|
<span class="k">case</span> <span class="o">.</span><span class="nf">failed</span><span class="p">(</span><span class="k">let</span> <span class="nv">error</span><span class="p">):</span>
|
|
<span class="nf">print</span><span class="p">(</span><span class="s">"Sign in FAILED, error: "</span><span class="p">,</span> <span class="n">error</span> <span class="p">??</span> <span class="s">"n/a"</span><span class="p">)</span>
|
|
<span class="p">}</span>
|
|
<span class="p">}</span>
|
|
<span class="p">}</span>
|
|
|
|
<span class="p">}</span>
|
|
</code></pre>
|
|
</div>
|
|
</li>
|
|
</ol>
|
|
|
|
<h2 id="troubleshooting-your-build-in-xcode">Troubleshooting your build in XCode</h2>
|
|
|
|
<p>XCode builds can retain old data. To ensure your builds are clean, try the following:</p>
|
|
|
|
<ol>
|
|
<li>Reset the simulator by choosing <strong>Hardware -> Erase all content and settings</strong> from the menu.</li>
|
|
<li>In XCode, clean the project by choosing <strong>Product > Clean</strong> from the menu or press ‘Command + Shift + K’ on your keyboard.</li>
|
|
<li>Clean the build folder by pressing ‘Command + Option + Shift + K’ on your keyboard.</li>
|
|
<li>Run the code on the simulator again.</li>
|
|
</ol>
|
|
|
|
<div class="share uk-text-center">
|
|
<a href="https://twitter.com/intent/tweet?text=iOS SDK Tutorial (Pre-release)&url=https://zbabystack.netlify.com/ios/tutorial.html&via=&related=" rel="nofollow" target="_blank" title="Share on Twitter" onclick="window.open(this.href, 'twitter', 'width=550,height=235');return false;"><span data-uk-icon="icon: twitter; ratio: 1.2"></span></a>
|
|
<a class="uk-margin-small-left" href="https://www.facebook.com/sharer/sharer.php?u=https%3A%2F%2Fzbabystack.netlify.com%2Fios%2Ftutorial.html" rel="nofollow" target="_blank" title="Share on Facebook" onclick="window.open(this.href, 'facebook-share','width=580,height=296');return false;"><span data-uk-icon="icon: facebook; ratio: 1.2"></span></a>
|
|
</div>
|
|
|
|
</div>
|
|
|
|
<hr class="uk-margin-medium">
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<!-- <div class="uk-margin-large-top">
|
|
<h3>Related Articles</h3>
|
|
|
|
|
|
|
|
|
|
|
|
<ul class="uk-list">
|
|
|
|
</ul>
|
|
</div>
|
|
-->
|
|
|
|
</article>
|
|
|
|
<script>
|
|
// Table of contents scroll to
|
|
UIkit.scroll('#markdown-toc a', {
|
|
duration: 400,
|
|
offset: 120
|
|
});
|
|
</script>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
</div>
|
|
|
|
|
|
<div id="offcanvas" data-uk-offcanvas="flip: true; overlay: true">
|
|
<div class="uk-offcanvas-bar">
|
|
|
|
<button class="uk-offcanvas-close" type="button" data-uk-close></button>
|
|
|
|
<ul class="uk-nav uk-nav-default">
|
|
<!-- <li><a class="uk-logo uk-margin-small-bottom" href="/"><img src="https://zbabystack.netlify.com/assets/posts/logo.png" alt="Docs"></a></li> -->
|
|
<li><a class="uk-logo uk-margin-small-bottom" href="/"><img src="/assets/posts/logo.png" alt="Docs"></a></li>
|
|
|
|
|
|
<li><a href="https://blockstack.org" target="_blank" >Blockstack.org</a></li>
|
|
|
|
|
|
<li><a href="https://forum.blockstack.org/" target="_blank" >Forums</a></li>
|
|
|
|
|
|
<li><a href="https://github.com/blockstack" target="_blank" >GitHub</a></li>
|
|
|
|
</ul>
|
|
|
|
<div class="uk-margin-small-top uk-text-center uk-text-muted uk-link-muted">
|
|
<div data-uk-grid class="uk-child-width-auto uk-grid-small uk-flex-center uk-grid">
|
|
|
|
<div class="uk-first-column">
|
|
<a href="https://twitter.com/" data-uk-icon="icon: twitter" class="uk-icon-link uk-icon" target="_blank"></a>
|
|
</div>
|
|
|
|
|
|
<div>
|
|
<a href="https://www.facebook.com/" data-uk-icon="icon: facebook" class="uk-icon-link uk-icon" target="_blank"></a>
|
|
</div>
|
|
|
|
|
|
|
|
|
|
<div>
|
|
<a href="https://www.instagram.com/" data-uk-icon="icon: instagram" class="uk-icon-link uk-icon" target="_blank"></a>
|
|
</div>
|
|
|
|
|
|
|
|
|
|
|
|
<div>
|
|
<a href="https://vimeo.com/" data-uk-icon="icon: vimeo" class="uk-icon-link uk-icon" target="_blank"></a>
|
|
</div>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
</div>
|
|
</div>
|
|
|
|
</div>
|
|
</div>
|
|
|
|
|
|
|
|
<footer class="uk-section uk-text-center uk-text-muted uk-link-muted">
|
|
<div class="uk-container uk-container-small">
|
|
|
|
<!-- <div>
|
|
<ul class="uk-subnav uk-flex-center">
|
|
|
|
|
|
|
|
|
|
<li><a href="https://blockstack.org" target="_blank" >Blockstack.org</a></li>
|
|
|
|
|
|
|
|
|
|
|
|
<li><a href="https://forum.blockstack.org/" target="_blank" >Forums</a></li>
|
|
|
|
|
|
|
|
|
|
|
|
<li><a href="https://github.com/blockstack" target="_blank" >GitHub</a></li>
|
|
|
|
|
|
</ul>
|
|
</div>
|
|
<div class="uk-margin-medium">
|
|
<div data-uk-grid class="uk-child-width-auto uk-grid-small uk-flex-center uk-grid">
|
|
|
|
<div class="uk-first-column">
|
|
<a href="https://twitter.com/" data-uk-icon="icon: twitter" class="uk-icon-link uk-icon" target="_blank"></a>
|
|
</div>
|
|
|
|
|
|
<div>
|
|
<a href="https://www.facebook.com/" data-uk-icon="icon: facebook" class="uk-icon-link uk-icon" target="_blank"></a>
|
|
</div>
|
|
|
|
|
|
|
|
|
|
<div>
|
|
<a href="https://www.instagram.com/" data-uk-icon="icon: instagram" class="uk-icon-link uk-icon" target="_blank"></a>
|
|
</div>
|
|
|
|
|
|
|
|
|
|
|
|
<div>
|
|
<a href="https://vimeo.com/" data-uk-icon="icon: vimeo" class="uk-icon-link uk-icon" target="_blank"></a>
|
|
</div>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
</div>
|
|
</div> -->
|
|
<div class="uk-margin-medium uk-text-small copyright">© 2018 Blockstack</div>
|
|
|
|
</div>
|
|
</footer>
|
|
|
|
|
|
|
|
<script type="text/javascript">
|
|
/* Create a configuration object */
|
|
var ss360Config = {
|
|
/* Your site id */
|
|
siteId: 'blockstack',
|
|
/* A CSS selector that points to your search box */
|
|
searchBox: {selector: '#searchBox'}
|
|
};
|
|
</script>
|
|
<script src="https://cdn.sitesearch360.com/sitesearch360-v11.min.js" async></script>
|
|
|
|
|
|
|
|
</body>
|
|
|
|
</html>
|
|
|