Categories
Uncategorized

Swift 3 text field magic, part 3: Creating text fields that ban a specific set of characters

creating-text-fields-that-ban-specified-characters

So far, in this series of articles, we’ve created classes that extend the capabilities of iOS’ default text fields so that they can:

These limits can be set in both Interface Builder and code.

In this article, we’ll create a new text field: one that doesn’t allow a specified set of characters to be entered into it. You may want to read the first two articles in this series, as this article builds their material.

The MaxLengthTextField class, in review

In the first article in this series, we created a subclass of UITextField called MaxLengthTextField. MaxLengthTextField added one additional ability to UITextField: the ability to limit the number of characters that could be entered into it. Here’s its code:

import UIKit


// 1
class MaxLengthTextField: UITextField, UITextFieldDelegate {
  
  // 2
  private var characterLimit: Int?
  
  
  // 3
  required init?(coder aDecoder: NSCoder) {
    super.init(coder: aDecoder)
    delegate = self
  }
  
  // 4
  @IBInspectable var maxLength: Int {
    get {
      guard let length = characterLimit else {
        return Int.max
      }
      return length
    }
    set {
      characterLimit = newValue
    }
  }

  // 5  
  func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {

    // 6    
    guard string.characters.count > 0 else {
      return true
    }
    
    // 7
    let currentText = textField.text ?? ""
    // 8
    let prospectiveText = (currentText as NSString).replacingCharacters(in: range, with: string)
    // 9
    return allowedIntoTextField(text: prospectiveText)
  }
  
  func allowedIntoTextField(text: String) -> Bool {
    return text.characters.count <= maxLength
  }
  
}

Here’s what’s happening in MaxLengthTextField — these notes go with the numbered comments:

  1. In order to create a text field with the ability to set a maximum length, we’re defining a new class — MaxLengthTextField — as a subclass of UITextField, which gives it all the properties and behaviors of a UITextField. We also specify thatMaxLengthTextField adopts the UITextFieldDelegate protocol, which allows us to manage changes to the content of our new text fields. We’ll need this in order to set a limit on how much text will be allowed inside the text field.
  2. characterLimit will hold the maximum number of characters that can be entered into the text field. It’s defined as an Int? since its value may or may not be defined, and defined as private since its value will be get and set using themaxLength property.
  3. In the initializer, we specify that MaxLengthTextField will define its ownUITextFieldDelegate protocol methods. We’ll make use of one of these protocol methods later on to ensure that the text field doesn’t accept any more than the specified maximum number of characters.
  4. The @IBInspectable attribute makes the maxLength property editable from within Interface Builder’s Attribute Inspector.
  5. The actual functionality of MaxLengthTextField is contained within textField(_:shouldChangeCharactersIn:replacementString:), one of the methods made available by adopting the UITextFieldDelegate protocol. This method is called whenever user actions change the text field’s content, and itsBool return value specifies if the text change should actually change place. We’ll use this method to limit the number of characters that can be entered into the text field — if user changes would cause the number of characters in the text field to exceed characterLimit, it returns false; otherwise, it returns true.
  6. Get to know and love the guard statement and the “early return” style of programming; you’re going to see a lot of it in a lot of Swift coding. Here, we’re using guard to filter out cases where the user’s changes are of zero length, which means that characters aren’t being added, but deleted. In this case, we don’t have to see if the user’s changes will cause the text field to exceed its set maximum number of characters. We do want the method to return true in order to allow the user’s deletions to take place.
  7. If we’ve reached this point of the method, it means that the user has made additions to the text field. We should see if these changes would cause the text field to contain more than characterLimit characters. The first step in this process is getting the text currently in the text field. We use the nil coalescing operator?? — to assign the contents of the text field if they are not nil, or the empty string if they are nil.
  8. Now that we have the current text, we’ll determine the prospective text — the text that would result if the changes were accepted.
  9. Finally, we use the the length of the prospective text to decide whether to allow the changes or not. We’ve factored this logic into its own method because we expect to create subclasses to override it.

The AllowedCharsTextField class, in review

In the second article in this series, we built of MaxLengthTextField and subclassed it to create AllowedCharsTextField. AllowedCharsTextField adds the ability to limit the characters that can be entered into it to only those in a specified string. Here’s its code:

