Quantcast
Channel: Kodeco | High quality programming tutorials: iOS, Android, Swift, Kotlin, Unity, and more
Viewing all 4370 articles
Browse latest View live

raywenderlich.com Abandoning Swift

$
0
0

No more Swift!

As soon as Swift was first announced, our team was quick to jump onto the Swift bandwagon.

At first it was great. The community was hyped, it was tons of fun to learn new stuff, and we started converting all of our written tutorials, video tutorials, and books.

But then the trouble began.

While we were converting our tutorials to Swift, every other week something would change in the language, forcing fresh rewrites.

“No worries”, we thought, “this is only because the language is in beta!”

However:

  • Last spring with the advent of Swift 1.2, they took away my beloved if let pyramids. “Allright”, I thought, “I’ve lost a friend, but I can carry on. Cue the rewrites!”
  • Last fall at WWDC with the advent of Swift 2.0, they took away my beloved println statement. “print doesn’t have as much style”, I complained, “but I guess it will do. Rewrite the rewrites!”
  • This spring with the advent of Swift 2.2, they deprecated my beloved ++ operator. “Now they’ve gone too far”, I growled, “We’re outta here!”

So today, I have some big news. Here on out, raywenderlich.com is officially abandoning Swift as a language – and we are never ever, ever getting back together!

Blame It All On My Roots

We’re going back to our roots – here on out, all tutorials will be in Objective-C!

Let’s face it people, Swift has problems – and it’s more than just the frequent rate of change. Let’s take a look:

  • Swift wastes time. Objective-C was great because when you need to code, you just write classes and methods and boom – you’re done.

    With Swift, you sit around thinking “Hm, I wonder if I should choose class, struct or enum?” Or “I wonder, should this be a method, or a computed property?” With all that time wasted sitting around debating, I could’ve finished coding the whole app!

  • Optionals suck. Optionals – who asked for them? I can’t remember a time my Objective-C code crashed due to messaging a nil reference – optionals simply solve a problem that doesn’t exist.

    Also, my editor said I include too many exclamation points in my writing already, so the last thing I want is them cluttering up my code too!

  • Nobody uses Swift anyway. Let’s face it, Swift is only used by hipsters. There’s stats to prove it – Swift developers have the most facial hair!

    Clean-shaven developers working with enterprise companies know: Objective-C is where it’s at.

Swift, I knew you were trouble when you walked in – so shame on me now.

Objective-C Approved

Addressing the Hipsters

I know the Swift hipsters out there might say – “But Ray – what about Swift’s additional code safety?!”

To that I say: “It’s boring playing it safe. True coders like to live on the wild side.”

But then they may exclaim – “But Ray – what about playgrounds?!”

To that I say: “Playgrounds are for kiddies. True coders just open up Xcode and start hacking.”

And then there’s the big one – “But Ray – what about Swift being open source?!”

To that I say: “True coders know that’s just Apple trying to scam people into working for them for free.”

And don’t just take my fancy arguments for it. Willi Shi, eminent developer and philosopher, argues about the disadvantages of Swift far more eloquently than I. That should silence all those pesky Swift hipsters!

Swift is Dead

Your Wish is Our Demand

At the end of the day though, it doesn’t matter what I think – it matters what you think.

But luckily, in this instance we are in agreement! Every day I get tweets like these, asking why we’ve abandoned our roots:

Tweets

Don’t worry folks, we’ve listened to you and heard your call – Objective-C is on the way!

A New Day, a New Team

This does lead to a bit of a problem. Currently, our entire tutorial team is composed of hipster Swift developers, who avoid Objective-C like the plague.

Luckily, I know just what to do, thanks to a well respected businessman and politician.

Fired!

It was fun knowing ya!

Open Call for Objective-C Authors and Tech Editors

Obviously, this means we have some rare openings on the tutorial team! In other words, we’ve got a blank space, and we’ll write your name.

If you’d like to write or tech edit some kick-ass Objective-C tutorials, please reply to this post on the forums with the answers to the following questions:

  • What’s your experience with Objective-C?
  • What part of Swift sucks the most? (It’s OK if you can’t narrow it down to just one)
  • Do you agree facial hair should be limited to eyebrows?

This is a new beginning for raywenderlich.com and this is your chance to get in on the ground floor – you’d be simply foolish not to apply.

Thanks everyone, and I wish you a happy and amusing day! :]

The post raywenderlich.com Abandoning Swift appeared first on Ray Wenderlich.


Video Tutorial: Beginning Audio with AVFoundation Part 4: Speech Synthesis

Video Tutorial: Beginning Audio with AVFoundation Part 5: Conclusion

Swift Apprentice Updated for Xcode 7.3

$
0
0

Swift Apprentice book

As many of you have guessed, our post yesterday was just an April Fools – raywenderlich.com will continue to be your best source for Swift books, tutorials, and videos! :]

And to prove it – today, we’re happy to announce that our popular book for Swift beginners, the Swift Apprentice, is now fully updated for Xcode 7.3.

Xcode 7.3 has a few small changes to Swift – mostly minor syntax things – but we wanted to make sure that all the instructions work without any issues.

In addition to updating the book for Xcode 7.3, we’ve fixed some errata pointed out by readers – thanks all!

This is a free update for existing PDF customers. Here’s how you can get your copy:

  • If you’re a Swift Apprentice PDF customer, you can download the update for free on your My Loot page (version 1.3).
  • If you haven’t picked up a copy of the Swift Apprentice yet, grab your copy now.

We’re hard at work updating the rest of our Swift books for Xcode 7.3 – stay tuned.

We I hope you enjoy this update!

The post Swift Apprentice Updated for Xcode 7.3 appeared first on Ray Wenderlich.

Video Tutorial: Beginning Video with AVFoundation: Series Introduction

Video Tutorial: Beginning Video with AVFoundation Part 1: Video Playback

React Native Tutorial: Building Apps with JavaScript

$
0
0
React Native tutorial

React Native Tutorial: Build native iOS applications with JavaScript.

Update note: This tutorial has been updated to React Native 0.22 by Tom Elliot. The original tutorial was written by iOS Team member Colin Eberhardt.

In this React Native Tutorial you’ll learn about a framework for building native iOS and Android applications from Facebook, based on the same principals behind their hugely popular React Javascript Framework for building declarative user interfaces.

Over the years there have been many frameworks using JavaScript and HTML5 to create iOS applications (such as PhoneGap or Titanium), so what makes React Native special?

  1. With React Native your application logic is written and runs in JavaScript, whereas your application UI is fully native; therefore you have none of the compromises typically associated with HTML5 UI.
  2. React introduces a novel, radical and highly functional approach to constructing user interfaces. In brief, the application UI is simply expressed as a function of the current application state.

The key point with React Native is that it aims to primarily bring the power of the React programming model to mobile app development. It is not aiming to be a cross platform, write-once run-anywhere, tool. It is aiming to be learn-once write-anywhere. An important distinction to make. This tutorial only covers iOS, but once you’ve learned the concepts here you could port that knowledge into creating an Android app very quickly.

If you have only ever written applications in Objective-C or Swift, you might not be particularly excited about the prospect of using JavaScript instead. Although, as a Swift developer, the second point above should pique your interest!

Through Swift, you’ve no doubt been learning new and more functional ways to encode algorithms, and techniques that encourage transformation and immutability. However, the way in which you construct your UI is very much the same as it was when developing with Objective-C: it’s still UIKit-based and imperative.

Through intriguing concepts such as a virtual DOM and reconciliation, React brings functional programming directly to the UI layer.

This React Native tutorial takes you through the process of building an application for searching UK property listings:

React Native tutorial

If you’ve never written any JavaScript before, fear not; this tutorial leads you through each and every step of the coding. React uses CSS properties for styling which are generally easy to read and understand, but if you need to, you can always refer to the excellent Mozilla Developer Network reference.

Want to learn more? Read on!

Getting Started

React Native uses Node.js, a JavaScript runtime, to build your JavaScript code. If you don’t already have Node.js installed, it’s time to get it!

First install Homebrew using the instructions on the Homebrew website, then install Node.js by executing the following in a Terminal window:

brew install node

Next, use homebrew to install watchman, a file watcher from Facebook:

brew install watchman

This is used by React Native to figure out when your code changes and rebuild accordingly. It’s like having Xcode do a build each time you save your file.

Next use npm to install the React Native Command Line Interface (CLI) tool:

npm install -g react-native-cli

This uses the Node Package Manager to fetch the CLI tool and install it globally; npm is similar in function to CocoaPods or Carthage and is packaged with Node.js.

The source code of the React Native framework is also available via GitHub if you wish to dig deeper.

Navigate to the folder where you would like to develop your React Native application, and use the CLI tool to construct the project:

react-native init PropertyFinder

This creates a starter-project containing everything you need to build and run a React Native application.

If you get complaints about the version of node, make sure the one installed by brew is the one in use. Run brew link --overwrite node in the terminal.

If you look at the created folders and files you will find a node_modules folder, which contains the React Native framework. You will also find an index.ios.js file, which is the skeletal app created by the CLI tool. There is also an ios folder, containing an Xcode project and the small amount of code required to ‘bootstrap’ your application. Finally, there are Android counterparts, although we won’t be touching on those in this tutorial.

Open the Xcode project file then build and run. The simulator will start and display the following greeting:

react native tutorial

Warning!: At the time of writing the default starter-project created by the React Native CLI tool contains 3 warnings when you build. So don’t worry if you see some Xcode warnings after building for the first time. The React Native team are aware of this and we’re working with them to fix the warnings in a future release of React Native :]

You might also have noticed that a terminal window has popped up, displaying the following:

 ┌──────────────────────────────────────────────┐
 │  Running packager on port 8081.                                            │
 │                                                                            │
 │  Keep this packager running while developing on any JS projects. Feel      │
 │  free to close this tab and run your own packager instance if you          │
 │  prefer.                                                                   │
 │                                                                            │
 │  https://github.com/facebook/react-native                                  │
 │                                                                            │
 └──────────────────────────────────────────────┘
