<![CDATA[IAM Apps - Blog]]>Mon, 17 Sep 2018 00:46:16 -0400Weebly<![CDATA[tripFiles]]>Tue, 17 Apr 2018 19:22:14 GMThttp://iamapps.net/blog/tripfiles
A travel app that lets you explore amazing destinations, treasure your own experiences, and share them safely with friends and family

• Collect travel photos and videos and organize them by trip
• Post your experiences in real-time or all at once when you’re back home
• Check into locations so you can remember places and activities you enjoyed
• Tell others what you think of the places you went and see what they had to say
• Create connection groups with family, friends or business associates or share only with specific people
• See where the people you know are going
• Find interesting things near you while you’re traveling
• Get inspired by others’ adventures
• Plan your next trip by keeping track of your favorite places, photos and more

Get tripFiles on the App Store
By tripFiles, LLC.
​Built by IAM Apps

]]>
<![CDATA[VFLLiteral]]>Mon, 22 Jan 2018 05:00:00 GMThttp://iamapps.net/blog/vflliteral

VFLLiteral is a swift library to create compile-time checked VFL expressions. What does that mean?

Examples

Each of the following are valid VFLLiteral expressions. Note that there are zero strings in these examples.

NSLayoutConstraint.create(V:[spanner[>=20]]-(>=0~998)-|)NSLayoutConstraint.create(H:[button]-[textField])NSLayoutConstraint.create(H:|[button]|)NSLayoutConstraint.create(V:|-50-[purpleBox]-(50)-|)NSLayoutConstraint.create(V:[textField][spanner])NSLayoutConstraint.create(H:[button[>=100~20]])NSLayoutConstraint.create(H:[button[>=70,<=100]])NSLayoutConstraint.create(V:[button[==70~750,<=100, >=40]])NSLayoutConstraint.create(V:|-[button]-[textField]-|)NSLayoutConstraint.create(H:|-[purpleBox[>=20]]-|)NSLayoutConstraint.create(H:|-[button]-[textField[0]]-[purpleBox[>=20]]-|)NSLayoutConstraint.create(V:[purpleBox[<=0]][button[0]]-(0~999)-|)NSLayoutConstraint.activate(H:[spanner[<=0~999]]-(0~999)-[button[0]])NSLayoutConstraint.activate(H:[purpleBox[<=0]]-0-[button[0]]-(0~999)-|)NSLayoutConstraint.activate(V:[button[>=50]])NSLayoutConstraint.activate(H:[button]-10-[textField])NSLayoutConstraint.activate(V:[spanner[==textField]])NSLayoutConstraint.activate(H:[spanner[>=textField,<=button]])NSLayoutConstraint.activate(V:|-[textField[0]]-[purpleBox[>=20]]-|)NSLayoutConstraint.create(H:[purpleBox[<=0]]-[button[0]]-(0~999)-|,                          V:[purpleBox][textField]) // H and V at the same time

VFLLiteral expressions directly contain UIView or NSView types, as well as numeric types. This means there is no need for a views dictionary or a metrics dictionary. The create methods generate and return an array of NSLayoutConstraint which have not been activated. The activate methods return the same value plus activating the constraints before returning.

The create and activate method forms both accept an options array for NSLayoutFormatOptions \ NSLayoutConstraint.FormatOptions.

    NSLayoutConstraint.activate(V:[spanner[<=0~999]]-(0~999)-[button[0]], options: [.alignAllCenterY])

That's all there is to it. :)

]]>
<![CDATA[HoneyBee]]>Sat, 07 Jan 2017 05:00:00 GMThttp://iamapps.net/blog/honeybee

HoneyBee is a Swift library to increase the expressiveness of asynchronous and concurrent programming. HoneyBee design follows a few principles:

  • Show Me. Concurrent code should look like the structure that it implements (see Examples below)
  • Bring Your Own Code. HoneyBee works with your asynchronous and synchronous functions, as they are today, with no modifications. (Usually.)
  • Safe By Default. HoneyBee enforces proper error handling techniques - while also reducing programmer burden.

Quick Examples

Example: Show Me.

HoneyBee.start()        .setErrorHandler(errorHandlingFunc)        .chain(funcA)        .branch { stem in            stem.chain(funcC)                .chain(funcD)            +            stem.chain(funcE)                .chain(funcF)        }        .chain(funcG)

In the above recipe, funcA will be called first. Then the result of funcA will be passed to funcC and funcE in parallel. funcD will be called after funcC has finished and will be passed the result of funcC. Likewise, funcF will be called after funcE has finished and will be passed the result of funcE. When both funcD and funcF have finished, their results will be combined into a tuple and passed to funcG. If any of the functions throws or asynchronously responds with an Error, then errorHandlingFunc will be invoked with the error as an argument.

