Preventing Spam iCloud Calendar Invites

IMG_1224.PNG

I woke up this morning seeing two notifications of calendar appointments I just couldn’t miss. [sarcasm]

IMG_1225.PNG

Annoying, right? Here’s the best part. No matter what I do – Accept, Maybe, Decline – the sender of the spam appointment receives the notification of my action. There’s no way to just simply delete the damn invitation from your calendar without sending the reply! Well I guess that means 章兴言 & 历昭 are going to get a sad decline from me.

How do I prevent this from happening in the future? How the hell did it happen? Turns out it’s Apple again – thinking they know better for how you want to use e-mail and calendars. Thankfully there is an option to prevent the forced invites.

The Answer Lies in iCloud.com

These calendar invites aren’t coming from some magic hacked portal in your phone. The invites are coming as e-mails into your iCloud.com e-mail account and then being automatically converted into in-app push notifications to both iOS and macOS. Once that’s done the original e-mail is deleted. Gone. Poof. Magical, yet stabby.

Let’s turn off this magical conversion so we have the ability to spam the incoming e-mails and never have them hit your calendar.

  1. First, open iCloud.com up in a web browser.
  2. Log into using the account you use on your phone (where your calendars are stored).
  3. Click on Calendar.
  4. Click on the settings gear 2016-11-25_08-50-07.png in the lower left of the screen.
  5. Click on Preferences.
  6. Click the Advanced tab.
  7. Under Invitations set the option for Receive event notifications as to the second option, as an Email to rather than an in-app notification.
    2016-11-25_08-39-11

Going forward then all of the invites you receive to your iCloud e-mail account will be received as e-mails.

Damn you, spammers!

~A

[update]

Deleting Spam Invites Without Sending Notifications

Taken from the Apple Discussion Forums, here’s a workaround to delete invites without sending the response to the spammer using macOS:

  1. Create a new iCloud calendar (not “On My Mac”).
  2. Move the spam event to the new iCloud calendar.
  3. Delete the new iCloud calendar.
  4. Calendar will now prompt you with “Delete and Don’t Notify” and “Delete and Notify”.
  5. Select “Delete and Don’t Notify”.

Original post: https://discussions.apple.com/thread/3705591?tstart=0

Swizzling in AFNetworking somehow breaks iOS’ NSDoubleLocalizedStrings

Tools to Help Test Localization

Apple provides some pretty slick tools to help with localization testing in your apps. I had completely forgotten about two launch parameters that make it possible to find those pesky layout problems early:

  • NSDoubleLocalizedStrings – Any calls made to NSLocalizedString will double the strings to simulate languages with longer words, like German.
  • NSShowNonLocalizedStrings – Replaces any text from NSLocalizedString that doesn’t have an entry in a strings file.
  • AppleTextDirection – Simulates a Left to Right language.

In Xcode 7 there is an easier way to provide these options. Edit the scheme for your app, click on the Run section, then the Options tab. You’ll see Application Language has two options – Double Length Pseudolanguage and Right to Left Pseudolanguage. There is also a check box for Show non-localized strings. These three options are equivalent to the launch arguments above.

There’s more about testing the localization of your app in Apple’s Internationalization and Localization Guide.

Why Isn’t it Working!?!!?!?

This past week I spent a good chunk of a day trying to figure out why Xcode’s options for localization testing weren’t working. I tried the three items above and also tried sending them as launch parameters like -NSDoubleLocalizedStrings YES with no avail. I checked the contents of NSUserDefaults upon launch and verified that the launch parameters made it into the defaults as expected. Why wasn’t it working??

I then tried to set the user default myself in the app delegate. At first it didn’t work. Then when I restarted the app suddenly the strings were being duplicated. I was confused to say the least.

I dug deeper and discovered that two test apps I had written for RayWenderlich.com worked just fine with the Xcode options and launch arguments approach. My project that didn’t work had CocoaPods – so I thought maybe that was the problem. It wasn’t because the second test app had CocoaPods. I then decided it had to be one of the pods causing the problem.

