CARROT iPhone App Video Marketing Done Right

The maker of the CARROT TODO app does user experience and marketing right in so many ways. To keep this post short, let’s just focus on one bit of video marketing titled CARROT Launch Trailer. The video is fun enough that I even saved it to watch again!

The video starts with some exciting music and a strong message similar to this: “the todo list with a personality.” It’s a good clear message which shows how it distinguishes itself and what the app does.

With the blue circle pulsing, the video moves on to the playful and humorous statements of “Let’s play a game. We’ll call it ‘Don’t Suck at Life.'” It shows some functionality of the app and then moves on to the rules of the game. Get stuff done or CARROT will get mad!

As someone who has used the app for years, I guarantee she (CARROT) will get mad. CARROT is often referred to as the user’s “new mistress.” Here’s the video:

One thing the video doesn’t show you is the funny and sometimes creepy (in a humorous way) push notifications that the app receives. I highly encourage you to turn the notifications on. Although the humor is often dark, it is fantastically funny. Check out the app for yourself!

Communities in Nonsocial Mobile Apps

Nonsocial apps with a social community inside of them. It seems to make sense since you already have a captive audience. However, does it always make sense? Let’s first dive into mobile apps that come with communities.

Besides the obvious social mobile apps, there are multiple apps with communities aka groups inside of them. These apps are not primarily social apps, but they attempt to support a community. Since humans are social beings, it can be a nice feature which can make the app more appealing and thus used more often.

Some Community Supporting Apps:

  • Argus – It’s a highly social activity tracker app that has a groups section. There’s more on Argus further down in this article. iPhone and Android apps exist.
  • Coursera has a “Discussions” area in the iPhone app. There’s an Android app too. Discussions are not available until a course starts. So, one cannot peek inside right away and explore it.
  • Lose It! – Weight Loss Program and Calorie Counter – Has a “Social” section with many groups in it. The group activity in it is kind of strong. Strongest are the groups which are promoted as “Featured Groups”. iPhone app and Android app exist.
  • Not quite a discussions area, but Udemy has a Q & A section which has questions directed at the instructor in a particular instructor. This provides longterm value with credibility in the information since the answers come from the instructor. However, there is no sense of community. They offer an iPhone app and an Android app.
  • It’s worth noting that I have seen apps drop support for groups. That can sometimes be the smartest move.

More on Argus

The target audience of the app focuses on people who like to be social while tracking health, fitness, meditation, sleep and other trackable activities. Even though the semi-new groups section is pretty dead, there’s a novel tie in from a group into the tracked activities of group members which I find interesting.

It’s interesting in how it provides a kind of newsfeed style of tracked activities. You can tap on a button in the group and see a combined newsfeed from the group members. Compared to the messages button, this has much more activity. Unfortunately, most of the activities have nothing to do with the particular group you are in since they are not filtered. At a glance, it’s also a slightly confusing user experience.

Also, the downside of the groups section is that it’s slow to load and has an annoying bug which makes the iPhone app crash when you click on a link. As a side note, I happen to run a meditation group in Argus that has 25 members.

All that said, it’s worth a look. The groups has potential if a few things are tweaked, promoted, and fixed.

Externally Support the Community?

Should one just tie into an existing social app such as Facebook to support a community? It’s a fair question. Facebook has a groups feature which can be successful. The most successful Facebook group I have been a part of is the Octalysis Explorers. It has over 2000 members. Like any group, a lot of effort goes into keeping the community engaged. Fortunately for the Octalysis Explorers, Yu-kai Chou is a master at the art and science of engagement. He has a handful of awesome and loyal people who support the effort.

The people supporting the Octalysis Explorers group are continuously driving people to the Facebook group through multiple channels. Even in its own “Join the Movement” section, the group is highlighted in Yu-kai Chou’s great book titled Actionable Gamification – Beyond Points, Badges, and Leaderboards. There are also multiple administrators for the group. Also, there is always at least one person actively interacting with every post. A successful community relies on that kind of wonderful support from its administrators and its members.