Looking for JS files in
   /Users/tomelliott/Desktop/Scratch/PropertyFinder
 
[6:15:40 PM] <START> Building Dependency Graph
[6:15:40 PM] <START> Crawling File System
[6:15:40 PM] <START> Loading bundles layout
[6:15:40 PM] <END>   Loading bundles layout (0ms)
[Hot Module Replacement] Server listening on /hot
 
React packager ready.
 
[6:15:41 PM] <END>   Crawling File System (747ms)
[6:15:41 PM] <START> Building in-memory fs for JavaScript
[6:15:42 PM] <END>   Building in-memory fs for JavaScript (653ms)
[6:15:42 PM] <START> Building in-memory fs for Assets
[6:15:42 PM] <END>   Building in-memory fs for Assets (277ms)
[6:15:42 PM] <START> Building Haste Map
[6:15:42 PM] <START> Building (deprecated) Asset Map
[6:15:42 PM] <END>   Building (deprecated) Asset Map (49ms)
[6:15:42 PM] <END>   Building Haste Map (400ms)
[6:15:42 PM] <END>   Building Dependency Graph (2094ms)

This is the React Native packager, running under node. You’ll find out what it does shortly.

Don’t close the Terminal window; just keep it running in the background. If you do close it by mistake, simply stop and re-run the project via Xcode.

Note: One final thing before you get too deep in the code — you’re going to be writing a lot of JavaScript code in this tutorial, and Xcode is certainly not the best tool for this job! I use Sublime Text, which is a cheap and versatile editor, but atom, brackets or any other lightweight editor will do the job.

Hello React Native

Before getting started on the property search application, you’re going to create a very simple Hello World app. You’ll be introduced to the various components and concepts as you go along.

Open index.ios.js in your text editor of choice and delete the current contents since you’re going to build your own app from scratch. Add the following to the start of the file:

'use strict';

This enables Strict Mode, which adds improved error handling and disables some less-than-ideal JavaScript language features. In simple terms, it makes JavaScript better!

Note: For a more detailed overview of Strict Mode, I’d encourage you to read Jon Resig’s article ECMAScript 5 Strict Mode, JSON, and More.

Next, add the following line:

var React = require('react-native');

This loads the react-native module and assigns it to React. React Native uses the same module loading technology as Node.js with the require function, which is roughly equivalent to linking and importing libraries in Swift.

Note: For more information about JavaScript modules I’d recommend reading this article by Addy Osmani on writing modular JavaScript.

Just below the require statement, add the following:

var styles = React.StyleSheet.create({
  text: {
    color: 'black',
    backgroundColor: 'white',
    fontSize: 30,
    margin: 80
  }
});

This defines a single style that you will shortly apply to your “Hello World” text. If you’ve done any web development before, you’ll probably recognize those property names; React Native uses Cascading Style Sheets (CSS) to style the application UI.

Now for the app itself! Still working in the same file, add the following code just beneath the style declaration above:

class PropertyFinderApp extends React.Component {
  render() {
    return React.createElement(React.Text, {style: styles.text}, "Hello World!");
  }
}

Yes, that’s a JavaScript class!

Classes were introduced in ECMAScript 6 (ES6). As JavaScript is constantly evolving, developers are restricted in what they can use due to the need to maintain compatibility with older operating systems or browsers. Even though iOS 9 doesn’t fully support ES6, React Native is using a tool called Babel to automatically translate modern JavaScript into compatible legacy JavaScript where necessary.

Note: If you are a web developer, you can use Babel in the browser as well! There really is no excuse for using older versions of JavaScript anymore, even when supporting legacy browsers :]

PropertyFinderApp extends React.Component, the basic building block of the React UI. Components contain immutable properties, mutable state variables and expose a method for rendering. Your current application is quite simple and only requires a render method.

React Native components are not UIKit classes; instead they are a lightweight equivalent. The framework takes care of transforming the tree of React components into the required native UI.

Finally, add the following to the end of the file:

React.AppRegistry.registerComponent('PropertyFinder', function() { return PropertyFinderApp });

AppRegistry defines the entry point to the application and provides the root component.

Save your changes to index.ios.js and then return to Xcode. Ensure the PropertyFinder scheme is selected with one of the iPhone simulators, and then build and run your project. After a few seconds you’ll see your “Hello World” app in action:

React Native tutorial

That’s a JavaScript application running in the simulator, rendering a native UI, without a browser in sight!

Still don’t trust me? :] Verify it for yourself: within Xcode, select Debug\View Debugging\Capture View Hierarchy and take a look at the native view hierarchy. You will see no UIWebView instances anywhere! Your text is being displayed in a view called RCTText. But what is that? Back in Xcode select File\Open Quickly… and type in RCTView.h. Notice RCTView inherits directly from UIView. Neat!

React Native tutorial

Curious as to how it all works? In Xcode open AppDelegate.m and locate application:didFinishLaunchingWithOptions:. This method constructs a RCTRootView, which loads the JavaScript application and renders the resultant view.

When the application starts, the RCTRootView loads the application from the following URL:

http://localhost:8081/index.ios.bundle

Recall the Terminal window that was opened when you ran this application; this starts a packager and server that handles the above request.

Open this URL in Safari; you’ll see the JavaScript code for your app. You should be able to find your “Hello World” code embedded among the React Native framework.

When your app starts, this code is loaded and executed by the JavaScriptCore framework. In the case of your application, it loads the PropertyFinderApp component, then constructs the native UIKit view. You’ll learn a bit more about this later in the tutorial.

Hello World JSX

Your current application uses React.createElement to construct the simple UI for your application, which React turns into the native equivalent. While your JavaScript code is perfectly readable in its present form, a more complex UI with nested elements would rapidly become quite a mess.

Make sure the app is still running, then return to your text editor to edit index.ios.js. Modify the return statement of your component’s render method as follows:

return <React.Text style={styles.text}>Hello World (Again)</React.Text>;

This is JSX, or JavaScript syntax extension, which mixes HTML-like syntax directly in your JavaScript code; if you’re already a web developer, this should feel rather familiar. You’ll use JSX throughout this article.

Save your changes to index.ios.js and return to the simulator. Press Cmd+R, and you’ll see your application refresh to display the updated message.

hello world again

Re-running a React Native application is really as simple as refreshing a web browser! :] Note that this will only reflect changes made to your JavaScript files – native code or resource changes will require a rebuild in Xcode.

Since you’ll be working with the same set of JavaScript in this tutorial, you can leave the app running and simply refresh the app in this fashion after modifying and saving index.ios.js.

Note: If you are feeling inquisitive, take a look at your ‘bundle’ in the browser to see what the JSX is transformed into.

Okay, enough of this “Hello World” fun; it’s time to build the real application!

Adding Navigation

The Property Finder app uses the standard stack-based navigation experience provided by UIKit’s navigation controller. It’s time to add this behavior.

Within index.ios.js, rename the PropertyFinderApp class to HelloWorld:

class HelloWorld extends React.Component {

You’ll keep the “Hello World” text display around a little longer, but it won’t be the root component of your app anymore.

Next add the following class below the HelloWorld component:

class PropertyFinderApp extends React.Component {
  render() {
    return (
      <React.NavigatorIOS
        style={styles.container}
        initialRoute={{
          title: 'Property Finder',
          component: HelloWorld,
        }}/>
    );
  }
}

This constructs a navigation controller, applies a style and sets the initial route to the HelloWorld component. In web development, routing is a technique for defining the navigation structure of an application, where pages — or routes — are mapped to URLs.

Within the same file, update the styles declaration to include the container style as shown below:

var styles = React.StyleSheet.create({
  text: {
    color: 'black',
    backgroundColor: 'white',
    fontSize: 30,
    margin: 80
  },
  container: {
    flex: 1
  }
});

You’ll find out what flex: 1 means a bit later in this tutorial.

Save your changes, head back to the simulator and press Cmd+R to see your new UI in action:

React Native tutorial

There’s the navigation controller with its root view, which is currently the “Hello World” text. Excellent — you now have the basic navigation structure for your application in place. It’s time to add the ‘real’ UI!

Building the Search Page

Add a new file to the project named SearchPage.js and place it in the same folder as index.ios.js. Add the following code to this file:

'use strict';
 
var React = require('react-native');
var {
  StyleSheet,
  Text,
  TextInput,
  View,
  TouchableHighlight,
  ActivityIndicatorIOS,
  Image,
  Component
} = React;

You’ve already seen the strict mode and the react-native import before, but the assignment statement that follows it is something new.

This is a destructuring assignment, which lets you extract multiple object properties and assign them to variables using a single statement. As a result, the rest of your code can drop the React prefix; for example, you can refer directly to StyleSheet rather than React.StyleSheet. Destructuring is also useful for manipulating arrays and is well worth learning more about.

Still working in SearchPage.js, add the following style at the bottom:

var styles = StyleSheet.create({
  description: {
    marginBottom: 20,
    fontSize: 18,
    textAlign: 'center',
    color: '#656565'
  },
  container: {
    padding: 30,
    marginTop: 65,
    alignItems: 'center'
  }
});

Again, these are standard CSS properties. Setting up styles like this is less visual than using Interface Builder, but it’s better than setting view properties one by one in your viewDidLoad() methods! :]

Add the component itself just below the styles you added above:

class SearchPage extends Component {
  render() {
    return (
      <View style={styles.container}>
        <Text style={styles.description}>
          Search for houses to buy!
        </Text>
        <Text style={styles.description}>
          Search by place-name, postcode or search near your location.
        </Text>
      </View>
    );
  }
}

render is a great demonstration of JSX and the structure it provides. Along with the style, you can very easily visualize the UI constructed by this component: a container with two text labels.

Finally, add the following to the end of the file:

module.exports = SearchPage;

