Today I Learned

A Hashrocket project

17 posts about #mobile

"experience uses an unsupported version of Expo"

error

If this happens when developing a React Native app with Expo and trying to test it in the iOS Simulator, it means the version of Expo on the iOS Simulator is out of date.

To fix that try the following:

  1. Quit the Expo app on the simulator
  2. Uninstall the Expo app on the simulator
  3. Lunch the app again in the simulator from the Expo XDE

This will cause the Expo app on the simulator to reinstall with the latest version.

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 ^⌘+\ 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

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.

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