I went back to the original app and started removing pods from the Podfile. Turns out the pod causing the issue was AFNetworking! I then added AFNetworking to my demo project that was working and it stopped working after that. Then I dug through each subspec in AFNetworking and found that the NSURLSession spec was the culprit.

Turns out there is a single line of code in a method swizzle in AFNetworking’s AFURLSessionManager’s private class _AFURLSessionTaskSwizzling that’s causing the issue.

I opened an issue on GitHub to help track this. It does seem to be an issue even in AFNetworking 3.

How do I Fix it Right Now?

Simply comment out the line of code referenced above in your checked out copy of AFNetworking. If you’re using CocoaPods you’ll get a warning message saying you have to unlock editing of that file. Go ahead and do that but don’t forget to undo the change after.

CouchDB Logo

Rediscovering CouchDB

I’m currently writing the materials for my presentation on Core Data & Synchronization of data for RWDevCon 2016. One of the requirements for the demonstration app is a web service that provides a REST API to sync with. One of the requirements of the talk is that I cannot rely upon an Internet connection. Every person going through the tutorial needs to be able to bring up a local web service to following along with while coding the iOS app on their machine.

I started looking into a lot of wrappers for web apps, including Electron. The issue is I have a limited amount of time to come up with a solution that is super simple for conference attendees to install and bring up. I haven’t developed a web app for a couple years – and I feel so rusty. I do not have a trusty fallback programming language outside of Swift and Objective-C. I really feel stupid sometimes not knowing Ruby, Python or any other language as well as I feel like I should.

I ended up digging for two full nights and got super frustrated. There is just so much to learn about a new language, their web frameworks, persistence layers, and on and on. I still need to find time to write the iOS demo application – so I ended up time-boxing the search. Suddenly I had a moment of clarity. I remembered CouchDB – a document store/database that has a JSON REST API built in!

I first learned about the Apache CouchDB project from a presentation given by Jens Alfke at SecondConf in Chicago, 2011.

Attendees will get a single ZIP file with the CouchDB binary. I’ll then have a small script they can execute to seed the data into the store. Super super simple. So far I’m in love with CouchDB again. 🙂

iOS 9 Good Morning & Afternoon Weirdness

I had a user write in to get some help clarifying a behavior with the Migraine Diary app I wrote on iOS 9.

The user explained that every morning she turns on her phone and Migraine Diary shows on the screen and when she opens it, it tells her Good Morning. The little icon sounded like Continuation or App Suggestions neither of which Migraine Diary supports. I asked for a screenshot and got this:

IMG_1715

Sure enough, there’s the app at the bottom of the screen. I’ve asked them for a screenshot of the Good Morning screen but still haven’t gotten an answer back. I did some digging and found this thread on Reddit that shows what I think the user is seeing:

q5moHqD

Has anyone else seen this? Anybody know what the heck it is? Time to file a Radar?

 

Recording Your iOS Device with QuickTime Player

The Task

You need to record your iPhone or iPad’s screen to show someone a bug or demo a feature to your customers. In the past the only method available was to use a program like Reflector to emulate an AirPlay/Apple TV and then record on your machine. This works fairly decently although the quality over WiFi isn’t very good leaving you with a less-than-crisp recording. Reflector also isn’t free which makes it difficult for users in the wild to record bugs.

Enter iOS 8 & Yosemite

Apple introduced the ability to record the screens of iOS 8 devices with QuickTime Player in Mac OS X Yosemite. You may have already been familiar with the ability to do a screen recording with QuickTime but now those screens includes any of the iOS 8 devices you have connected with a cable. The implications of this new feature include:

  • High quality video recording – the video is going over the wire instead of WiFi
  • Capture audio from the device or your computer
  • Easy access to QuickTime’s built-in exporting tools
  • No new software to install – Yosemite and iOS 8 are the only requirement