Example: BYOC (Bring Your Own Code)

func funcA(completion: ([String]?, Error?) -> Void) {...}func funcB(string: String) throws -> Int {...}func funcC(int: Int, completion: (Error?) -> Void) {...}func funcD(int: Int, completion: (FailableResult<String>) -> Void) {...}func funcE(strings: [String], completion: () -> Void) {...}func successFunc(strings: [String]) {...}HoneyBee.start()        .setErrorHandler(errorHandler)        .chain(funcA)        .map { elem in            elem.chain(funcB)                .chain(funcC)                .chain(funcD)        }        .chain(funcE)        .chain(successFunc)

In the above recipe we see six of HoneyBee’s supported function signatures. funcA is an Objective-C style errorring async callback. funcB is a synchronous Swift throwing function. funcC completes with an optional error but does not generate a new value. HoneyBee forwards the inbound value automatically. funcD is a Swift style, generic enum-based result which may contain a value or may contain an error. funcE is asynchronous but cannot error (UI animations fit this category). And successFunc is a simply, synchronous non-errorring function.

HoneyBee supports 34 distinct function signatures.

Example: Safe By Default

One of the many problems with the “pyramid of doom” is that error handling is hard to get right.

func processImageData1(completionBlock: (result: Image?, error: Error?) -> Void) {    loadWebResource("dataprofile.txt") { dataResource, error in        loadWebResource("imagedata.dat") { imageResource, error in            decodeImage(dataResource, imageResource) { imageTmp, error in                dewarpAndCleanupImage(imageTmp) { imageResult in                    completionBlock(imageResult, nil)                }            }        }    }}

The above naive, “happy path” code has no error handling. Let’s add the most principled form of handling now:

func processImageData2(completionBlock: (result: Image?, error: Error?) -> Void) {    loadWebResource("dataprofile.txt") { dataResource, error in        guard let dataResource = dataResource else {            completionBlock(nil, error)            return        }        loadWebResource("imagedata.dat") { imageResource, error in            guard let imageResource = imageResource else {                completionBlock(nil, error)                return            }            decodeImage(dataResource, imageResource) { imageTmp, error in                guard let imageTmp = imageTmp else {                    completionBlock(nil, error)                    return                }                dewarpAndCleanupImage(imageTmp) { imageResult in                    guard let imageResult = imageResult else {                        completionBlock(nil, error)                        return                    }                    completionBlock(imageResult, nil)                }            }        }    }}

Not very pretty, right? And there’s still issues here. This form of processImageData has made its contract correctness dependent on the contract correctness of all of the invoked asynchronous methods. What happens if one of the methods fails to call its completion? Or calls back more than once? What happens if a method calls the completion, but with two nil values? HoneyBee handles each of these issues for you, so that your method’s correctness is not dependent on the correctness of any dependency method. Let’s take a look at the Honeybee form:

func processImageData3(completionBlock: (result: Image?, error: Error?) -> Void) {    HoneyBee.start()            .setErrorHandler { completionBlock(nil, $0)}            .branch { stem in                stem.chain(loadWebResource =<< "dataprofile.txt")                +                stem.chain(loadWebResource =<< "imagedata.dat")            }            .chain(decodeImage)            .chain(dewarpAndCleanupImage)            .chain{ completionBlock($0, nil) }}

So much cleaner right? And Bonus Points, the HoneyBee implementation allows us to parallelize the first two async calls to loadWebResource, so this form has better performance than the others too. Groovy.

(If you’re wondering about the =<< operator it’s pronounced bind. It performs a partial function application, “binding” the argument to the function. See the API docs for more details.)

Error Diagnostics

Diagnosing problems in misbehaving concurrent code is really hard right? Not with HoneyBee. Consider the following:

func handleError(_ errorContext: ErrorContext) {    print(errorContext)}func stringToInt(string: String, callback: (FailableResult<Int>) -> Void) {    if let int = Int(string) {        callback(.success(int))    } else {        let error = NSError(domain: "couldn't convert string to int", code: -2, userInfo: ["string:": string])        callback(.failure(error))    }}HoneyBee.start()        .setErrorHandler(handleError)        .insert(7)        .chain(String.init)              // produces "7"        .chain(String.append =<< "dog")  // produces "7dog"        .chain(stringToInt)              // errors        .chain(successFunc)              // not reached}

prints

subject = "7dog" file = "/Users/HoneyBee/Tests/ErrorHandlingTests.swift" line = 172 internalPath = 5 values { [0] = "start: /Users/HoneyBee/Tests/ErrorHandlingTests.swift:167" [1] = "chain: /Users/HoneyBee/Tests/ErrorHandlingTests.swift:169 insert" [2] = "chain: /Users/HoneyBee/Tests/ErrorHandlingTests.swift:170 (Int) -> String" [3] = "chain: /Users/HoneyBee/Tests/ErrorHandlingTests.swift:171 (String) -> String" [4] = "chain: /Users/HoneyBee/Tests/ErrorHandlingTests.swift:172 (String, (FailableResult<Int>) -> ()) -> ()" }

