Today I Learned

A Hashrocket project

16 posts about #mobile

Log React Native HTTP calls on Chrome dev tools

There is a workaround to log all React Native HTTP Api calls on the Chrome dev tools. Add the following code to the index files:

if (__DEV__) {
  GLOBAL.XMLHttpRequest = GLOBAL.originalXMLHttpRequest || GLOBAL.XMLHttpRequest;
}

Make sure it only works for the dev enviroment checking the __DEV__ variable.

Credits: https://github.com/facebook/react-native/issues/934

Xcode Behaviors For Succeeding and Failing Tests

In the Xcode preferences, there's a section for Behaviors where you can specify how Xcode should handle certain situations. What I learned about today was that you can have Xcode tell you when your tests pass or fail:

WiFi Menu With More Info

Here I have told Xcode to use the Good News voice to announce when my tests pass. I also picked a voice for passing tests: Bad News seemed appropriate.

Comes in handy when you have switched to another application and you happened to miss the notification in the corner of the screen. Plus, it sounds cool.

h/t Leo Picado

React Native, Heroku, and SSL @heroku @reactnative

I recently switched over a Phoenix app from the paid Heroku SSL add on to the new SSL beta. Everything seemed to work great, until I noticed all Network Requests from the Android side of my React Native mobile app were failing, however iOS, curl, postman, etc were all fine.

I banged my head around for a while and went back to check my SSL set up. During the beta setup, Heroku tells you your certificate is usually a .pem or a .cert. I have both. Without much though, I uploaded the .cert. I went back and uploaded the .pem, and everything works fine.

I don't know why the .pem worked and the .cert didn't, but I'll do some digging and post a follow up to this when I know why.

Emoji Variables in Swift #🚀

Swift allows developers to specify variable names in unicode, which is very helpful if you and the rest of the developers to ever touch your code speak a non-english language which uses unicode characters:

let 你好 = "你好世界"

It is also useful if you want to specify special constants such as

let π = 3.14159

most importantly though, it allows developers to use emojis for variable names:

let 🐶🐮 = "dogcow"
let 🚀 = "Hashrocket"
NSLog(🚀)

but don't take my word for it, read the official documentation which contains some of the above examples.

Note: the pound sign above (#) is unicode, that is why it is allowed as part of a variable name, whereas normal # sign is not.

P.S. to access emojis and other unicode symbols directly in the current edit field press ^⌘+<space> on Mac.

Xcode's Fix All in Scope

Xcode scans your code for compiler errors as you type. These errors show up as a red dot in the gutter that can be clicked to reveal the error message. Xcode may also provide a Fix-It that you can accept.

When your file contains multiple errors and you want to accept all the Fix-Its, do this: Editor > Fix All in Scope. Better yet, the keyboard shortcut: ctrl + opt + cmd + f.

This feature can be a little unpredictable because while Xcode does a great job of identifying compiler errors, it's not always great at suggesting fixes. But, when you're confident that you know what the fix is going to be, it can be very handy to let Xcode help you out.

One place I find myself using this feature is when I change my mind about a constant:

let foo = 1
// some code
foo += 1

I thought foo was going to be a constant, but then further down the file I realize my mistake - Xcode will error and I'm usually sure that hitting ctrl + opt + cmd + f will switch the let to var for me.

InteractionManager smooth scene transitions

If you have an expensive scene to render with a lot going on in the constructor, or componentDidMount, etc, your navigator animation will likely by choppy because the Javascript thread is blocked executing that code. Use the InteractionManager API to execute that code after the transition ( and render a placeholder if necessary).

https://facebook.github.io/react-native/docs/performance.html#slow-navigator-transitions

Check platform on React Native

import React, { Platform } from 'react-native';

if(Platform.OS === 'android'){
//...
}

Private Set on Swift Property

Swift supports public get but private set on properties:

// foo.swift
public class Foo {
  public private(set) var bar: String = "hahaha"
}

// baz.swift
let foo = Foo()
foo.bar = "muhahaha" // "Cannot assign to property: 'bar' setter is inaccessible"

So, Foo is a public class with a public String property called bar. This property can be read, but cannot be set from the outside.

Choosing Which XCTestCases to Run

Xcode's Test Navigator (cmd + 5), is an outline of your tests. As you mouse over the elements in this outline, you'll see a run button off to the right. Using this button you can pick an individual case, file or target to run.

While editing a test file, you can use the buttons in the gutter to run either an individual case or the entire file.

But if you want more control, you can shift or command click on test cases in the Test Navigator to highlight them and then command click to bring up even more options:

Test Navigator Selection Menu

We can choose to run both highlighted cases or even disable them. Nice.

But, what about keyboard shortcuts??

You can run the entire suite with cmd + u, but did you know about these others:

  • ctrl + opt + cmd + u - Run the test file currently open.
  • ctrl + opt + cmd + g - Rerun the test(s) you just ran.

That last shortcut can be really helpful. Once you've run a particular test case in isolation, you can use that shortcut to run it over and over as you work.

The Order of Args With Default Values in Swift

Like many languages, the arguments to functions in Swift can have default values. As the documentation notes, it's a best practice to place these arguments at the end of a function's parameter list:

func foo(bar: String, baz: String = "omg", bah: String = "haha") {}
foo("<3 <3 <3") // `baz` and `bah` take on the values of "omg" and "haha" respectively

What I learned today is that when calling a function like this, the default arguments can be in any order:

foo("<3 <3 <3", bah: "first!", baz: ":(")

Weird!

Joe Groff has a proposal on the mailing list to change this behavior.

Credit where credit's due: I found out about this while reading the excellent Swift Weekly Brief.

Hot Reloading Error on React Native 0.22

If you upgrade your React Native app to 0.22 and you start getting the following error <Text> can't have any children except <Text>, <Image> or raw strings even if your <Text> components are all correct, just disable the new Hot Reloading feature that was introduced in this version and the errors will stop:

Shake the device => Disable Hot Reloading

Linear Gradient in React Native

So far, there is no official implementation for linear gradients in React Native but there is a really cool open source component that implements that for both platforms: Android and iOS.

Check it out react-native-linear-gradient

<LinearGradient
  colors={['#F00', 'transparent']}
/>

Clip subviews content out of bounds

In iOS when you want to clip part of the subviews that are out of the bounds you just set clipsToBounds = YES; in the parent view.

In Android you set setClipChildren(true); in the ViewGroup.

React Native tries to mimic CSS with their own implementation of it, so you can set the property overflow: 'hidden' in the view's style.

Easy as pie!

limit android text entry length

android:maxLength=4 such a simple solution to a simple problem

Static singletons in swift

Today i learned how to make a static singleton class in swift

class SharedManager{
static let sharedInstance = ShareManager()
///properties and methods below 
}

Cocoapod integration with swift

Today I had to integrate a project that I am working on for open source distribution with Cocoapods. I have used this repository manager before but not in swift.

  1. You have to uncomment or type in !use_frameworks in you Podfile

  2. You then type in the appropriate space which pods you want to install

  3. Then do pod install

  4. Create a header file for bridging the objective c code

  5. Then in your build settings , swift code generation area type in the name of the header file you just created

# Uncomment this line to define a global platform for your project
platform :ios, '9.0'
# Uncomment this line if you're using Swift
use_frameworks!

target 'TippleiOS' do
    pod 'Stripe', '~> 4.0'
    pod 'AFNetworking', '~> 2.5.4'
end

target 'TippleiOSTests' do

end

target 'TippleiOSUITests' do

end