The Steps

  1. Connect your iOS 8 device to your Mac OS X Yosemite (10.10) computer with the USB to lightning or dock connector cable.
  2. Launch QuickTime Player (inside of /Applications in Finder).
  3. Click Done on the file browser window that appears by default when QuickTime launches.
  4. Click File > New Movie Recording. A window will appear typically picking your built-in FaceTime camera by default. Smile.
    QuickTime File New Recording
  5. Click the little arrow next to the red recording button.
    QuickTime Recording Inputs
  6. Under Camera select the iOS device you wish to record.
  7. Your iOS device’s screen should appear on your Mac.
  8. Optionally select your device under Microphone as well if you want to record the audio from the device rather than your computer’s microphone.
  9. Click the red record button when you want to record, clicking it again when you’re done.
  10. Export the video under File > Export picking an appropriate resolution.

Notice that Apple took the time to replace your device’s status bar with one being carrier-free and fixed at 9:41am.

QuickTime Sanitized Status Bar

Nice touch.

Limitations

There are only a couple limitations that I’ve found so far. Finger tips are not shown in the video, so it can be hard to demonstrate things. My suggestion is to talk through the issue or provide a list of things you tapped if its not obvious. Secondly if you’re trying to demonstrate something that involves going full screen (like watching a video on the phone) then the recording will not capture the full screen presentation (it’ll go black). Lastly there is a little bit of lag when you’re recording so make sure to watch the actual device screen and not your computer. If you record audio from your microphone, QuickTime does a good job syncing it up afterwards. This process also works a bit better on newer devices.

Next Steps

Sharing the video you’ve recorded can be a challenge since these videos tend to be of a very very large size in a matter of seconds. Exporting in 480p can definitely help. If you’re providing a demonstration of a bug then you may wish to clip the beginning and end of the movie to only show the actual reproduction of the bug. Follow Apple’s instructions on how to clip a video here.

Reflector is still a great program and very useful. Simple things like being able to add a fake iPhone or iPad frame around the video makes a big difference for demo purposes. I will still continue to use Reflector especially since it’s still the only way to record iOS 7 devices.

Providing Emergency Contacts with iOS 8

The Problem

Something that has been missing on iOS for a long time is a reliable way to provide emergency contact information.  Imagine you’re out and about and you end up having an accident or have an acute attack from a known medical condition you have.  We all tend to carry our mobile phones with us.  Most emergency personnel are trained to review personal data in your wallet/purse and now mobile phones.  The issue is most of us have a lock code on our devices, preventing access to potential life-saving communication with a loved one about your medical condition.

Setting up Medical ID

iOS 8 now has a feature that lets you provide that critical medical information to emergency responders.  It’s called Medical ID.  Here’s how to set it up in a few steps:

First, select the “Health” app.

IMG_0004

 

Then, select “Medical ID” on the far right.  And then tap “Create Medical ID”.

IMG_0005

 

Enter in your personal information you’d like to provide to emergency workers.  At a minimum you should select a contact from your phone to allow someone to call on your behalf.  I’d also suggest entering in your blood type.

IMG_0007 IMG_0008

Tap Done when you’re finished.

IMG_0009

 

Now when someone swipes to “Emergency Call” on your device, Medical ID is listed with the details you provided.

IMG_0010

IMG_0011

Share This Information

Make sure to share this information with your loved ones that have iOS devices.  A few minutes of setting this up could mean a huge help down the road!

 

Core Data Object IDs can change

I thought I knew a lot about Core Data with having used it a lot over the past years.  Today, I learned something new that I feel like I should have known for a long time.  NSManagedObjectIDs can change.  Seriously.

Identity in Core Data is really a tuple of (file aka store UUID, entity name, primary key). This can be captured in the -URIRepresentation from NSManagedObjectID. However, that requires using the same file, and not resetting the primary keys (e.g. changing the store UUID, or delete the file and creating a new one, or performing a not-light-weight migration)

If you want a different notion of identity, you can just add an UUID string as an attribute to your entity. A separate mapping table is not recommend. The 2 apps should agree to use the same UUIDs for the same identities.

– Ben

Ref: https://devforums.apple.com/message/480640#480640