HoneyBee pinpoints the file and line where the recipe errored, along with the path which was taken to arrive at that function, and the inbound “subject” value. In most cases this reduces your diagnostic search process to a single function.

Multiple Queues

By default HoneyBee performs all functions on the global background queue. What if you need to work on the main queu?

HoneyBee.start(on: DispatchQueue.main)        .setErrorHandler(handleError)        .chain(funcA)  // performed on main queue        .chain(funcB)  // same

Easy right? Need to change queues? What about NSManagedObjectContexts?

HoneyBee.start(on: DispatchQueue.main)         .setErrorHandler(handleError)        .chain(funcA)  // performed on main queue        .setBlockPerformer(DispatchQueue.global())        .chain(funcB)  // performed on global background queue         .chain(funcC)  // performed on global background queue         .setBlockPerformer(myMOC)        .chain(funcD)  // performed on myMOC's internal queue. 

HoneyBee puts you in complete control of what queue will invoke your functions. This remains true even if the functions themselves call back on different queues than they were invoked from.

Wrap Up

So that’s HoneyBee. Expressive, easy, and safe. Concurrency the way it should be. If you have any questions, contact me.

]]>
<![CDATA[Sing With The Best]]>Thu, 07 Jul 2016 04:00:00 GMThttp://iamapps.net/blog/sing-with-the-best
Learn to sing with the best intonation, pitch accuracy, resonance, vibrato, and vocal clarity. Sing With The Best helps you recognize your vocal strengths and weaknesses, and guides you to meaningful answers to your vocal questions. The app's inventor, Dr. Adam Kirkpatrick, will be your virtual voice teacher.

Features
  • Pitch Display: Displays the note you are singing and highlights the note name in green when you are fully in tune. Sing with the best intonation and pitch accuracy!
  • 3D Spectrogram: Sing with the best resonance and "ping!" Amazing voice visualization displays frequency, amplitude, and time; it creates an image, mapping out your unique vocal fingerprint, and highlights the desirable bell tone harmonics of the voice in green, and noise in red.
  • Vibrato Meter: Indicates the presence and quality of your vibrato (Pleasing, Slow Wobble, Wide Wobble, Wide & Slow, Bleat, and Flutter). Sing with the best vibrant tone!
  • Noise Meter: Tracks and displays the noisiness of your tone. Sing with the best vocal clarity!
  • Record & Playback: Hear what you really sound like, and watch the replay. Sing with the best way to review and assess your performance!
  • Recording Archive: Generates a library of your recordings with a time/date stamp so you can track your vocal progress over time, or just store your favorite recordings.
  • Tutorials: With the touch of a button, you have free access to an ever-expanding wealth of video lessons and app tutorials by the inventor Dr. Adam Kirkpatrick. Learn to sing with the best vocal exercises and techniques for vocal mastery!

​Get Sing With the Best

By Adam Kirkpatrick
Built by IAM Apps


It's available in the iTunes Store for all iOS devices.
]]>
<![CDATA[Talkler]]>Wed, 15 Jul 2015 07:00:00 GMThttp://iamapps.net/blog/talkler
Drowning in email? Introducing Talkler, the only app for heads-up, reads-aloud-to-you, voice-controlled email. Reads your emails aloud. Listens for your voice commands. Just say, "Hey, Talkler..."
  • "Play the next email"
  • "Record a reply"
  • "Delete"
  • "Mark unread"
  • "Check for new mail"
  • Dozens more voice commands

​Talkler is easier than ever to set up. And with the NEW Talkler QuickConnect: Simply enter your email & password — Talkler enters the rest of your settings for you. Including custom domains, like example@mydomain.com. Plus, NEW Hosted Exchange support! (Expert users can always customize server and port settings; ActiveSync isn't yet supported, so in-house Exchange servers must open IMAP/POP, and SMTP.) Need a hand? We're happy to help. Visit Talkler.com/help for 1-to-1 support, or email us: help@talkler.com

Features:
  • Talkler TapAnywhere™ heads-up gestures. No squinting at tiny buttons. TapAnywhere onscreen to pause and resume playback of your emails. Swipe anywhere to skip to the next email. Pinch anywhere to delete. As heads-up as your turn signal.
  • Talkler Teleprompter™ auto-scrolling text. Didn't catch that last word? No worries. Synced, auto-scrolling text is easy to read from a distance. Easy as glancing at a speedometer.
  • Talkler AudioReplies™ with Zero Typos.™ No proofreading. No need to take your eyes off what matters. Records every inflection, and sends an audio voice reply.
  • Talkler AutoPilot.™ Intelligent auto-continue, when all you want to do is listen.
  • Talkler QuickConnect.™ Simply enter your email & password. Talkler enters the rest of your settings for you.
  • Raise-to-Ear Privacy Mode.™ Like a phone call with your inbox. Lift your iPhone to your ear: the screen darkens, and volume adjusts for privacy. Automatically.

Get Talkler - Email for Your Ears
By Talkler Labs Inc.
Built by IAM Apps

It's available in the iTunes Store for all iOS devices.
]]>
<![CDATA[Growing Local Learning]]>Tue, 14 Jan 2014 08:00:00 GMThttp://iamapps.net/blog/growing-local-learning
Now it’s easier than ever to earn cash for your school…Growing Local Learning® has just gone mobile!