This exports the SearchPage class, which permits its use in other files.

The next step is to update the application routing in order to make this the initial route.

Open index.ios.js and add the following just after the current require import near the top of the file:

var SearchPage = require('./SearchPage');

Within the render function of the PropertyFinderApp class, update initialRoute to reference the newly added page as shown below:

component: SearchPage

At this point you can remove the HelloWorld class and its associated style, if you like. You won’t be needing that code any longer.

Save your changes, return to the simulator, and hit Cmd+R and check out the new UI:

React Native tutorial

This is using the new component, SearchPage, which you added.

Styling with Flexbox

So far, you’ve seen basic CSS properties that deal with margins, paddings and color. However, you might not be familiar with flexbox, a more recent addition to the CSS specification that is very useful for application UI layout.

React Native uses the css-layout library, a JavaScript implementation of the flexbox standard which is transpiled into C (for iOS) and Java (for Android).

It’s great that Facebook has created this as a separate project that targets multiple languages, since this allows for novel applications, such as applying flexbox layout to SVG.

In your app, the container has the default flow direction of column, which means its children are arranged in a vertical stack, like so:

React Native tutorial

This is termed the main axis, and can run either vertically or horizontally.

The vertical position of each child is determined from a combination of its margin, height and padding. The container also sets the alignItems property to center, which determines the placement of children on the cross axis. In this case, it results in center-aligned text.

It’s time to add the input field and buttons. Open SearchPage.js and insert the following just after the closing tag of the second Text element:

<View style={styles.flowRight}>
  <TextInput
    style={styles.searchInput}
    placeholder='Search via name or postcode'/>
  <TouchableHighlight style={styles.button}
      underlayColor='#99d9f4'>
    <Text style={styles.buttonText}>Go</Text>
  </TouchableHighlight>
</View>
<TouchableHighlight style={styles.button}
    underlayColor='#99d9f4'>
  <Text style={styles.buttonText}>Location</Text>
</TouchableHighlight>

You’ve added two top-level views here: one to hold a text input and a button, and one with only a button. You’ll read about how these elements are styled in a little bit.

In your styles definition, add a comma following the container style, then add the following new styles below it:

flowRight: {
  flexDirection: 'row',
  alignItems: 'center',
  alignSelf: 'stretch'
},
buttonText: {
  fontSize: 18,
  color: 'white',
  alignSelf: 'center'
},
button: {
  height: 36,
  flex: 1,
  flexDirection: 'row',
  backgroundColor: '#48BBEC',
  borderColor: '#48BBEC',
  borderWidth: 1,
  borderRadius: 8,
  marginBottom: 10,
  alignSelf: 'stretch',
  justifyContent: 'center'
},
searchInput: {
  height: 36,
  padding: 4,
  marginRight: 5,
  flex: 4,
  fontSize: 18,
  borderWidth: 1,
  borderColor: '#48BBEC',
  borderRadius: 8,
  color: '#48BBEC'
}

Take care with the formatting; each style property should be separated by a comma. That means you’ll need to add a trailing comma after the container selector.

These styles are used by the text input and buttons which you just added.

Save your changes, return to the simulator, and press Cmd+R to see the updated UI:

React Native tutorial

The text field and ‘Go’ button are on the same row, so you’ve wrapped them in a container view using the flowRight style which uses flexDirection: 'row' to horizontally place the items in a row. Rather than explicitly specifying the widths of the input field and button, you give each a flex value to define their relative width. The text field uses the searchInput style with flex: 4, while the button uses the button style with flex: 1; this results in their widths having a 4:1 ratio.

You might have noticed that your buttons…aren’t actually buttons! :] With UIKit, buttons are little more than labels that can be tapped, and as a result the React Native team decided it was easier to construct buttons directly in JavaScript. The buttons in your app use TouchableHighlight, a React Native component that becomes transparent and reveals the underlay color when tapped.

The final step to complete the search screen of the application is to add the house graphic. The images are available to download as a zip file. Download and unzip the file.

Next, create a directory in your root project folder and call it ’Resources’. Place the three images of the house in this directory.

Asset Catalogs: As you probably know, Apple recommends placing images in Asset Catalogs where possible. In React Native, however, it’s recommended not to. Placing your assets alongside your components helps to keep your components self contained, doesn’t require the App to be relaunched if you add new images and provides a single place for adding images if you are building on both iOS and Android.

Back in SearchPage.js, add the following beneath the closing tag of the TouchableHighlight component defining the location button:

<Image source={require('./Resources/house.png')} style={styles.image}/>

Now, add the image’s corresponding style to the end of the style list, remembering to add a trailing comma to the previous style:

image: {
  width: 217,
  height: 138
}

Save your changes. Returning to the simulator, hit Cmd+R and admire your new UI:

React Native tutorial

Note: If you don’t see the house image at this point and see an image that “house” cannot be found instead, try restarting the packager (i.e. the “npm start” command you have in the terminal).

Your current app looks good, but it’s somewhat lacking in functionality. Your task now is to add some state to your app and perform some actions.

Adding Component State

Each React component has its own state object, which is used as a key-value store. Before a component is rendered you must set the initial state.

Within SearchPage.js, add the following code to the SearchPage class, just before render():

constructor(props) {
  super(props);
  this.state = {
    searchString: 'london'
  };
}

Your component now has a state variable, with searchString set to an initial value of london.

Time to make use of this component state. Within render, change the TextInput element to the following:

<TextInput
  style={styles.searchInput}
  value={this.state.searchString}
  placeholder='Search via name or postcode'/>

This sets the TextInput value property — that is, the text displayed to the user — to the current value of the searchString state variable. This takes care of setting the initial state, but what happens when the user edits this text?

The first step is to create a method that acts as an event handler. Within the SearchPage class add the following method below the constructor:

onSearchTextChanged(event) {
  console.log('onSearchTextChanged');
  this.setState({ searchString: event.nativeEvent.text });
  console.log(this.state.searchString);
}

This takes the value from the native browser event’s text property and uses it to update the component’s state. It also adds some logging code that will make sense shortly.

To wire up this method so it gets called when the text changes, return to the TextInput field within the render method and add an onChange property so the tag looks like the following:

<TextInput
  style={styles.searchInput}
  value={this.state.searchString}
  onChange={this.onSearchTextChanged.bind(this)}
  placeholder='Search via name or postcode'/>

Whenever the user changes the text, you invoke the function supplied to onChange; in this case, it’s onSearchTextChanged.

Note: You might be wondering what the bind(this) statement is for. JavaScript treats the this keyword a little differently than most other languages; its counterpart in Swift is self. The use of bind in this context ensures that inside the onSearchTextChanged method, this is a reference to the component instance. For more information, see the MDN page on this.

There’s one final step before you refresh your app again: add the following logging statement to the top of render(), just before return:

console.log('SearchPage.render');

You are about to learn something quite intriguing from these log statements! :]

Save your changes, return to your simulator, then press Cmd+R. You should now see that the text input has an initial value of ‘london’ and that editing the text causes some statements to be logged to the Xcode console:

React Native tutorial

Looking at the screenshot above, the order of the logging statement seems a little odd:

  1. This is the initial call to render() to set up the view.
  2. You invoke onSearchTextChanged() when the text changes.
  3. You then update the component state to reflect the new input text, which triggers another render.
  4. onSearchTextChanged() then wraps things up by logging the new search string.

Whenever the app updates the state of any React component, this triggers an entire UI re-rendering that in turn calls the render of all of your components. This is a great idea, as it entirely de-couples the rendering logic from the state changes that affect the UI.

With most other UI frameworks, it is either your responsibility to manually update the UI based on state changes, or it’s done via some type of binding framework which creates an implicit link between the application state and its UI representation. For an example of the later, see this article on implementing the MVVM pattern with ReactiveCocoa.

With React, you no longer have to worry about which parts of the UI might be affected by a state change; your entire UI is simply expressed as a function of your application state.

At this point you’ve probably spotted a fundamental flaw in this concept. Yes, that’s right — performance!

Surely you can’t just throw away your entire UI and re-build it every time something changes? This is where React gets really smart. Each time the UI renders itself, it takes the view tree returned by your render methods, and reconciles — or diffs — it with the current UIKit view. The output of this reconciliation process is a simple list of updates that React needs to apply to the current view. That means only the things that have actually changed will re-render.

It’s amazing to see the novel concepts that make ReactJS so unique — the virtual-DOM (Document Object Model, the visual-tree of a web document) and reconciliation — applied to an iOS app.

You can wrap your head around all that later; you still have some work to do in the app. First, remove the logging code you just added above, since it’s no longer necessary and just adds cruft to the code.

Initiating a Search

In order to implement the search functionality you need handle the ‘Go’ button press, create a suitable API request, and provide a visual indication to the user that a query is in progress.

Within SearchPage.js, update the initial state within the constructor:

this.state = {
  searchString: 'london',
  isLoading: false
};

The new isLoading property will keep track of whether a query is in progress.

Add the following logic to the start of render:

var spinner = this.state.isLoading ?
  ( <ActivityIndicatorIOS
      size='large'/> ) :
  ( <View/>);

This is a ternary if statement that either adds an activity indicator or an empty view, depending on the component’s isLoading state. Because the entire component is rendered each time, you are free to mix JSX and JavaScript logic.

Within the JSX that defines the search UI in return, add the following line below the Image to place the spinner:

{spinner}

Next, add the following methods to the SearchPage class:

_executeQuery(query) {
  console.log(query);
  this.setState({ isLoading: true });
}
 
onSearchPressed() {
  var query = urlForQueryAndPage('place_name', this.state.searchString, 1);
  this._executeQuery(query);
}

_executeQuery() will eventually run the query, but for now it simply logs a message to the console and sets isLoading appropriately so the UI can show the new state.

Note: JavaScript classes do not have access modifiers, so they have no concept of ‘private’. As a result you often see developers prefixing methods with an underscore to indicate that they should be considered private.