Summary

Even though the implementation and user experience is pretty rough, it seems like the app with the most group activity without overt support is “Lose It!” However, that’s not saying much. The app with the most potential from a technology point of view may be Argus. However, Argus is already a highly social app so its group feature doesn’t add much.

If one can dedicate people to supporting a community on Facebook, that might be your best bet. If you go that route, you will need to continuously drive people to the group through your existing email marketing, verbal announcements in events or podcasts, and every other chance you get. Communities require care and feeding.

No matter how you support a community experience, it can provide an advantage over other solutions who don’t provide such. If one cannot dedicate the resources to the community experience or if the community experience doesn’t ever pay off, my advice is to drop it and refocus on other things.

iOS Color War! Appearance Proxy vs UIButton Title Text Color

Now here’s a weird issue that appeared in iOS 10, I found myself saying one day. I was seeing an iOS button’s title change color as a I navigated from one scene to the next. It got worse. When I navigated back, the button’s title color stayed the wrong color. It was the same color as all the labels in the iOS app. What’s going on?

We dug in deeper and discovered something. There was a nasty appearance proxy color issue where the appearance proxy would change the color of the UIButton‘s title text color even though the code was explicitly setting the color. In fact, the appearance proxy would set it to be the same color as it has configured for all UILabel objects. The configuration code for labels was like this:

UILabel.appearance().textColor = labelTextColor()

Since a UIButton contains a UILabel, that might make sense. How does one fix this situation?

The answer to fixing it was discovered after thinking about what was read in this Stack Overflow post titled Appearance Proxy overridden when resetting text:

iOS applies appearance changes when a view enters a window, it doesn’t change the appearance of a view that’s already in a window.

It turns out the code to explicitly set the color on the UIButton was getting called before the view appeared on the screen aka viewWillAppear. Once the view appeared on the screen, the appearance proxy would set the button’s label’s text color aka button title color.

As a side note, this only seemed to happen when using setAttributedTitle on the button as opposed to calling setTitleColor and setTitle separately. Unfortunately, we wanted different parts of the text to be different sizes. So, using setAttributedTitle still seemed like the thing we should do.

Given all that knowledge, we called setNeedsLayout on the UIButton in viewWillAppear and viewWillDisappear That fixed everything up! The button no longer appeared to change color when switching between screens. Hurrah!

 

 

Adding Swift Initializers Through Extensions

While watching the Stack Views with Enums by objc.io, I learned an interesting little tidbit. You can add a convenience constructor aka convenience initializer by extending a class. The benefit of doing such is that you don’t have to subclass the class. In hindsight, the availability of that feature seems obvious. The Swift reference even has a section called “Initializers”. However, this ability may be news to others as well.

Similar to what they show at 7:45 in the video, one can write the following:

Next, you can call this new init like any other initializer:

I highly recommend you watch the entire Stack Views with Enums video. Enjoy!

RxSwift and Squishing the Pyramid of Doom

Say, you just learned RxSwift and all about subscribeNext. You have a series of Harry Potter related service calls to make and they affect each other. Let’s also say they all return the same type of Observable<Person>. So, you start to call these services one after another using subscribeNext.

The indention of calls is known as the Pyramid of Doom. This is a case of not using all of the power that RxSwift offers. If we inject flatMapLatest into the mix instead of all subscribeNext calls, we get the following:

Not only is the flatMapLatest approach easier to read, but one can see easily where the addDisposableTo(disposeBag) should be added at the end to manage the memory.

This concept is also covered in the RxSwift Tips document. Enjoy all that RxSwift has to offer!

Swizzle Swift Class Methods

While writing some test Swift code, I ran into a situation where I wanted the implementation of a class method swapped out with some fake code. Basically, I wanted to swap out SomeClass‘s saveSomeThings class method with a fake one.

Inspired by NSHipster’s Swift & the Objective-C Runtime article, I came up with some concise code that does what I want. Focusing on only what shows the concept, we have the following example SomeClass:

The saveSomeThings method implementation is what we want to swap out with some fake code for testing purposes. How, you might ask? First, ensure the method has the dynamic keyword as discussed in this Stack Overflow post. Next, we grab a handle to the class method like so:

Now we need something to swap it with. What if we had a method inside a SomeTestClass class like the following just for testing purposes?:

We can grab a handle to the method like so:

The actual call to swap the implementation between the saveSomeThings and forTesting_SaveSomeThings is done using method_exchangeImplementations like this:

The SomeTestClass prefixes the originalMethod and swizzledMethod because I am storing them as static members of the SomeTestClass.

Those are all the magical pieces of this puzzle! Besides being on github, here is a complete Swift playground example to see it all in context:

At CARFAX, I have been fortunate enough to work on such interesting challenges like the one above in Swift, Objective-C and Java based languages. Since CARFAX is a growing company with opportunities that open up from time to time, you might want to checkout the CARFAX Career link.

Regardless, I hope you found the above information interesting and useful. Enjoy!

Hit Your Own Server On Your Mac With Your iPhone

To truly evaluate the user experience, there is no substitute for having the app on your iPhone and in your hands. Yet, it’s rare that a person can make an iPhone app that doesn’t depend on a server of some kind.

If you don’t have a server deployed somewhere yet, what can one do? Well, you can hardcode values in the app. However, that can be more trouble than it’s worth. Also, you’re not testing the whole app end to end. So, what one can do is create a mock server that returns hardcoded values using Node.js or some other framework. Great!

Just one thing, the mock server your iPhone depends on is not ready to be deployed. It’s on your machine only. What to do?

You can run the server locally on your mac and have your iPhone hit it over wireless. Sounds easy enough. Right?

After figuring out your IP address of your machine for the phone to hit, changing the iPhone app to hit whatever URL it needs, and probably temporarily turning off App Transport Security so you can hit it with an http as opposed to an https URL, you may find that your iPhone app still cannot hit the machine your mock server is running on.

Stack Overflow to the rescue! After digging into the google world, I found the key sentence I was looking for in a Stack Overflow post:

I turned off my WI-FI on my Mac and then turned it on again, which solved the problem.

Although I’m not positive, it seems like I had to flip the wireless from on to off and back to on more than once. To test that the phone can reach the machine, I used safari on the iPhone to check that I can hit anything at all on that machine.

Once I figured all this out, I was so happy that I decided to write this for others to use. If it wasn’t for Stack Overflow and our community of knowledge sharers, where would we be today?

Fire! Wife, Apple Watch, and Meditation are Heroes

Ring! Ring! There goes my Apple Watch. The iPhone is in another room and my hands are dirty-dishes-gross. “That’s weird and annoying”, I think reflexively to myself. My wife is calling but she just left.

With the final ring sounding, I quickly do the right thing regardless of my thoughts. I rinse off a pinky finger and answer the call on my Apple Watch with it. I hear her Apple Watch’ed voice say loudly “Get a trashcan full of water and …. <something about a bin>.” What’d she say? After quickly rinsing off my hands, I grab a trashcan, yank the trash out, and mutter about needing caffeine while filling it up with water.

Next, I’m outside. Hmm! Lots of smoke is coming from the trash bin area. Uh oh… A quick emotion check reveals slight concern and the thought that I better get out there soon and see what’s up. I’m slightly surprised about how matter-of-fact my mind feels.

Keeping a clear mind is a credit to the meditation training I’ve done over my life and most recently received from my two favorite meditation apps. At some point, I run toward the smoke and check out the situation. Oh! This fire could spread quickly!

My wife had emptied the wastebasket full of water and tells me to get the fire extinguisher. “Good thinking”, I reflect while running back. I dug it out from the back of the closet, run it out to her, and she puts the fire out while I am running back for more water. Success!

A photo of the inside trash bin area that caught fire.

Where the Fire Started Inside the Bin Area

Just then, the maintenance person shows up that my wife had called. Good. He can do any needed follow up with whomever.