Ben is one of the core developers of Core Data at Apple.  The last sentence describing ways primary keys can change blew my mind when mentioning “not-light-weight migration”.  In WordPress for iOS we sometimes have to perform heavyweight migrations – especially in the case of removing objects or combining object ancestries.  In a number of cases we use NSManagedObjectID’s URIRepresentation and throw it in NSUserDefaults for retrieval later.  Turns out, that ID isn’t stable enough between migrations.

The solution, as Ben points out, is to create a UUID and make the ID yourself upon initial persistence.

Mind blown.

Live Storm Chasing App

Enjoy chasing storms from your couch like me?  There’s a great app called “TVNweather Live Storm Chasing” that I’ve been using to watch live streams from actual storm chasers out in the field.  You’ll see names like Reed Timmer (TornadoVideos.net) and the team running the Dominator 2.

TVNweather Live Storm Chasing for iOS

The app itself needs some work with stability, but the collection of active streams is incredibly handy and fun to watch.  An Android version is coming soon as well.  Until then you can also watch on their site at http://tvnweather.com/live.

On the Importance of Glue

Glue is the thing that … well … glues everything together.  You don’t see glue (if the product is made right) but it plays an important role in the overall satisfaction with the product.  If you buy a bird house that has bad gluing technique or not enough glue, you will be upset when the first bird flattens the house.

The same hold trues for mobile apps as well as web and desktop applications.  For sake of this discussion, I’m limiting myself to mobile apps and mentioning some specific iOS technologies.

So much time is seemingly spent on visual design and user experience that occasionally the glue doesn’t receive the attention it should.  Glue is everything that the user doesn’t see outright in your app:

  • Persistence / State Restoration
    • Core Data
    • Data Synchronization (iCloud, Dropbox, Simperium, etc.)
    • UIStateRestoration
  • Performance
    • Power
    • CPU
    • Memory
  • Integration & Networking
  • Internationalization
  • Dates & Times
  • Accessibility
  • Unit Testing

It’s easy to get hung up on the visual details and leave some of these incredibly important things to the side.  Users may not see the problems outright but they will come to associate a bad feel with your app if things don’t work quite right.

Example: The Nike+ Fuelband App

I’ve been an avid Fuelband user for almost two years now.  I’ve come to treat the device as something that I use every day and pay attention to how much activity I’ve done for the day.  Getting to green is my goal and it irritates me when things don’t work.  Some of the glue that has been broken lately includes funky sync over Bluetooth LE and bad dates/times when syncing with their web app.  The web app itself has also been flaky and slow.  This is a good example of when a beautifully designed app fails the user and causes distrust of the entire brand.

The Recourse

Admit your mistakes and start fixing them.  The WordPress iOS app has been around for quite some time but had been unstable for a while.  The nature of open source software means there are so many hands touching it.  We started focusing on the glue to make the experience better overall.  Once we got some of the stability back into the project, we moved forward with the UI changes for iOS 7.  Things are improving with every release – especially when we are able to spend the time to replace aging code.  Core Data has a big role in the application and stabilizing the stack there with multithreading has made a huge improvement.  We have big plans for further UI improvements!  Get involved at http://make.wordpress.org/mobile if you’re interested. 🙂

The Balance

A balance has to be maintained between visual and the non-visual elements of an application.  If you’re in charge of running a mobile project, make sure the people paying the bill know upfront what’s important to keep in mind when developing an application.  If they don’t want to pay for what you’re estimating, don’t take the project.  This may be a little hard at an ad agency or working with an internal department, but the outcome is the same.  Make sure they know if all they want to focus on is the user experience and visual design, the output will be of prototype quality.  It’s your job to educate your customer and product owner of the importance of the things that can’t be seen.

 

Stop Being Lazy with Accessibility

I’m making  a pledge as a software developer to think of accessibility with every change I make.  My first step was to turn on iOS’ VoiceOver and test everything I’m working on with it.  In the first five minutes of using it, I’ve discovered so many necessary improvements to make the app even useful for someone who has trouble seeing.  There are many more accessibility tools than VoiceOver (like Dynamic Type) that should also be on your list to try.  Baby steps.

Developers: Spend some time with your apps without your eyes.  It’s not fair to place limits on sight-impaired people because you’re lazy.

I’m going to stop being lazy.