onSearchPressed() configures and initiates the search query. This should kick off when the ‘Go’ button is pressed. To accomplish that, go back to the render method and add the following property within the opening TouchableHighlight tag that renders the ‘Go’ text:

onPress={this.onSearchPressed.bind(this)}

Finally, add the following utility function just above the SearchPage class declaration:

function urlForQueryAndPage(key, value, pageNumber) {
  var data = {
      country: 'uk',
      pretty: '1',
      encoding: 'json',
      listing_type: 'buy',
      action: 'search_listings',
      page: pageNumber
  };
  data[key] = value;
 
  var querystring = Object.keys(data)
    .map(key => key + '=' + encodeURIComponent(data[key]))
    .join('&');
 
  return 'http://api.nestoria.co.uk/api?' + querystring;
};

This function doesn’t depend on SearchPage, so it’s implemented as a free function rather than a method. It first creates the query string based on the parameters in data. Following this, it transforms the data into the required string format, name=value pairs separated by ampersands. The => syntax is an arrow function, another recent addition to the JavaScript language that provides a succinct syntax for creating anonymous functions.

Save your changes, head back to the simulator, and press Cmd+R to reload the application and tap the ‘Go’ button. You’ll see the activity indicator spin; take a look at the Xcode console to see what it’s telling you:

React Native tutorial

The activity indicator renders and the URL for the required query appears in the log. Copy and paste that URL into your browser to see the result. You’ll see a massive JSON object. Don’t worry — you don’t need to understand that! You’ll add code to parse that now.

Note: This app makes use of the Nestoria API for searching property listings. The JSON response coming back from the API is pretty straightforward, but you can have a look at the documentation for all the details on the expected request URL and response formats.

The next step is to make the request from within your application.

Performing an API Request

Still within SearchPage.js, update the initial state in the class constructor to add a message variable:

this.state = {
  searchString: 'london',
  isLoading: false,
  message: ''
};

Within render, add the following to the bottom of your UI:

<Text style={styles.description}>{this.state.message}</Text>

You’ll use this to display a range of messages to the user.

Within the SearchPage class, add the following code to the end of _executeQuery():

fetch(query)
  .then(response => response.json())
  .then(json => this._handleResponse(json.response))
  .catch(error =>
     this.setState({
      isLoading: false,
      message: 'Something bad happened ' + error
   }));

This makes use of the fetch function, which is part of the Web API, and provides a vastly improved API versus XMLHttpRequest. The asynchronous response is returned as a promise, with the success path parsing the JSON and supplying it to _handleResponse which you are going to add next.

The final step is to add the following function to SearchPage:

_handleResponse(response) {
  this.setState({ isLoading: false , message: '' });
  if (response.application_response_code.substr(0, 1) === '1') {
    console.log('Properties found: ' + response.listings.length);
  } else {
    this.setState({ message: 'Location not recognized; please try again.'});
  }
}

This clears isLoading and logs the number of properties found if the query was successful.

Note: Nestoria has a number of non-1** response codes that are potentially useful. For example, 202 and 200 return a list of best-guess locations. When you’ve finished building your app, why not try handling these and present a list of options to the user?

Save your work, then in the simulator press Cmd+R and try searching for ‘london’; you should see a log message saying that 20 properties (the default result size) were found. Next try a non-existent location, such as ‘narnia’ (sniff), and you’ll be greeted by the following message:

React Native tutorial

It’s time to see what those 20 properties in real places such as London look like!

Displaying the Results

Create a new file SearchResults.js, and add the following:

'use strict';
 
var React = require('react-native');
var {
  StyleSheet,
  Image,
  View,
  TouchableHighlight,
  ListView,
  Text,
  Component
} = React;

Yes, that’s right, it’s a require statement that includes the react-native module, and a destructuring assignment. You’ve been paying attention haven’t you? :]

Next add the component itself:

class SearchResults extends Component {
 
  constructor(props) {
    super(props);
    var dataSource = new ListView.DataSource(
      {rowHasChanged: (r1, r2) => r1.guid !== r2.guid});
    this.state = {
      dataSource: dataSource.cloneWithRows(this.props.listings)
    };
  }
 
  renderRow(rowData, sectionID, rowID) {
    return (
      <TouchableHighlight
          underlayColor='#dddddd'>
        <View>
          <Text>{rowData.title}</Text>
        </View>
      </TouchableHighlight>
    );
  }
 
  render() {
    return (
      <ListView
        dataSource={this.state.dataSource}
        renderRow={this.renderRow.bind(this)}/>
    );
  }
 
}

The above code makes use of a more specialized component — ListView — which displays rows of data within a scrolling container, similar to UITableView. You supply data to the ListView via a ListView.DataSource, and a function that supplies the UI for each row.

When constructing the data source, you provide a function that compares the identity of a pair of rows. The ListView uses this during the reconciliation process, in order to determine the changes in the list data. In this instance, the properties returned by the Nestoria API have a guid property, which is a suitable check for this purpose.

Now add the module export to the end of the file:

module.exports = SearchResults;

Add the following to SearchPage.js near the top of the file, underneath the require call for React:

var SearchResults = require('./SearchResults');

This allows us to use the newly added SearchResults class from within the SearchPage class.

Modify the current _handleResponse method by replacing the console.log statement with the following:

this.props.navigator.push({
  title: 'Results',
  component: SearchResults,
  passProps: {listings: response.listings}
});

The above code navigates to your newly added SearchResults component and passes in the listings from the API request. Using the push method ensures the search results are pushed onto the navigation stack, which means you’ll get a ‘Back’ button to return to the root.

Save your changes, head back to the simulator, press Cmd+R and try a quick search. You’ll be greeted by a list of properties:

React Native tutorial

It’s great to see the property listings, but that list is a little drab. Time to liven things up a bit.

A Touch of Style

This React Native code should be starting to look familiar by now, so this tutorial is going to pick up the pace.

Add the following style definition just after the destructuring assignment in SearchResults.js:

var styles = StyleSheet.create({
  thumb: {
    width: 80,
    height: 80,
    marginRight: 10
  },
  textContainer: {
    flex: 1
  },
  separator: {
    height: 1,
    backgroundColor: '#dddddd'
  },
  price: {
    fontSize: 25,
    fontWeight: 'bold',
    color: '#48BBEC'
  },
  title: {
    fontSize: 20,
    color: '#656565'
  },
  rowContainer: {
    flexDirection: 'row',
    padding: 10
  }
});

This defines all the styles that you are going to use to render each row.

Next replace renderRow() with the following:

renderRow(rowData, sectionID, rowID) {
  var price = rowData.price_formatted.split(' ')[0];
 
  return (
    <TouchableHighlight onPress={() => this.rowPressed(rowData.guid)}
        underlayColor='#dddddd'>
      <View>
        <View style={styles.rowContainer}>
          <Image style={styles.thumb} source={{ uri: rowData.img_url }} />
          <View  style={styles.textContainer}>
            <Text style={styles.price}>£{price}</Text>
            <Text style={styles.title}
                  numberOfLines={1}>{rowData.title}</Text>
          </View>
        </View>
        <View style={styles.separator}/>
      </View>
    </TouchableHighlight>
  );
}

This manipulates the returned price, which is in the format ‘300,000 GBP’, to remove the GBP suffix. Then it renders the row UI using techniques that you are by now quite familiar with. Of note, an Image is added to the row and is loaded from a returned URL (rowData.img_url) which React Native decodes off the main thread.

Also, note the use of an arrow function in the onPress property of the TouchableHighlight component; this is used to capture the guid for the row.

The final step is to add this method to the class to handle the press:

rowPressed(propertyGuid) {
  var property = this.props.listings.filter(prop => prop.guid === propertyGuid)[0];
}

This method locates the property that was tapped by the user. It doesn’t do anything with it yet, but you’ll fix that shortly. But right now, it’s time to admire your handiwork.

Save your work, head back to the simulator, press Cmd+R and check out your results:

React Native tutorial

That looks a lot better — although it’s a wonder anyone can afford to live in London!

Time to add the final view to the application.

Property Details View

Add a new file PropertyView.js to the project, then add the following to the top of the file:

'use strict';
 
var React = require('react-native');
var {
  StyleSheet,
  Image,
  View,
  Text,
  Component
} = React;

Surely you can do this in your sleep by now! :]

Next add the following styles:

var styles = StyleSheet.create({
  container: {
    marginTop: 65
  },
  heading: {
    backgroundColor: '#F8F8F8',
  },
  separator: {
    height: 1,
    backgroundColor: '#DDDDDD'
  },
  image: {
    width: 400,
    height: 300
  },
  price: {
    fontSize: 25,
    fontWeight: 'bold',
    margin: 5,
    color: '#48BBEC'
  },
  title: {
    fontSize: 20,
    margin: 5,
    color: '#656565'
  },
  description: {
    fontSize: 18,
    margin: 5,
    color: '#656565'
  }
});

Then add the component itself:

class PropertyView extends Component {
 
  render() {
    var property = this.props.property;
    var stats = property.bedroom_number + ' bed ' + property.property_type;
    if (property.bathroom_number) {
      stats += ', ' + property.bathroom_number + ' ' + (property.bathroom_number > 1
        ? 'bathrooms' : 'bathroom');
    }
 
    var price = property.price_formatted.split(' ')[0];
 
    return (
      <View style={styles.container}>
        <Image style={styles.image}
            source={{uri: property.img_url}} />
        <View style={styles.heading}>
          <Text style={styles.price}>£{price}</Text>
          <Text style={styles.title}>{property.title}</Text>
          <View style={styles.separator}/>
        </View>
        <Text style={styles.description}>{stats}</Text>
        <Text style={styles.description}>{property.summary}</Text>
      </View>
    );
  }
}

The first part of render() performs some manipulation on the data. As is often the case, the data returned by the API is of mixed quality and often has missing fields. This code applies some simple logic to make the data a bit more presentable.