Box Tops for Education® has teamed up with ACME, Albertsons, Cub, Farm Fresh, Jewel-Osco, Shaw’s, Shop ’n Save, and Shoppers to create the new Growing Local Learning app. Now, when you make qualifying purchases, and receive a Growing Local Learning code at checkout, you can enter those codes immediately—right from your iPhone®!

You can still enter your codes online, but between work, carpools, volunteering, and trips to the grocery store, we know you’re busy. And Growing Local Learning is here to help!

Features

  • Register for Growing Local Learning
  • Enter Growing Local Learning codes on your iPhone®
  • View the latest General Mills Bonus Box Tops offers
  • Browse delicious and easy-to-make Betty Crocker® recipes
  • Track your personal earnings as well as your school’s Growing Local Learning earnings
  • Find participating stores in your area

Get Growing Local Learning
By General Mills Inc.
Built by IAM Apps


It's available in the iTunes Store for all iOS devices.
]]>
<![CDATA[Nutritiming]]>Wed, 06 Feb 2013 08:00:00 GMThttp://iamapps.net/blog/nutritiming
NutriTiming™ is the only iOS app providing a revolutionary way to track your “Within Day Energy Balance”—a system used by Olympic, professional and other elite athletes from all over the world. Developed by top sports nutritionist, Dr. Dan Benardot, the within-day energy balance strategy is now available to the general public. Through NutriTiming™, you can now achieve REAL TIME, individualized calorie and activity guidance that will enhance your weight loss, nutrition, body composition, and performance goals.
Energy balance has traditionally been assessed over periods of 24 hours, but this 24-hour assessment fails to consider the fluctuations in energy balance that occur on an hourly basis, which can influence your body’s response to calories. Measuring within-day energy balance in real time resolves this problem. By staying within the prescribed energy balance boundaries (+ or – 400 calories during the day), you can target fat loss and spare muscle mass, improve athletic performance, avoid low blood sugar that can make you feel less alert and too hungry, and improve your attention span and sense of well-being.
NutriTiming™ helps you match on an hourly basis your actual need for calories with your present rate of calorie usage. The right amount at the right time means a leaner you with NutriTiming™.
reports & graphs
Know when and how much to eat in real time by viewing a simple graph to determine whether your energy balance is too high or to low (higher than + 400 or lower than -400).
Use simple graphs to review end-of-day energy balance. To lower your body fat level, you should end the day with an energy deficit of between -100 to -400 calories. To increase muscle mass, you should do resistance activity and end the day with an energy surplus of between + 100 to + 400 calories.
Turn the device sideways to review REAL TIME within-day energy balance graphs. Make certain you spend the day in the ‘green zone’.

Features
  • Easy to enter food items
  • More than 4,500+ food and restaurant items from the latest (version 21) of the USDA nutrient database
  • Store frequently consumed meals for later faster and easier food selection
  • Works with any exercise because it uses the relative intensity of activity to predict calories expended
  • Easy and fast user interface for entering foods and activities.

What makes it so great?
  • Proven by more than 15 years of laboratory work and research on elite athletes
  • REAL TIME tracking of calories both consumed and expended lets you know WHEN and HOW MUCH to eat
  • Customized to your age, gender, and body weight
  • No special foods needed or eliminated
  • Safe for any age
  • Healthy, well-rounded diet
  • Lose weight while maintaining healthy body composition
  • OPTIMIZE ATHLETIC PERFORMANCE, by avoiding the huge energy dips so often associated with exercise.
  • No suffering – users feel better while accomplishing their weight loss, nutrition, and performance goals
For questions and for a list of references related to within-day energy balance, go to nutritiming.com.

Get NutriTiming for iOS.

NutriTiming
By Calorie & Pulse, LLC.
Built by IAM Apps

For more information on NutriTiming, visit nutritiming.com
]]>