import UIKit
import Foundation


class AllowedCharsTextField: MaxLengthTextField {
  
  // 1
  @IBInspectable var allowedChars: String = ""
  
  
  required init?(coder aDecoder: NSCoder) {
    super.init(coder: aDecoder)
    delegate = self
    // 2
    autocorrectionType = .no
  }
  
  // 3
  override func allowedIntoTextField(text: String) -> Bool {
    return super.allowedIntoTextField(text: text) &&
           text.containsOnlyCharactersIn(matchCharacters: allowedChars)
  }
  
}


// 4
private extension String {
  
  // Returns true if the string contains only characters found in matchCharacters.
  func containsOnlyCharactersIn(matchCharacters: String) -> Bool {
    let disallowedCharacterSet = CharacterSet(charactersIn: matchCharacters).inverted
    return self.rangeOfCharacter(from: disallowedCharacterSet) == nil
  }

}

Here’s what’s happening in AllowedCharsTextField — these notes go with the numbered comments:

  1. The instance variable allowedChars contains a string specifying the characters that will be allowed into the text field. If a character does not appear within this string, the user will not be able to enter it into the text field. This instance variable is marked with the @IBInspectable attribute, which means that its value can be read and set from within Interface Builder.
  2. We disable autocorrect for the text field, because it may try to suggest words that contain characters that we won’t allow into it.
  3. Overriding MaxLengthTextField‘s allowedIntoTextField method lets us add additional criteria to our new text field type. This method limits the text field to a set maximum number of characters and to characters specified inallowedChars.
  4. We extend the String class to include a new method,containsOnlyCharactersIn(_:), which returns true if the string contains only characters within the given reference string. We use the private keyword to limit this access to this new String method to this file for the time being.

Let’s make BannedCharsTextField

BannedCharsTextField is a slight variation on AllowedCharsTextField. Here’s its code:

import UIKit


class BannedCharsTextField: MaxLengthTextField {
  
  @IBInspectable var bannedChars: String = ""
  
  
  required init?(coder aDecoder: NSCoder) {
    super.init(coder: aDecoder)
    delegate = self
    autocorrectionType = .no
  }

  override func allowedIntoTextField(text: String) -> Bool {
    return super.allowedIntoTextField(text: text) &&
           text.doesNotContainCharactersIn(matchCharacters: bannedChars)
  }
  
}


private extension String {
  
  // Returns true if the string contains no characters in common with matchCharacters.
  func doesNotContainCharactersIn(matchCharacters: String) -> Bool {
    let disallowedCharacterSet = CharacterSet(charactersIn: matchCharacters)
    return self.rangeOfCharacter(from: disallowedCharacterSet) == nil
  }
  
}

The differences between BannedCharsTextField and AllowedCharsTextField are:

  • We store a string containing the characters that we want to ban from being entered into the text field in an instance variable called bannedChars.
  • The allowedIntoTextField method calls a String extension method called doesNotContainCharactersIn, which returns true if the string doesn’t any of the banned characters.

Using BannedCharsTextField

Using BannedCharsTextField within storyboards is pretty simple. First, use a standard text field and place it on the view. Once you’ve done that, you can change it into an BannedCharsTextField by changing its class in the Identity Inspector (the inspector with the identity-inspector icon):

bannedcharstextfield-custom-class

If you switch to the Attributes Inspector (the inspector with the attributes inspector icon icon), you’ll be able to edit the text field’s Allowed Chars and Max Length properties:

bannedcharstextfield-attributes-inspector

If you prefer, you can also set BannedCharsTextField‘s properties in code:

// myNextTextField is an instance of BannedCharsTextField
myNewTextField.bannedChars = "AEIOUaeiou" // No vowels allowed!
myNewTextField.maxLength = 7

A sample project showing MaxLengthTextFieldAllowedCharsTextField, and BannedCharsTextField in action

app