The rest of render is quite straightforward; it’s simply a function of the immutable state of this component.

Finally add the following export to the end of the file:

module.exports = PropertyView;

Head back to SearchResults.js and add the require statement to the top of the file, just underneath the React require line:

var PropertyView = require('./PropertyView');

Next update rowPressed() to navigate to your newly added PropertyView:

rowPressed(propertyGuid) {
  var property = this.props.listings.filter(prop => prop.guid === propertyGuid)[0];
 
  this.props.navigator.push({
    title: "Property",
    component: PropertyView,
    passProps: {property: property}
  });
}

You know the drill: save your changes, head back to the Simulator, press Cmd+R, and go all the way to the property details by running a search and tapping on a row:

React Native tutorial

Affordable living at it’s finest — that’s a fancy looking pad!

Your app is almost complete; the final step is to allow users to search for nearby properties.

Geolocation Search

Within Xcode, open Info.plist and edit the NSLocationWhenInUseUsageDescription row to the following value:

PropertyFinder would like to use your location to find nearby properties

Here’s how your plist file will look once you’ve added the new value:

React Native tutorial

This key details the prompt that you’ll present to the to the user to request access to their current location.

Open SearchPage.js, locate the TouchableHighlight that renders the ‘Location’ button and add the following property value:

onPress={this.onLocationPressed.bind(this)}

When you tap the button, you ‘ll invoke onLocationPressed — you’re going to add that next.

Add the following within the body of the SearchPage class:

onLocationPressed() {
  navigator.geolocation.getCurrentPosition(
    location => {
      var search = location.coords.latitude + ',' + location.coords.longitude;
      this.setState({ searchString: search });
      var query = urlForQueryAndPage('centre_point', search, 1);
      this._executeQuery(query);
    },
    error => {
      this.setState({
        message: 'There was a problem with obtaining your location: ' + error
      });
    });
}

The current position is retrieved via navigator.geolocation; this is an interface defined by the Web API, so it should be familiar to anyone who has used location services within the browser. The React Native framework provides its own implementation of this API using the native iOS location services.

If the current position is successfully obtained, you invoke the first arrow function; this sends a query to Nestoria. If something goes wrong, you’ll display a basic error message instead.

Since you’ve made a change to the plist, you’ll need to relaunch the app to see your changes. No Cmd+R this time — sorry. Stop the app in Xcode, and build and run your project.

Before you use the location-based search, you need to specify a location that is covered by the Nestoria database. From the simulator menu, select Debug\Location\Custom Location … and enter a latitude of 55.02 and a longitude of -1.42, the coordinates of a rather nice seaside town in the North of England that I like to call home!

Now hit the Location button, allow location services, and check your results!

React Native tutorial

Note from Ray: Location searching worked for some of us, but not for others (reporting an access denied error even though we gave access) – we’re not sure why at the moment, perhaps an issue with React Native? If anyone has the same issue and figures it out, please let us know.

It’s not quite as swank as London — but it’s a lot more affordable! :]

Where To Go From Here?

Congratulations on completing your first React Native application! You can find the complete project here if you just want the code to look through or want to compare notes :]

If you come from the web world, you can see how easy it is to define your interface and navigation with JavaScript and React to get a fully native UI from your code. If you work mainly on native apps, I hope you’ve gained a feel for the benefits of React Native: fast app iteration, modern JavaScript and clear style rules with CSS.

Perhaps you might write your next app using this framework? Or then again, perhaps you will stick with Swift or Objective-C? Whichever path you take, I hope you have learned something new and interesting in this article, and can carry some of the principles forward into your next project.

If you have any questions or comments on this React Native tutorial, feel free to join the discussion in the forums below!

The post React Native Tutorial: Building Apps with JavaScript appeared first on Ray Wenderlich.

Open Call For Applications: Unity Authors and Tech Editors

$
0
0

OpenCall-Unity-feature

Have you ever wanted to teach people how to approach a certain problem that wasn’t covered in any book or blog post?

Have you ever been frustrated that a game development tutorial didn’t dive as deep into a subject as you expected?

Do you love Unity?

If you answered yes to any of these questions, then you may have the makings of either a writer or tech editor extraordinaire! But not just any writer or tech editor, rather, a Unity writer or a Unity tech editor.

That right, we’re looking for great new authors and editors to join our team. Keep reading to find out what’s involved, and how to apply!

Note: This is not a full time job; these are part-time informal positions you can do in the evenings/weekends.

Why Join Our Team?

Here are the top 5 reasons to join the Unity tutorial team:

  1. Learning. You’ll always be learning something new – and will have fun doing it! You’ll become a better developer, writer, and person, and make a lot of new friends along the way.
  2. Money! Get paid to learn! We offer the highest rates in the industry.
  3. Special Opportunities. Members of the Tutorial Team get access to special opportunities such as contributing to our books and products, speaking at our conference, being a guest on our podcast, working on team projects, and much more.
  4. You’ll Make a Difference. We get emails every day about how our tutorials help our readers make their first app, get their dream job, or accomplish a lifelong dream of making their own game. This means a lot to us and makes all the hard work worth it!
  5. Free Stuff! And as a final bonus, by joining the Tutorial Team you will get a lot of free stuff! You’ll get a free copy of all of the products we sell on the site – over $1,000 in value!

Aww Yeah!

Requirements and How to Apply

Here are the requirements:

  • You must be an advanced-level Unity developer.
  • You should be a great writer with fluent English writing skills.
  • You should be comfortable learning brand new topics that you have never done before, which are either not documented or poorly documented.
  • You should have a strong work ethic – this will be a significant time commitment and is not easy.

To apply, send our Unity Team Lead Brian Moakley an email , with the following details:

  • Why do you want to be an Unity Writer or Tech Editor
  • Please tell me a little bit about yourself and your experience.
  • What is the best Unity game you’ve made or worked on, and why are you proud of the work you did on this game? [Please include link]
  • Please link to any examples of technical writing you have done in the past.
  • Please include links to: your GitHub account, your StackOverflow account, your Twitter account.

If you are applying for an author, you will be required to write a sample tutorial to gauge your writing skills. For applicants applying as a tech editor, you will be given you a tech editor tryout which will gauge your editing skills.

If you pass the tryout, you’re in!

Now’s The Time

If you’ve ever been thinking about joining the Tutorial Team in the past, and have some Unity experience, this is a great time. We could really use the help, and we may have a secret project around the corner that you could get in on the ground floor :]

Thanks all – the Unity Team and I look forward to creating some great tutorials with you! :]

The post Open Call For Applications: Unity Authors and Tech Editors appeared first on Ray Wenderlich.


Android App Distribution Tutorial: From Zero to Google Play Store

$
0
0

AndroidAppDistribution_feature

You have finished your Android app, and celebrated its perfection with many flagons of ale (or pitchers of beer). Hooray! Now you’re ready to send your app out into the world. Soon it will reside not only on your own Android device, but on the devices of people around the globe. It’s an exciting step!

There are several ways to distribute your Android app. This Android app distribution tutorial will cover two of the most common channels: the Google Play Store, where over 1.8 million Android apps are available, and the Amazon Appstore, which has over 300,000.

In this step-by-step tutorial, you’ll see how to take your finished Android app and release it to the Google Play Store and other stores. Let’s get shipping! :]

Getting Started

To publish an app, you first need … a finished app, of course :] For this tutorial, you’ll use a simple app that allows users to search for books, see book covers, and share books with friends.

Download and unzip this archive and open the project in Android Studio.

Note: If you have a finished Android app of your own, you can use it instead of the sample app, and work alongside this tutorial to put it in the store.

Before going any further, you must set a new package name across the app. The package name needs to be unique and remain unchanged in Google Play. A common format is the reverse-domain name, like this:

com.your_domain_name.app_name

Currently, the best way to refactor an app’s package name in Android Studio is to start in the Project pane of Android Studio, with the Android view chosen. Select the gear icon that looks like this:

gear_icon

You will see a drop-down menu with several project viewing options. Uncheck Compact Empty Middle Packages if it is not already unchecked:

compact_empty_middle_packages

Now you can refactor the parts of the package name separately. Right-click on the package named example, select Refactor\Rename, and change it to your name or domain name. Then do the same for the package omgandroid. Your project should now look like this (with your own names instead of mine):

renamed_packages

Next, open build.gradle (the one labeled Module: OMGAndroid, NOT the one for whole project), and find defaultConfig. Add a applicationId parameter with your new package name:

defaultConfig {
  applicationId 'com.colemanfrancis.bookmastergeneral'
  minSdkVersion 14
  targetSdkVersion 23
}

Finally, open manifest\AndroidManifest.xml, find the manifest tag at the top of the file, and locate the package attribute within it. Update it with your new package name:

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
  package="com.colemanfrancis.bookmastergeneral"
  android:versionCode="1"
  android:versionName="1.0">

Build and run to verify that your refactoring worked correctly. With your unique package name in hand, you’re now ready to package your app for distribution.

Creating a Signed APK

When developing on the Android operating system, you use the Android application package (APK) format to distribute apps.

Android requires that APKs are digitally signed with a certificate before they can be installed. The certificate is used to identify the author of the app. More information about app signing can be found here.

A signed APK can be generated manually from command line or in Android Studio.

In Android Studio, select Build\Generate Signed APK….

generate_signed_apk

Your app only has one module, so select Next.

signed_apk_module

With your app module chosen, you need to tell Android Studio how to sign the APK. You’ll use a key store, which will stay private to you. Android Studio will guide you through creating a new key store; start by selecting Create new….

keystore_info_empty

Choose a filename and location on your system, set and confirm a secure password, and fill in the rest of the information about yourself:

new_keystore

Click OK, and Android Studio will create your key store. You’ll need that file, with its password info, to make any updates to your app, so don’t lose it!

With your new key store, Android Studio returns you to the dialog box you saw before. Now the key store information is pre-filled, so just click Next.