Fire scorched trash bin area fence

Fire Scorched Fence Outside of the Bin Area

Let’s recap. The trash bin area is completely surrounded by a dry timber fence. If I hadn’t been wearing my Apple Watch, had my meditation training, and/or my hero wife hadn’t seen the fire, it might have gone completely up in flames. As my wise wife said, who knows if a floating fire ember would have started another fire on a nearby home?

As far as who the hero is that kept people and property safe, the credit goes to my wife.

This is also a moment of gratefulness. I am grateful for my wife’s levelheadedness. I’m also thankful to Apple for their innovation and specifically my Apple Watch. Finally, I feel lucky to have experienced first hand the fruit of all of my meditation training which kept the whole event in perspective and kept me from overreacting.

May you also be as blessed as I in such times!

An Apple iOS Distribution Certificate Dying

In an iPhone developer’s life, there is sometimes mystery around some of the Apple related administrative work that is needed. Certificates expire, Provisioning Profiles have to get regenerated, and test devices come and go.

One interesting question was brought to my attention recently:

If the iOS Distribution Certificate expires, will the iPhone apps in the App Store still work?

Yes. The iPhone apps will still work. From the Apple documentation:

If your Apple Developer Program membership is valid, your existing apps on the App Store will not be affected.

So, it’s well understood that Distribution Certificates expire. What about if someone adds a test device, will that invalidate the iOS Distribution Certificate? The short answer is “no.” Devices are added to Provisioning Profiles as opposed to certificates.

For detailed information, look at the Registering Devices Using Member Center section of the Maintaining Identifiers, Devices, and Profiles Apple documentation and Exporting Your App for Testing (iOS, tvOS, watchOS).

I hope that clears up some of the mystery around an iOS Distribution Certificate dying and point to some helpful Apple documentation.

Mobile Architecture Going Right and Wrong

Most decisions have positive and negative outcomes. When it comes to choosing what technologies to use for a software development team, it often comes down to two different “right” choices. They are right for different reasons and optimize for different things. A smart move is to optimize those things which serve peoples’ best interests (and the interests of their company) even at the expense of other concerns.

Imagine this situation brought to my attention: A team member observes upcoming code duplication between two systems down the road between an iOS and Android product. Among other things, they point out a technological solution that involves adding an additional language that would let them share code between iOS and Android.

From that single point of view, a solution like that sounds OK. Yet, what are the consequences? As you would expect there are pros and cons.

Cons

Let’s start with the cons. Adding new things to a technology stack of this kind may cause the following things:

  • Overstressed team by spreading the team too thin
  • Integration overhead
  • Expertise silos
  • Resistance to refactoring
  • Unforeseen issues due to an increase in overall architecture complexity
  • Increased time and pain around troubleshooting
  • Longer time to get new team members up to speed
  • Enjoyment of work going down for some and potentially all

Overstressed Team by Spreading the Team Too Thin

This deserves diving into a little. Imagine the team has recently adopted Android. Let’s say they recently also adopted a new programming paradigm such as Functional Reactive Programming. Now add a couple new team members. What’s the potential result? A magnification of the concerns listed above.

Pros

Good things that come can come from adding more to the technology stack:

  • Reduction of duplicate code
  • A new thing to learn (which can be good or bad depending on how much one has to learn currently already)

Summary

Which idea is right? Both are right in some ways and painful in other ways. As someone once said:

The hardest decisions in life are not between good and bad or right and wrong, but between two goods or two rights.

Of course decisions need to be made in part against the “-ilities” of architecture. In this case, Architecture complexity increases as one adds technologies. Lessons of the past have taught me that with the adoption of any addition to a technology stack, there can be costs to pay from an architecture and team point of view.

However, consider the people aspect of this too. The quality of a person’s life and their happiness affects productivity. So, measure decisions against those things that will make you excited about working and contributing as well. I highly suggest keeping those in mind. Otherwise, nothing will get done if you are fighting against the human nature of people seeking happiness.