If you’d like to try out the code from this article, I’ve created a project named Swift 3 Text Field Magic 3 (pictured above), which shows both MaxLengthTextField andAllowedCharsTextField in action. It’s a simple app that presents 3 text fields:

  1. A MaxLengthTextField with a 10-character limit.
  2. An AllowedCharsTextField text field with a 5-character maximum length that accepts only upper- and lower-case vowels. Its Max Length and Allowed Chars properties were set in Interface Builder.
  3. BannedCharsTextField text field with a 7-character maximum length that doesn’t allow vowels to be entered into it. Its Max Length and Allowed Chars properties were set in Interface Builder.
  4. BannedCharsTextField text field with a 7-character maximum length that doesn’t allow digits to be entered into it. Its maxLength and allowedChars properties were set in code.

Try it out, see how it works, and use the code in your own projects!

xcode download

You can download the project files for this article (67KB zipped) here.

Coming up next in this series…

In the next installment in this series, we’ll build a text field that accepts only valid numerical values.

Categories
Uncategorized

Tools of my new trade (or: My sweet, sweet SMARTRAC-assigned gear)

15-inch MacBook Pro, Samsung Galaxy S7, Jabra speakerphone, and other goodies assigned to me by SMARTRAC.

I’m working on my kitchen table because I’ve got people in the house installing a brand new air conditioner. You need one in Florida.

Today marks the end of my first week at SMARTRAC as their Technology and Developer Evangelist. Those of you who follow this blog and my social media feeds probably know that I’ve spent most of this week in Fletcher, North Carolina (it’s just outside Asheville), where SMARTRAC has one of its U.S. offices, as well as one of its RFID tag-manufacturing factories.

Although a lot of my work will be done from my home office in Accordion Bay (a.k.a. Tampa), I traveled to Fletcher for a number of reasons:

  • To have some serious face time with Product Manager Jason Rusk and Portfolio Architect Robert van Voorhees and get up to speed on SMARTRAC, the SMART COSMOS IoT platform, and our plans for evangelizing,
  • to get a tour of the factory and see how RFID tags are made, from raw materials to finished product,
  • and to get my grubby paws on the sweet, sweet, sweeeeeet gear that they assigned to me (pictured above).

I didn’t even know that I was getting assigned anything until I toured the factory on Tuesday morning. Here’s a pretty accurate rendition of my reaction:

In order to help me do my job, I have been assigned the following:

  • 2015 15″ MacBook Pro with maxed-out RAM, suitable for coding and creative work
  • IntelliJ IDEA Ultimate and Adobe Creative Cloud, which will come in extremely handy with the evangelizing (and we’ll add the new version of Camtasia to the mix once it’s released)
  • Samsung Galaxy S7 (no, not the exploding one) because I’ll be on the road often
  • Jabra Speak 510 speakerphone module because I’ll be on conference calls often
  • Graph-ruled hardcover notebooks
  • Pens in company colors
  • A whole lotta USB keys that you can wear as wristbands
  • A pile of NFC and other RFID tags
  • SMART COSMOS-branded gummi bears, because why not?
  • A SMARTRAC tie in company colors. Those of you who attended Microsoft TechDays Canada’s conferences back during my time there know that I can pull off orange:

Me, circa 2009. And yes, since I was in Canada, I used the Canadian spelling: favourite

It’s a very promising sign that SMARTRAC gives their employees not just the tools they need to get their jobs done, but such very nice versions of those tools. In a world where many businesses see employees only as necessary evils and expenses, it’s heartening to see that there are still companies out there that invest in their people.

What comes next is the reason I was assigned all this stuff: to help customers understand the technology and platform that we’re building, and to help systems integrators and developers make the most of it. I know that what I’m saying sounds all hand-wavey and amorphous right now, but keep an eye on this blog — there’s going to be a lot of very, very interesting new stuff on it over the coming weeks and months!

Categories
Uncategorized

How to rescue a princess in 8 programming languages

Two of the jokes from the 'Git the Princess! How to save the princess using 8 programming languages' comic.

This is an excerpt. Click the comic to see the full version.

Just in time for Hump Day comes Git the Princess! How to save the princess using 8 programming languages, a comic that pokes fun at JavaScript, C, C#, Java, Lisp, Go, Pascal, and (of course) PHP.

The comic is yet another variation on the “If programming languages were $THING joke, such as “If programming languages were vehicles”, which goes all the way back to the days when all the interesting stuff happened on USENET.