keystore_info_prefilled

Choose a destination folder for your signed APK, specify your Build Type as release, and click Finish.

choose_destination_folder

When the packaging process is complete, Android Studio will notify you that your APK is ready, and let you open it in Finder:

reveal_in_finder

With your APK in hand, it’s time to head to the store.

The Google Play Developer Console

To submit an app to Google Play, you first need a Google Account. Create one here (or sign in, if you already have an account) before going further.

When you are signed into your Google Account, navigate to the Google Play Developer Console. You should see a screen like this:

Google Play Developer Console

Agree to the Google Play Developer distribution agreement, pay the one-time $25 Google Developer Registration Fee, then complete your Developer Profile on this screen:

developer_profile

With your developer account now registered, your developer console has more options. Click Publish an Android App on Google Play to continue.

console_signed_in

Since this is your first application, you’re given a dialog box to specify the app name and a choice on how to begin. Type in your app name and choose Upload APK.

add_new_application

This creates a draft store listing for your app, currently containing nothing except the app title. To begin, click Upload your first APK to Production.

New Store Listing

Choose the APK file you created earlier, and upload it. When the upload is complete, you will see the app listing updated like this:

upload_successful

Notice that the check mark next to APK is green, indicating that your APK is ready!

Time to move on to the remaining check marks…

Completing the Store Listing

Bookmaster General is a pretty simple app, so the rest of the process will be easy. Click on the Store Listing check mark in the menu on the left page and fill in the Short Description and Full Description fields with information about the app:

app_descriptions

Note: For your own app, you will want to create as engaging a description as possible, so start thinking about this early in the development process!

Next, upload at least two screenshots of the app. If you have the app on an Android device, you can simply take screenshots straight from the device.

If you prefer to use an emulator for the screenshots, you can easily make these in Android Studio. Build and run the app, then navigate to the part of the app where you’d like the screenshot.

With the Android Monitor tab opened in Android Studio, click the camera icon on the far left:

screen_capture

Android Studio will present you with the captured image from the emulator. Click Save and select the file location on your system.

Drag these images onto your store listing where you see the following prompt:

add_screenshot

In addition to screenshots, you need to upload a 512×512 high-resolution version of the app icon and a 1024×500 “feature graphic” to display at the top of the page. For our sample app, use these resources:

Sample App Icon

Sample Feature Graphic

Complete the store listing by specifying an Application Type, Category, Content rating, and Contact Email. Other fields are optional.

Scroll back to the top of the store listing and click Save draft. Since the listing is now complete, the Store Listing check mark is now green. We’re making progress!

Click on the Content Rating check mark to see a description of the upcoming content rating questionnaire.

content_rating

This questionnaire asks a straightforward series of questions about the content of the app. For those using our sample app, Bookmaster General is in the Reference, News, or Educational category; answer No to all the content questions. If you’re using your own app, give the appropriate answers.

Once you are finished, click Save questionnaire, then Calculate rating. You will see the ratings for the various locales where your app may be on sale:

ratings_completed

Scroll to the bottom of the list and click Apply rating. The Content Rating check mark is now green.

Select the Pricing & Distribution check mark for the final step: setting the price of your app, and in which countries it will be available. For this example, the app will be free and available universally.

whole_universe

The Free pricing option is selected by default, so keep that choice. Check the box next to SELECT ALL COUNTRIES.

pricing

Scroll down past the list of countries, and you will find several more distribution options. Check the boxes by Content guidelines and US export laws to indicate your app’s compliance with relevant rules, then scroll to the top of the page and click Save draft.

With that, the final check box is green, and the Publish app button in the top-right of the console is now active! When you’re satisfied with your app and store listing, go ahead and click it.

Your app listing status now updates to Pending Publication, like this:

pending_publication

It generally takes at least a few hours for your app to be available in Google Play, so go grab some pizza. Eventually you’ll see a listing like this one:

listed_in_store

Congratulations on your first app in Google Play!

Other Distribution Channels (Optional)

While Google Play is the main channel for distribution, you are free to distribute your APK through other means. Consider this section as a reference in case you want to try one of them.

Unknown Sources

There is a big caveat to using any method other than Google Play for distributing your app: the users must have the Unknown sources setting enabled on their Android device to allow an APK not from Google Play. Some carriers do not allow this setting to be turned on at all. More information is available here.

This option is usually available in the Settings app under Security:

unknown_sources

Note that, on some devices, there is a rather foreboding message to warn the user of malicious APKs when the user turns on Unknown sources:

scary_dialog

scared_face

Just be aware that some users are not going to want to live dangerously.

Amazon Appstore

The Amazon Appstore is powered by Amazon, registration as a developer is free, and the store is non-exclusive, so you can submit your app to both Google Play and the Amazon Appstore.

To get started here, navigate to the Amazon developer portal. Create a new Amazon account or sign in with an existing one.

When you first join the developer program, you are asked to verify address and company information for use in your app listings. You also have a developer agreement to accept, and Amazon asks you if you plan to charge money for your apps. If you are publishing your apps for free, mark that choice and complete your registration. If you do plan to monetize your app, Amazon will ask for your financial information.

Once registered, you are returned to an empty Developer Console. Scroll down and click Add a New App.

amazon_developer_console

When asked to choose a platform, choose Android and click Next. You then fill out general information on your app, along with support contact information. When finished, click Save to move on.

amazon_new_app

Now you have a listing page for your app. Similar to Google Play, there are several steps to accomplish before the Submit app button will become active.

amazon_listing_page

First, select Availability & Pricing. Choose Standard app, all countries, free app, and note the date the app was available elsewhere, if applicable. Then click Save.

amazon_availability_and_pricing

Next, click the Description tab, fill out the required app description info, and click Save.

amazon_app_description

The contents for Images & Multimedia are mostly already prepared from your Google Play listing, except for a smaller version of your app icon. The app screenshot dimensions are more specific here, so you may have to do some resizing. You also need three app screenshots here instead of the two required by Google Play.

Upload those images and click Save.

The Content Rating tab has a questionnaire similar to the one on Google Play. Supply your answers about any potentially objectionable content and click Save.

Upload your signed APK under the Binary File(s). When the upload finishes, you may get a warning that some older Amazon devices aren’t supported by your app. Click Edit device support to the right of Amazon Fire phones and tablets:

amazon_device_support

De-select the unsupported devices with warning labels and click OK.

amazon_device_list_unselected

Wrap up by checking the box next to Export Compliance, then click Save.

You’re ready to submit, so scroll down your store listing and click Submit App.

If your submission is successful, your store listing will look like this:

amazon_submitted

Several hours later, pending Amazon approval, your app will be live! Here is the Bookmaster General listing:

bookmaster_amazon

HockeyApp and Crashlytics

While not app stores, HockeyApp (owned by Microsoft) and Crashlytics (owned by Twitter) are two leading platforms for beta testing. You can easily sign up beta testers and other team members, manage versions, and track app crashes. Each supports iOS apps, which could make beta testing simpler if you are developing for both platforms.

Note that Google Play also has Alpha and Beta channels built in, so you have several good options for pre-release distribution.

Google Play Private Channel

If you are already maintaining Google Apps for your organization (Gmail, Google Calendar, Drive, etc), you can create a private channel of Google Play for your employees. Then when you publish an Android app, you can make it available only on this private channel instead of to the whole public. See Google Support for more info.

Google App Streaming

In a new service, Google is beginning to run versions of mobile apps on virtual machines in Google’s cloud. This means that users may be able to “stream” your app’s native content without needing to download your app.

This app streaming is only available on a few launch partners at the moment, but be aware that the trend is coming soon.

Hosting on Your Own Website or Via Email

As long as users have Unknown sources enabled, you are free to send them your APK file however you like. You can even simply host the file on your website or send it over email! For instance, even a service like HockeyApp or Crashlytics would be too much for an extremely early demo meant for a few coworkers, so you can simply email them the APK.

Where to Go From Here?

The Google Play Developer Console has several other features, such as teammate invitations and Google Apps keys (necessary for apps that use Google Maps and similar services). You can read about these features and more on the Android Developer page and the Google Play Developer Help Center.

I hope this Android app distribution tutorial helps you get your apps into the hands of real users! If you have any questions or comments, please join the forum discussion below.

The post Android App Distribution Tutorial: From Zero to Google Play Store appeared first on Ray Wenderlich.

Video Tutorial: Beginning Video with AVFoundation Part 2: Capturing Media: Images

Opportunity: Front-End Designer/Developer at raywenderlich.com

$
0
0
Come work with us!

Come work with us!

As you might know, this site is a community effort of over 100 part-time authors and editors, who team up to write high quality tutorials and books.

But you might not know that we also have 6 full-time employees too. Our job is to keep things running smoothly, create video tutorials, and to run our annual conference, RWDevCon.

Today, we are happy to announce an opportunity for a new full-time position: Front-End Designer/Developer at raywenderlich.com!

If you are a great designer with some front-end skills or know someone who is, keep reading to find out what’s involved!

What’s Involved

We are seeking a highly motivated and talented individual to join our team as our a front-end designer with some developer skills, to help make a major overhaul of this site.

This is a great chance to work on a green-field project with some great developers using lots of exciting new tech, and to take an already popular site to the next level! :]

Better yet – our team is distributed, so you can work remotely from the comfort of your own home – from anywhere in the world.

The ideal candidate will possess the following skills:

Design Skills

  • Strong Design skills
  • Strong U/X skills
  • Able to create mockups of websites in design tool of your choice (sketch / photoshop / framer.js etc)

Development Skills

  • Experience building front-end web apps
  • Strong HTML5 skills
  • Strong CSS3 skills
  • Strong JS skills
  • Good understanding of responsive web design
  • Good understanding of front-end frameworks like Bootstrap, Foundation, etc
  • Experience with different JavaScript frameworks for the above

Non-technical Skills

  • Self-driven work ethic. You need to be a self-starter who loves taking initiative and seeing things through to completion.
  • Detail oriented and highly organized. We are a small company with a lot to do, so you should be able to work on and prioritize multiple tasks at any given time, and stay very organized.
  • Great communication skills. We’re a distributed team, so frequent and clear written communication is a must.
  • Friendly personality. We pride ourselves on being a friendly and open bunch, and this is especially important because you will be frequently interacting with customers and external team members.
  • Curiosity and the desire to learn. Our business is changing and growing fast – who knows what will be the skills of tomorrow?
  • Bonus items! Bonus if you like Apple products, video games, board games, zombies, and/or know what the word “chuffed” means – you’ll fit right in! :]
If you like zombie cats, even better!

If you like zombie cats, even better!

About Razeware

Razeware is the company behind this site. We’re passionate about learning new development skills, and teaching others what we’ve learned through high quality, hands-on tutorials.

We are a small company that has been profitable for over 6 years. Currently we have just 6 full-time employees, so you’d be getting in on the ground floor.

We’re also a 100% distributed company: everyone works from their own home or office, whether it be Maryland, Virginia, Connecticut, or England. We make heavy use of Trello, Slack, Google Hangouts, and email for team communication.

We have a ton of great benefits, such as:

  • Remote working!
  • Health insurance and 401K match (US only)
  • Generous PTO – plus 1-week company-wide Christmas vacation
  • Competitive salary
  • Professional development (conferences & training)
  • Free trip to our annual conference – RWDevCon

RWDevCon

Our site is helping millions of developers across the world make apps, further their careers, and fulfill lifelong dreams. If you’re passionate about helping our small but highly motivated team take this to the next level, this is the job for you.

How To Apply

To apply, please email a resume and cover letter to ray@razeware.com.

Otherwise, please help spread the word about this post – we really appreciate it.

We look forward to hearing from you! :]

The post Opportunity: Front-End Designer/Developer at raywenderlich.com appeared first on Ray Wenderlich.

Video Tutorial: Beginning Video with AVFoundation Part 3: Capturing Media: Video

Playgrounds, and SceneKit Revisited – Podcast S05 E11

$
0
0
playgrounds

What’s the deal with Xcode Playgrounds? Find out in this episode!

Join Mic, Jake, and Caroline as they, somewhat belatedly, discuss Playgrounds in Xcode, before revisiting SceneKit and the changes to the framework that came with iOS 9.

[Subscribe in iTunes] [RSS Feed]

Our Sponsor

This episode was brought to you by the kind folks from Indie DevStock.

Make your plans now to come to Nashville, Tennessee and attend one of the best tech conferences being held this year!

Indie DevStock isn’t just about learning the latest Apple Frameworks or how to program in Swift. Indie DevStock is about making connections.

Our speakers will share their stories, experiences and ideas with you. Through their words, you’ll gain a better understanding of the challenges indies face and more importantly, how to overcome them. It doesn’t matter if you’re currently a successful indie developer, just starting out or trying to decide if ‘going indie’ is right for you — we’re all in this together.

In addition to the inspiration talks, you’ll also have an opportunity to attend hands-on tech talks to help level-up your skills.

During this two-day event, not only will you get to experience Southern Hospitality at its finest, but you’ll also get to hear some of the best live music around while enjoying all Nashville has to offer.

For more information, and to buy your ticket, go to indiedevstock.com. We hope to see you there.

Interested in sponsoring a podcast episode? We sell ads via Syndicate Ads, check it out!

Show Notes

Playgrounds

SceneKit

Contact Us

Where To Go From Here?

The post Playgrounds, and SceneKit Revisited – Podcast S05 E11 appeared first on Ray Wenderlich.

JavaScriptCore Tutorial for iOS: Getting Started

$
0
0

JavaScriptCore-feature

Since the introduction of Swift in 2014, its popularity has skyrocketed: according to the TIOBE index from February 2016 it’s already listed in 16th place. But only a few spaces ahead at number 9, you’ll find a language that seems quite the opposite of Swift: JavaScript. Swift puts a lot of effort on compile-time safety, while JavaScript is weakly typed and dynamic.

Swift and JavaScript may look different, but there is one important thing that binds them together: you can use them together to make a slick iOS app!

In this JavaScriptCore tutorial you’ll build an iOS companion app for a web page, reusing parts of its existing JavaScript code. In particular, you’ll learn about:

  • The components of the JavaScriptCore framework.
  • How to invoke JavaScript methods from your iOS code.
  • How to access your native code from JavaScript.

Note: You don’t need to be experienced in JavaScript to follow along. If this JavaScriptCore tutorial has piqued your interest in learning the language, Mozilla Developer Network is an excellent resource for beginners — or you can also choose to skip straight to the good parts. :]

Getting Started

Download the starter project for this tutorial and unzip it. You’ll be greeted by the following folder structure:

  • Web: Contains the HTML and CSS for the web app that you’ll be converting to iOS.
  • Native: The iOS project. This is where you’ll make all the changes in this tutorial.
  • js: Contains the JavaScript code used in the project.

The app is named Showtime; you can use it to search for movies on iTunes by price. To see it in action, open Web/index.html in your favorite browser, enter your preferred price, and hit Return:

javascriptcore tutorial

Movie night is ON…

To test Showtime on iOS, open the Xcode project residing in Native/Showtime. Build and run the app to take a look:

javascriptcore tutorial

… Or Not?

As you can see, the mobile companion isn’t quite feature-ready, but you’ll fix it shortly. The project already contains some code; feel free to browse through it to get a better idea of what’s going on. The app aims to provide a similar experience to the web page: it will display the search results in a collection view.

What is JavaScriptCore?

The JavaScriptCore framework provides access to WebKit’s JavaScript engine. Originally, the framework had a Mac-only, C API, but iOS 7 and OS X 10.9 shipped with a much nicer Objective-C wrapper. The framework enables powerful interoperability between your Swift/Objective-C and JavaScript code.

Note: React Native is an impressive demonstration of the power of JavaScriptCore. If you’re curious about building native apps with JavaScript, make sure you check out our Introducing React Native tutorial on this site.

In this section, you’ll take a closer look at the API. Under the hood, JavaScriptCore consists of a couple of key components: JSVirtualMachine, JSContext, and JSValue. Here’s how they all fit together.

JSVirtualMachine

JavaScript code is executed in a virtual machine represented by the JSVirtualMachine class. You won’t normally have to interact with this class directly, but there is one main use case for it: supporting concurrent JavaScript execution. Within a single JSVirtualMachine, it’s not possible to execute multiple threads at the same time. In order to support parallelism, you must use multiple virtual machines.

Each instance of JSVirtualMachine has its own heap and its own garbage collector, which means that you can’t pass objects between virtual machines. A virtual machine’s garbage collector wouldn’t know how to deal with a value from a different heap.

JSContext

A JSContext object represents an execution environment for JavaScript code. It corresponds to a single global object; its web development equivalent would be a window object. Unlike with virtual machines, you are free to pass objects between contexts (given that they reside in the same virtual machine).

JSValue

JSValue is the primary data type you’ll have to work with: it can represent any possible JavaScript value. An instance of JSValue is tied to the JSContext object it lives in. Any value that comes from the context object will be of JSValue type.

This diagram shows how each piece of the puzzle works together:

javascriptcore tutorial

Now that you have a better understanding about the possible types in the JavaScriptCore framework, it’s finally time to write some code.

javascriptcore tutorial

Enough theory, let’s get to work!

Invoking JavaScript Methods

Back in Xcode, expand the Data group in the project navigator and open MovieService.swift. This class will retrieve and process movie results from iTunes. Right now, it’s mostly empty; it will be your job to provide the implementation for the method stubs.

The general workflow of MovieService will look like the following:

  • loadMoviesWithLimit(_:onComplete:) will fetch the movies.
  • parseResponse(_:withLimit:) will reach out to the shared JavaScript code to process the API response.

The first step is to fetch the list of movies. If you’re familiar with JavaScript development, you’ll know that networking calls typically use XMLHttpRequest objects. This object isn’t part of the language itself, however, so you can’t use it in the context of an iOS app. Instead, you’ll have to resort to native networking code.

Within the MovieService class, find the stub for loadMoviesWithLimit(_:onComplete:) and modify it to match the code below:

func loadMoviesWithLimit(limit: Double, onComplete complete: [Movie] -> ()) {
  guard let url = NSURL(string: movieUrl) else {
    print("Invalid url format: \(movieUrl)")
    return
  }
 
  NSURLSession.sharedSession().dataTaskWithURL(url) { data, _, _ in
    guard let data = data,
        jsonString = String(data: data, encoding: NSUTF8StringEncoding) else {
      print("Error while parsing the response data.")
      return
    }
 
    let movies = self.parseResponse(jsonString, withLimit:limit)
    complete(movies)
 
  }.resume()
}

The snippet above uses the default shared NSURLSession session to fetch the movies. Before you can pass the response to the JavaScript code, you’ll need to provide an execution context for the response. First, import JavaScriptCore by adding the following line of code to the top of MovieService.swift, below the existing UIKit import:

import JavaScriptCore

Then, define the following property in MovieService:

lazy var context: JSContext? = {
  let context = JSContext()
 
  // 1
  guard let
      commonJSPath = NSBundle.mainBundle().pathForResource("common", ofType: "js") else {
    print("Unable to read resource files.")
    return nil
  }
 
  // 2
  do {
    let common = try String(contentsOfFile: commonJSPath, encoding: NSUTF8StringEncoding)
    context.evaluateScript(common)
  } catch (let error) {
    print("Error while processing script file: \(error)")
  }
 
  return context
}()

This defines context as a lazy JSContext property:

  1. First, you load the common.js file from the application bundle, which contains the JavaScript code you want to access.
  2. After loading the file, the context object will evaluate its contents by calling context.evaluateScript(), passing in the file contents for the parameter.