The comic is the creation of the dev team at Toggl, the time tracking tool. Come to think of it, since I’m contract-to-hire at my new job for the next six months, I should sign up for an account.

Categories
What I’m Up To

Day one of the new job: Developer evangelist at SMARTRAC!

Photo: American Airlines jet as seen from below, taking off. Headline: New job - DAY ONE.

Today — Monday, October 3rd, 2016 — marks the start of my new gig, Developer Evangelist at SMARTRAC, a leading manufacturer of high-security RFID inlays and tags, and the world’s largest supplier of RFID inlays for “e-passports”, according to Wikipedia.

Logo: SMARTRAC / Connect Things

SMARTRAC manufacture a wide variety of RFID inlays and tags for all sorts of uses, ranging from asset tracking and supply chain management to access control to contactless payment (such as “tap” credit cards) to remote keyless entry for cars to animal identification to tickets for concerts and sports events to retail sales and anti-counterfeiting protection.

Photo: A roll of SMARTRAC 'DogBone' RFID tags. The tiny black dot in the center of the tag is the actual RFID chip; the dogbone-shaped metal trace making up most of the tag is the antenna.

SMARTRAC started as a hardware company producing radio frequency transponders and reader, but they’ve seen that a lot of the opportunity is in the software that talks to this hardware and in the emerging internet of things (IoT).

Logo: SMARTCOSMOS - Powered by SMARTRAC

That’s where SMART COSMOS comes in. It’s SMARTRAC’s portfolio of cloud-based services that enables developers to build new applications that can work with SMARTRAC’s RFID tags and inlays to “read the world”.

Here’s the official “SMART COSMOS 101” video:

SMART COSMOS needs someone who can wear a number of hats:

  • Developers will be writing applications that make use of SMART COSMOS’ SaaS services, and they’re going to need someone who can speak their language to show them how it’s done.
  • A number of SMARTRAC’s clients are the sales and marketing departments of large retail operations, and they’ll need to someone who can operate in both the worlds of marketing and technology.
  • And finally, SMARTRAC makes appearances at conference worldwide — a quick glance at their site says that they’ll be a conferences in Vegas, Munich, Tehran, Cannes, and Manila before the end of the year — and they’ll need a skilled speaker and presenter to promote their wares.

You know who’s really good at all of these? This guy:

This is a remote job, with me working from the home office…

…but punctuated with trips to conferences where SMARTRAC will have a booth or will be presenting and developer gatherings, visits to the U.S. office in Baltimore or the European office, and possibly SMARTRAC’s RFID manufacturing facilities, which are scattered all over the globe.

Photo: The city of Asheville, North Carolina in the sunset (or sunrise), with forest in the foreground and mountains in the background. Heading: HELLO, ASHEVILLE!

Day one of the job has me on the road to one of those aforementioned manufacturing facilities. I’m off to Asheville, North Carolina to visit the SMARTRAC plant there, and spend the next few days working with my new team on a developer evangelism plan for SMARTTRAC. This will be interesting, and I’ll be posting quite a bit on this topic, so watch this space!

Categories
Uncategorized

End of an era: BlackBerry no longer making its phones

losing-the-signal

Close-up of J. Scott Paul’s cover design for the Canadian edition of Losing the Signal: The Spectacular Rise and Fall of BlackBerry, written by Jacquie McNish and my schoolmate from Crazy Go Nuts University, Sean Silcoff.

BlackBerry CEO John Chen’s statement today marks the end of an era: “The company plans to end all internal hardware development and will outsource that function to partners.”

With revenues in the second quarter of 2016 falling by nearly a third and its recent pivot to Android failing to boost sales, there was no choice but to follow through on the promise to leave the handset business if they couldn’t make it profitable.

alcatel-idol-4-blackberry-dtek50

The same phone: Alcatel’s Idol 4 and BlackBerry’s DTEK50.

The departure from hardware isn’t unexpected. Analysts have been predicting that BlackBerry would switch to software for some time, and its most recent device are other vendors’ hardware with BlackBerry branding (the DTEK50 is an Alcatel Idol 4, and leaked photos suggest that the DTEK60 is the Idol 4S). There’s also the matter of Chen being less than enthusiastic about the company’s hardware business, from his focus on the software side of BlackBerry, to outsourcing manufacturing to several Taiwanese companies, to this “I don’t really use the thing” demo of the Priv from last September:

“We are reaching an inflection point with our strategy,” says Chen. “Our financial foundation is strong, and our pivot to software is taking hold.” The sea change may keep the company alive, but it’ll be a far different entity than the industry-defining behemoth it once was.

Categories
Uncategorized

Thank you, GSG!

about-time-you-updated-your-blog

Things have been quiet here on Global Nerdy (and even on my other blog, The Adventures of Accordion Guy in the 21st Century) for the past few days. There’s a very good reason for this — I’ve been busy.

The reason I’ve been busy: I’m in the middle of transitioning from my current job to a new one.

gsg-logo-300x300

I’ve enjoyed my time as a GSG’s Platform Evangelist. Landing a job with GSG was a very lucky break. From the fall of 2012 to the end of 2013, I ran a telecom consultancy with a former high school friend, and through his hustling and my presentations and documentation, we managed to pick up Rogers (a big Canadian telco with fingers in lots of pies from publishing to cable TV to sports teams — think of them Canuck version of Time Warner) as a client.

That job should’ve made me some decent coin, but it pretty much drained my bank account. That’s because my former friend pretty took all the money for himself while telling the rest of us that we’d get paid soon, “once the client paid us”. I was going broke and paying rent with my blogging profits (fortunately, I was having a hot streak with ad revenue at the time) while my friend started leasing a big house in Oakville, bought a new car, and who knows what else, a fact I discovered when invited to his house one Saturday for a little get-together.

empty-wallet

Although working with my former friend turned out to have a lot of downside, there was one significant upside: it got me in touch with GSG. They were also working with Rogers, and loved the presentations and documentation that I produced. They offered me some contract work, which grew into my current job. They sponsored my TN-1 status, which allowed me to work in the U.S., and my first day as a GSGer was March 10, 2014.

I’m thankful for all the things I got to do at GSG, from helping them create a new web site, to changing all their marketing material, to working on interesting projects with GSG partners. I got us our moment on a Times Square billboard:

nubison-gsg-times-square

A GSG press release on a Times Square billboard. Click to see at full size.

I did a number of webcasts with partners, including Enterprise Mobile (a subsidiary of Honeywell)…

…and made a number of videos like this one for IBM, for which I wrote the script, created the graphics, did the narration, and assembled the video:

One of the highlights of my time at GSG was getting to meet (and perform on stage with) the folks at the office in Pune, India:

20151105_074057

It was working for GSG that allowed me to move to Tampa to be with Anitra, make enough money to get out of the debt that working for my former friend had put me in, and help cover the costs of a wedding. For giving me the chance to start my new life in a subtropical paradise with a lovely lady, I will always be grateful to GSG.

anitra-joey-wedding

I leave GSG with no small amount of reluctance. They’re great people to work with. GSG’s COO Amine Doukkali was impressed enough by my work and accordion playing to introduce me to CEO Andy Goorno and President Dan Hughes. I soon began work with Dan Goorno, Phil Caruso, Shauna Heydecker, Chris Martin, and Eric Goldman, as well as Mohan Sathe and Sudhir Bapat, who run the India branch, and so many other solid people.

The field that GSG is in — a mix of telecom expense management, enterprise mobility and networking management, and communications lifecycle management — is filled with companies many times GSG’s size, but you wouldn’t know it by its work. GSG punches well above its weight class because its people go above and beyond what anyone should expect. I’m leaving only because an exceedingly rare and precious opportunity came up — otherwise, I’d have gladly continued my work at GSG. I’m proud to have worked there, and would glad cross paths with them in the future.

us-team-1

kugan-and-company

us-team-2

Thank you, GSG for everything; I hope you benefited from my being there as much as I did.

If you’ve read this far, you’re probably wondering what my new job is. I’ll tell you later this week.

Categories
Uncategorized

The two states of every programmer

2-states-of-every-programmer

Sometimes, it feels as if we spend more time in the latter state.

Thanks to Bil Simser for the find!