Now it’s time to invoke the JavaScript methods. Still in MovieService.swift, find the method stub for parseResponse(_:withLimit:), and add the following code:

func parseResponse(response: String, withLimit limit: Double) -> [Movie] {
  // 1
  guard let context = context else {
    print("JSContext not found.")
    return []
  }
 
  // 2
  let parseFunction = context.objectForKeyedSubscript("parseJson")
  let parsed = parseFunction.callWithArguments([response]).toArray()
 
  // 3
  let filterFunction = context.objectForKeyedSubscript("filterByLimit")
  let filtered = filterFunction.callWithArguments([parsed, limit]).toArray()
 
  // 4
  return []
}

Taking a look at the process, step by step:

  1. First, you make sure the context object is properly initialized. If there were any errors during the setup (e.g.: common.js was not in the bundle), there’s no point in resuming.
  2. You ask the context object to provide the parseJSON() method. As mentioned previously, the result of the query will be wrapped in a JSValue object. Next, you invoke the method using callWithArguments(_:), where you specify the arguments in an array format. Finally, you convert the JavaScript value to an array.
  3. filterByLimit() returns the list of movies that fit the given price limit.
  4. So you’ve got the list of movies, but there’s still one missing piece: filtered holds a JSValue array, and you need to map them to the native Movie type.
Note: You might find the use of objectForKeyedSubscript() a little odd here. Unfortunately, Swift only has access to these raw subscripting methods rather than having them translated into a proper subscript method. Objective-C can use subscripting syntax with square brackets, however.

Exposing Native Code

One way to run native code in the JavaScript runtime is to define blocks; they’ll be bridged automatically to JavaScript methods. There is, however, one tiny issue: this approach only works with Objective-C blocks, not Swift closures. In order to export a closure, you’ll have to perform two tasks:

  • Annotate the closure with the @convention(block) attribute to bridge it to an Objective-C block.
  • Before you can map the block to a JavaScript method call, you’ll need to cast it to an AnyObject.

Switch over to Movie.swift and add the following method to the class:

static let movieBuilder: @convention(block) [[String : String]] -> [Movie] = { object in
  return object.map { dict in
 
    guard let
        title = dict["title"],
        price = dict["price"],
        imageUrl = dict["imageUrl"] else {
      print("unable to parse Movie objects.")
      fatalError()
    }
 
    return Movie(title: title, price: price, imageUrl: imageUrl)
  }
}

This closure takes an array of JavaScript objects (represented as dictionaries) and uses them to construct Movie instances.

Switch back to MovieService.swift. In parseResponse(_:withLimit:), replace the return statement with the following code:

// 1
let builderBlock = unsafeBitCast(Movie.movieBuilder, AnyObject.self)
 
// 2
context.setObject(builderBlock, forKeyedSubscript: "movieBuilder")
let builder = context.evaluateScript("movieBuilder")
 
// 3
guard let unwrappedFiltered = filtered,
  let movies = builder.callWithArguments([unwrappedFiltered]).toArray() as? [Movie] else {
  print("Error while processing movies.")
  return []
}
 
return movies
  1. You use Swift’s unsafeBitCast(_:_:) function to cast the block to AnyObject.
  2. Calling setObject(_:forKeyedSubscript:) on the context lets you load the block into the JavaScript runtime. You then use evaluateScript() to get a reference to your block in JavaScript.
  3. The final step is to call your block from JavaScript using callWithArguments(_:), passing in the array of JSValue objects as the argument. The return value can be cast to an array of Movie objects.

It’s finally time to see your code in action! Build and run. Enter a price in the search field and you should see some results pop up:

javascriptcore tutorial

That’s more like it!

With only a few lines of code, you have a native app up and running that uses JavaScript to parse and filter results! :]

Using The JSExport Protocol

The other way to use your custom objects in JavaScript is the JSExport protocol. You have to create a protocol that conforms to JSExport and declare the properties and methods, that you want to expose to JavaScript.

For each native class you export, JavaScriptCore will create a prototype within the appropriate JSContext instance. The framework does this on an opt-in basis: by default, no methods or properties of your classes expose themselves to JavaScript. Instead, you must choose what to export. The rules of JSExport are as follows:

  • For exported instance methods, JavaScriptCore creates a corresponding JavaScript function as a property of the prototype object.
  • Properties of your class will be exported as accessor properties on the prototype.
  • For class methods, the framework will create a JavaScript function on the constructor object.

To see how the process works in practice, switch to Movie.swift and define the following new protocol above the existing class declaration:

import JavaScriptCore
 
@objc protocol MovieJSExports: JSExport {
  var title: String { get set }
  var price: String { get set }
  var imageUrl: String { get set }
 
  static func movieWithTitle(title: String, price: String, imageUrl: String) -> Movie
}

Here, you specify all the properties you want to export and define a class method to construct Movie objects in JavaScript. The latter is necessary since JavaScriptCore doesn’t bridge initializers.

It’s time to modify Movie to conform to JSExport. Replace the entire class with the following:

class Movie: NSObject, MovieJSExports {
 
  dynamic var title: String
  dynamic var price: String
  dynamic var imageUrl: String
 
  init(title: String, price: String, imageUrl: String) {
    self.title = title
    self.price = price
    self.imageUrl = imageUrl
  }
 
  class func movieWithTitle(title: String, price: String, imageUrl: String) -> Movie {
    return Movie(title: title, price: price, imageUrl: imageUrl)
  }
}

The class method will simply invoke the appropriate initializer method.

Now your class is ready to be used in JavaScript. To see how you can translate the current implementation, open additions.js from the Resources group. It already contains the following code:

var mapToNative = function(movies) {
  return movies.map(function (movie) {
    return Movie.movieWithTitlePriceImageUrl(movie.title, movie.price, movie.imageUrl);
  });
};

The above method takes each element from the input array, and uses it to build a Movie instance. The only thing worth pointing out is how the method signature changes: since JavaScript doesn’t have named parameters, it appends the extra parameters to the method name using camel case.

Open MovieService.swift and replace the closure of the lazy context property with the following:

lazy var context: JSContext? = {
 
  let context = JSContext()
 
  guard let
      commonJSPath = NSBundle.mainBundle().pathForResource("common", ofType: "js"),
      additionsJSPath = NSBundle.mainBundle().pathForResource("additions", ofType: "js") else {
    print("Unable to read resource files.")
    return nil
  }
 
  do {
    let common = try String(contentsOfFile: commonJSPath, encoding: NSUTF8StringEncoding)
    let additions = try String(contentsOfFile: additionsJSPath, encoding: NSUTF8StringEncoding)
 
    context.setObject(Movie.self, forKeyedSubscript: "Movie")
    context.evaluateScript(common)
    context.evaluateScript(additions)
  } catch (let error) {
    print("Error while processing script file: \(error)")
  }
 
  return context
}()

No big changes here. You load the contents of additions.js into your context. By using setObject(_:forKeyedSubscript:) on JSContext, you also make the Movie prototype available within the context.

There is only one thing left to do: in MovieService.swift, replace the current implementation of parseResponse(_:withLimit:) with the following code:

func parseResponse(response: String, withLimit limit: Double) -> [Movie] {
  guard let context = context else {
    print("JSContext not found.")
    return []
  }
 
  let parseFunction = context.objectForKeyedSubscript("parseJson")
  let parsed = parseFunction.callWithArguments([response]).toArray()
 
  let filterFunction = context.objectForKeyedSubscript("filterByLimit")
  let filtered = filterFunction.callWithArguments([parsed, limit]).toArray()
 
  let mapFunction = context.objectForKeyedSubscript("mapToNative")
  guard let unwrappedFiltered = filtered,
    movies = mapFunction.callWithArguments([unwrappedFiltered]).toArray() as? [Movie] else {
    return []
  }
 
  return movies
}

Instead of the builder closure, the code now uses mapToNative() from the JavaScript runtime to create the Movie array. If you build and run now, you should see that the app still works as it should:

javascriptcore tutorial

Congratulations! Not only have you created an awesome app for browsing movies, you have done so by reusing existing code — written in a completely different language!

javascriptcore tutorial

Now that’s what I call seamless user experience!

Where to Go From Here?

You can download the completed project for this tutorial here.

If you wish to learn more about JavaScriptCore, check out Session 615 from WWDC 2013.

I hope you enjoyed this JavaScriptCore tutorial. If you have any questions or comments, please join the forum discussion below!

The post JavaScriptCore Tutorial for iOS: Getting Started appeared first on Ray Wenderlich.

iOS Animations by Tutorials Updated for Xcode 7.3

$
0
0

Another wild update appears! Today, we’re happy to announce that Marin Todorov has updated his popular book iOS Animations by Tutorials for Xcode 7.3.

Xcode 7.3 has a few small changes to Swift – mostly minor syntax things – but we wanted to make sure that all the instructions work without any issues.

In addition to updating the book for Xcode 7.3, we’ve fixed some errata pointed out by readers – thanks all!

This is a free update for existing PDF customers. Here’s how you can get your copy:

  • If you’re an iOS Animations by Tutorials PDF customer, you can download the update for free on your My Loot page (version 2.1).
  • If you haven’t picked up a copy of iOS Animations by Tutorials yet, grab your copy now.

We’re hard at work updating the rest of our Swift books for Xcode 7.3 – stay tuned.

Marin and I hope you enjoy this update!

The post iOS Animations by Tutorials Updated for Xcode 7.3 appeared first on Ray Wenderlich.


Video Tutorial: Beginning Video with AVFoundation Part 4: Merging Media

Video Tutorial: Beginning Video with AVFoundation Part 5: Overlays And Animation

Video Tutorial: Beginning Video with AVFoundation Part 6: Conclusion

Video Tutorial: Intermediate iOS Animations: Series Introduction

Video Tutorial: Intermediate iOS Animations Part 1: Basic Layer Animations

Viewing all 4370 articles
Browse latest View live


<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>