Wednesday, December 30, 2015

Writing Energy Efficient iOS Code



How to extend the user's battery life and improve user experience.

This transcript is from Apple's WWDC14 2-part video: "Writing Energy Efficient Code"

Overview

OSX 10 Maverix and UP, 2 new sections were added:
1. "Apps Using Significant Energy" in the battery indicator on the status bar.
2. "Battery Usage" tab in Settings showing by-app breakdown of battery usage.


Everything on the system uses Energy. Components include:
1. CPU (using a small amount of CPU makes a big difference to energy consumption)
2. Flash storage. (big dynamic range)
3. Networking.
4. Graphics. (A small change by the developer might cause an expensive operation under the hood)


There are 3 states of energy use:
1. Idle power (device is not being used.  apps not running)
2. System Active (your app is running code)
3. Intermediate States. (system is idle, but not able to get back to idle power.  Time is required to achieve this state.)
a. Device stays in this state a lot, if sporadic work is done.
b. This is the concept of "Fixed Cost".  Anytime sporadic work needs to be done, a minimal cost is incurred.
c. Fixed cost tasks (sporadic tasks) consume a lot of energy for the amount of work they actually perform. (high overhead)
d. The solution is: Bundle all the sporadic tasks together in order to reduce the fixed cost of your work.


Energy and Power are 2 different things.
Power is the peak value at a given, instantaneous point in time (measured in Watts)
Energy is the sustained combined energy usage to accomplish a task (measured in Joules)+

Better Performance most times means: Better Energy use

For small workloads, Fixed Cost will dominate
For intensive workloads, dynamic cost will dominate

POWER can be TRADED for ENERGY, for example:  a single threaded workload can be multi threaded in order to minimize the Fixed Cost. (The Dynamic Cost will stay the same)



Techniques:

1. Do It Never  (Avoid unnecessary work)

If another app comes in front of your app, are you still running animation code in your app?
If another view comes on top of the active view, are you still animating the parent view?
Use:
- (void)applicatioNDidResignActive
- (void)applicationDidBecomeActive
or listen for UIApplicationWillResignActiveNotification

Pause Timers and animations when resigned active.


2. Do It a a Better Time

If you expect an expensive operation such as downloading a huge update or content.  Schedule the work when the user is plugged in to a power source.
OS10 Yosemite has NSBackgroundActivityScheduler schedule things like:
- Periodic content fetch
- Update install
- Garbage collection and data maintenance tasks
- Automatic saves or backups

OSX:
1. Create an NSBackgroundActivityScheduler object with a reverse-dns Unique Identifier.  Re-use these identifiers for the same activity.
2. Set the tolerance  (in seconds.  600 = 10 minute from now start)
3. Set the interval (Execute every interval.  Tolerance applies on top of this)
4. Set reapeats = YES (if you want it to repeat)
5. shouldDefer (allows deferring work until the best time)
Interval will execute it once each Period (not at the same time each time).

Call activity scheduleWithBlock:...

NSURLSession Backround Session:
ou pass a bunch of NSURLRequests to the background session, and they will get executed Out-Of-Process on a System Daemon.
Delegate callbacks work as usual with NSURLSession
If your app gets terminated, your tasks will still be executed by the OS, and when App is re-opened, you will
retrieve your existing session by it's unique string ID, and you will get delegate callbacks also.

iOS7 and Up, you can set configuration.discretionary = YES;   (System picks the best time to do the work)
This provides bandwidth monitoring and automatic retry. (if bandwidth drops below minimum speed, task is paused and retried later. Handles edge cases for you)



3. Do It More Efficiently

iOS8 and up, has "Quality of Service Classes"
1. User Interactive (main thread interactions) - Is this work actively involved in updating the UI? Animations, input event processing...
2. User Initiated (Immediate results) - Is the user waiting on this content before next Interaction can be done.
a. Is it OK for Usre Interactive work to happen before my work?
b. Is it okay for this work to complete with other User Initiated work?
c. Is it oka for my work to take precedence over Utility work?
3. Utility (Long-running tasks) - Is the user aware of the progress of this work. Does it show a progress bar?
4. Background (Not user visible)

(This is a hierarchical priority)
The system prioritizes higher level tasks over lower level tasks..


Practical Example: Imagine we have a Grid View app with image thumbnails being imported and loaded:
1. User Interactive would be the Scrolling only (main thread)
2. User Initiated would be the Thumbnail Generation, and Image loading when clicked.
3. Utility would be Image import and conversion (progress bar shown)
4. Background would include search indexing.



Powermetrics tool can be used to see which QoS are in use. 
usage:  sudo powermetrics —show-process-cos —samplers tasks

Gives the MS per sec usage breakdown of each QoS class for your application. 

To see which QoS class is used while debugging: 
  • Pause in debugger. 
  • Go to the CPU tab to see breakdown of threads. 
  • You will see all the different threads and resource usage of each. 
  • For each thread it also shows the QoS class under the thread name. 

Spindump tool can be used to see which QoS is used to execute particular code. 
usage: sudo spindump -timeline MyApplication

Gives you the history of which QoS was used over the lifetime of the execution of your code. 

When the user is not actively interacting with your application, you want to aim to have 90% of all work to be at Utility or Below.  


4. Do it less:

CPU:  
1% CPU usage causes 10% higher use over idle
10% CPU usage causes 2x power draw over idle
100% CPU usage causes 10x power draw over idle. 

  • CPU use has a huge dynamic range in power.
  • Minitor CPU use with Xcode debug gauge
  • Intruments’ Time Profiler is the best tool to use for monitoring CPU usage. Gives a stack trace breakdown by CPU usage. 
  • Performance Unit Tests can be used to detect Performance/Energy regressions.  

Minimize Timer Use in the application:  to minimize the Fixed cost overhead associated with them.
Timer types:
  • NSTimer
  • CFRunLoopTimer
  • pthread_cod_timedwait()
  • sleep()
  • GCD timers
  • select()
  • CVDisplayLink
  • dispatch_semaphore_wait()

Use the # Wakes tab in the Energy Impact tab to find out how many times the app awoke due to a timer firing on average per second. 

sudo timerfires -p MyApplication -s -g 
Helps see all timer firings inside the app. 

Timer Coalescing:  Groups timer executions together, according to a maximum tolerance you specify.  Examples:
[myTimer setTolerance: 60.0];

CFRunLoopTimerSetTolerance(myTimer, 60.0);

dispatch_source_set_timer(my_timer, DISPATCH_TIME_NOW, 30 * NSEC_PER_SEC, 60 * NSEC_PER_SEC);

This grouping of timer executions improves the fist cost of energy consumption. 
  • Be mindful of wakeup overhead
  • Monitor for wakeups
  • Debug with timefires
  • Specify timer tolerance
Graphics:
  • Avoid extraneous screen updates
  • Unnecessary drawing kicks graphics hardware out of low-power modes
  • Drawing more content than needed causes extra power draw to update the screen
  • Use needsToDrawRect: or getRectsBeingDrawn:count: methods to fine-tune drawing

In Debug options you can enable: “Flash updated regions” to visually see which regions are being updated, to check whether all those updates are necessary. 

If you apply a translucency or blur effect on an element that has other elements behind them that frequently update, this is an expensive graphical operation.  Better to ensure that frequently updated content is not behind any elements that have transparency effects.  (Avoid Blurs on updated content)


Storage:
  • Writes to flash are much more energy hungry than reads
  • Write the minimum content necessary
  • Aggregate the writes for better efficiency. 
  • Any I/O will pull device out of low-power states. 
  • Use caching to your advantage. 


Writing Energy Efficient Code Part 2


Recap: 

The Fixed cost of any resource is due to the fact that the resource stays powered on for a while after performing work, in case its’ needed for more work in a short period of time.  If no work is performed, then the resource is powered back down after a while.   

Trading Power for Energy is generally a concept of Using higher power in a shorter amount of time in order to minimize the Fixed cost of the work performed.  (thus reducing the total energy used) - “Do as much work as you can quicker, minimizing the overall energy used”. 

  • Do it never
    • Stop unnecessary work on app transitions
  • Do it at a better time
    • Scheduling with NSBackgroundActivityScheduler / NSURLSession
  • Do it more efficiently
    • Set appropriate QoS work priority
  • Do it less
    • Coalesce your timers

CPU Monitor:
Throws an exception if over-normal type of CPU usage is observed.
Example:
Exception Type: EXC_RESOURCE
Exception Subtype: CPU_FATAL
Exception Message: (Limit 80%) Observed 89% over 60 seconds. 
Catches “Runaway background usage"
But this won’t catch normal use which is happening in background, in times that it should not be.   

Energy efficient Animations:
Review your Blur usage and reduce frame changes behind blurs. 
Avoid extraneous screen updates. 



Energy Efficient Networking

  • Lots of small calls has the Fixed cost of keeping the radios ON over a period of time  (Overhead costs).   In this case, the overhead cost is very high in proportion to the amount of packets sent. 
  • Not all means of network transfer are the same.  For example: 3G web browsing for example is more expensive than WiFi. 
Conditions affecting network battery use:
  • Celliar vs WiFi 
  • Signal conditions
  • Network throughput

Solution 1:
  • Buffer data together and send as batch.   (Coalesce transactions)

Do it less/never 
  • Reduce media quality
  • Compress data
Avoid redundant transfers
  • Cache data
  • Resumable transactions  (or chunked transfers
Handle errors:
  • Timeout
  • Retry policies
Consider tolerance (doing it at a better time)
  • Understand the requirements - when really is it needed?
  • Consider technology used
  • Check network conditions before sending. 
  • Check data before sending it to make sure something actually changed. 
NSURLSession allows:
  • Pause/Resume
  • Caching with (NSURLCaching)
  • Background Sessions - out of process transactions
NSURLSession Example:
NSURLSessionConfiguration *config = [NSURLSessionConfiguration backgroundSessionConfigurationWithIdentifier: @“com.apple.App.UserRestore”];
[config setAllowsCellularAccess:NO];   // Will only use WiFi - save the user money
[config setDiscretionary: YES];   // Take care of the task at any time within the window
config.timeoutIntervalForResource = 18 * 60 * 60;  // Within the last 18 hours. 
…  Now make the session and task with this config as normal.  

Summary: 
  • Coalesce your transactions
  • Coalesce your transfers
  • Consider tolerance
Measuring Impact:
  • Developer menu on the device now has an Instruments option where you can start recording an energy trace.
  • Then “Import data from device” to load this file .
  • Apps can also force display brightness to maximum. Make sure this is only done when absolutely necessary. 
Sleep:
“To sleep is to prepare for the longer journey ahead”. 
“The longer you allow your devices to sleep, the better the battery life”. 

Background best practices:
Notifications:
Device does wake up in order to send the local notification or push notifications. 
  • With Push Notifications, you can set the push priority.  (10 is default - immediately. 5 - Delivered at a power conservative time). 

VoIP

Previous to iOS 8 was Periodic keep-alive packets causing device wakes, and code complexity. 
As of iOS8 the PushKit framework now allows using the Push Notification service to talk to VoIP apps:
  • No persistent connection required. 
  • app relaunched if terminated
  • include up to 4k payload  (much more than the 256 bytes with regular pushes)
  • app runtime to process the pushes. 

VoIP Push example:
#import <PushKit/PushKit.h>

- (void) voipRegistration {
PKPushRegistry *voipRegistry = [PKPushRegistry alloc] initWithQueue: dispatch_get_main_queue()];
voipRegistry.delegate = self;
voipRegistry.desiredPushTypes = [NSSet setWithObject: PKPushTypeVoip]; // register

}

NOTE: VoIP Background mode needs to be requested for this to work. 

Delegate methods:
  1. Handling push tokens
- (void) pushRegistry:(PKPushRegistry*)registry didUpdatePushCredentials:(PKPushCredentials*)credentials forType:(NSString*)type
{
    // Register push token with server. 
    // There will be a separate token between VoIP and Push notifications. 
}

- (void) pushRegistry:(PKPushRegistry*)registry didReceiveIncomingPushWithPayload:(PKPushPayload*)payload forType:(NSString*)type
{
    // Received push
}

On the server:
  1. Request the VoIP push certificate on the apple portal
  2. iOS8+ only.  

Location Optimizations:
  • Example: Location based restaurant suggestions. 
  • [locationManager startUpdatingLocation] will keep your device ON continuously. 
  • Accuracy affects energy use. (more precise is more energy used)
  • Only use this when necessary, and turn off continuous updates when not needed. 
  • Make sure to Turn OFF location Updates when not needed. 

If you don’t need GPS level accuracy: 
  • locationManager allowDeferredLocationUpdatesUntilTravelled:timeout: 
(Only notifies if you moved a certain distance)  500 meters or 5 minutes for example. 
Example: Weather app. 

Region Monitoring:
  • When entering or exiting a specific location.  
  • Set up a specific region you care about.  App is only woken up when condition is satisfied. 

Significant Locations Visited API

BLE

Peripheral-side buffering can be used to only wake the device when the peripheral’s buffer is full. 
Can also group unrelated transfers into one wakeup occurrence, such as a BLE transfer at the same time that Location entry is satisfied.
Learn how to create your own Programming Language here!!

Sunday, July 12, 2015

Main iOS Architecture and Patterns

Main iOS Architecture and Patterns

The following design patterns are present in many of apple's iOS frameworks:

  1. Target-Action: Can be used to connect a UI control to an implementation of what it does upon being activated by the user.  You can see this pattern in Storyboards when dragging from a control to the code and creating an "Action". Even if your UI classes come from different parents, for example: UIBarButtonItem vs UIButton, they still both use the Target-Action mechanism to handle their pressed events.  The same target-action mechanism is used by gesture recognizers.  A message is also sent along with the action to the target. 

  2. Responder-Chain:  Lets your application handle events without knowing which particular object will handle them. An initiator kicks off an action to the first responder.  That responder may or may not respond to it, or forward it on to the next responder. Typical responder chain (Default view hierarchy):  View-->ViewController-->Window-->Applicastion-->AppDelegate. 

  3.  Composite: Manipulate a group of objects as a single object.  Example: create two views: A and B.  Add B as a subview to A. Now manipulating A will also operate on B, because B is inside A's composite.  Now also B's nextResponder is A, because that is its super view.  UIDynamicBehavior is another place where the same pattern is found: a child behaviour can be added to your dynamicBehavior.  Now the physics simulation running in the background will manipulate the parent dynamicBehavior object as a composite, affecting all nested behaviors inside (nested tree) as one object. 

  4. Delegation: Customize behavior without subclassing the customized object.  For example: UIApplication --> UIApplicationDelegate.   The App Delegate specifies behaviour for various methods of your application.  The app delegate doesn't have to know anything else about the UIApplication.  It only needs to know how to react to 7 application life cycle events.  If you had to override UIApplication instead of receiving it's delegated events, you would have to understand how UIApplication works:  
    1. Which methods must you override?
    2. Which methods are optional?
    3. Do you have to call super on overridden methods?

    4. Other examples of Delegates:
      AVAssetResourceLoader --> AVAssetResourceLoaderDelegate
      CALayer --> CALayerDelegate
      GKSession --> GKSessionDelegate 

  5. Data Source: Customize the data retrieval without having to subclass the object that needs the data.  Example:  UITableView --> UITableViewDataSource.  The tableView asks you for things that it needs from the data source, such as: number of rows, number of sections, view for row, etc.  Other examples: 
    1. UICollectionView --> UICollectionViewDataSource
    2. UIPageViewController --> UIPageViewControllerDataSource
    3. UIPickerView --> UIPickerViewDataSource

  6. Model-View-Controller:  Build organizational structure around application's responsibilities. The model is your business data definition, and possibly functionality related to that particular entity.  The view is your UI which fires events to perform certain actions.  The controller handles the View's actions, reads models, returns data to Views, and does everything else necessary to allow the View to do its job, and update the models accordingly. 
The below steps are a good general process when building a simple application: 

1. The Human Interface Guideline

https://developer.apple.com/library/ios/documentation/UserExperience/Conceptual/MobileHIG/
Should use this as a guide when designing an application. 

2. Application Definition Statement

Important to come up with a focused application statement.  It's a 30 second elevator pitch of exactly what the application is and who it's for.  For example:  "Allow people to share simple, short updates about what is happening in their lives".  The come up with a list of features that are likely to be used.  In this case:  Networked, Lists of data, Good performance, Add an entry, Add photos, Mark items, Edit posts.  Then figure out what to say No to.   So according to our above application statement, we would drop the following 3:  Add photos, Mark items and Edit posts, because they do not fit into the statement. 

3. Come up with simple wire-frames of all screens. 

This will help visualize layout, content, models and ui controls needed.

4. Define Models

Based on the user story statements, pull out the nouns, and that will likely tell you what models will be used. 

5. Define Views

For example:  Use a tableview. Have table view cells with wrappable text fields and images.  Use UIBarButtonItem to display the + button in the Top right, to create an entry. 

6. Define ViewController

Most likely our View Controller will serve as a data source to our table view.  It will also have actions, such as the "add new entry".  In a simple example, VC also has to manage the networking, such as using NSURLConnection, to retrieve model data, and expose it to the views.  However, ideally we don't want the VC to know anything about the networking layer, and instead use a Query object to retrieve the data. 





Saturday, July 11, 2015

Strategies that produce Great Software

Strategies that produce Great Software

based on the Apple WWDC 2014 Video by: Ken Kocienda
  1. When adopting 3rd party controls, try to get a demo as soon as possible.  The ease in adoption of the framework will tell how likely it is to be useful in your project.  Rather than striving for code-complete perfect implementation, make a minimal viable product to demo and throw stones at, so that an understanding of feasibility can be made, and the size of the gap to be bridged.  Know a good idea when you see it by testing the prototype. 

  2. Don't try to solve every single problem right away.  When adopting libraries, you might want to only use the parts you are going to use.  So pull out the parts you want, and only bring those in, rather than using the whole project which you will not use all of.  This process can take time, however, because likely the creator of the Third Party library did not intend this.  Have achievable goals.  For example, when Apple was integrating KHTML to build Safari WebKit for the first time, after integrating everything, only a "Black Obelisk" would show on the screen (black rectangle).   You won't be able to address every point in a huge problem right away.  Just try to get something drawing on the screen. 

  3. Ask for help if you don't feel like you're making sufficient progress.  Are you trying to use an API that is too low level for what you are trying to do?   If that's the case, consider building your own API which does exactly what you are trying to accomplish.  When framing the requirement from a higher abstraction, you will get the benefit of having the code structure organized.  So you may still need to use the low level APIs to get there, but at-least the higher Level API design helps you organize the code with clarity.  In other words if a low level API doesn't serve your purpose, build a higher level API abstraction around it, in order to simplify the interaction with the calling code.  (Facade or Bridge).  Get input from smart colleagues if you are stuck.  They will always have a different perspective. 

  4. It's great to be able to use something that people are aware of, so you don't have to train them. Everyone is familiar with the QWERTY keyboard.  Work should explain itself (by convention). 

  5. Choose the simplest idea which might work.  For example, when you type on a keyboard with Auto-correct, if you make the dictionary look up very fast (O logN), it might make sense to look up every combination of neighbouring letters next to the keys you pressed, and actually look up all those permutation - for any word length.  (Every word on every keystroke)

  6. Only show your best work.  Test out all the ideas, pick the best idea and really test it out. When the time to make the decision comes, you will have all the information to make the best decision.  When you have gone through all this effort, you will have your best work distilled into a Demo which will succeed. 

  7. Can we go faster than the iterative cycle of:  Demo to Designer, Make Changes, Demo Again etc...   Instead we can have "Tunable Values" to reduce iteration time.  This way the designer can make changes on the fly, such as "Make something 2% darker".  Every single value can be polished to perfection by the designer now.  The designer tunes it until he is completely satisfied, then you take the produced slider values and commit that to the code base.  This eliminates all the iterations which would have been needed, if tuning was not in place. Therefore: "Iterating quicker leads to better work". 

  8. Be kind to people, but be honest about their work.  Never raise your voice.  The people are most likely trying very hard to produce good work, but you still have to be honest and up-front about the quality of the work, and let them know that.  They will also not take your feedback personally.  You need to separate yourself from your work emotionally.  If your solution is viewed as that of poor quality, you shouldn't take it personally. It's just an opportunity for improvement.  

  9. You are never "done" in Technology.  It moves fast, and you need to keep up.  Try to do the best possible job at any given time.  Don't dwell too long on something that is pretty good, but rather move on to the next step.  Often times you will have to "Rewrite" your solution completely, while working on it.  This is because of valuable lessons you could have learned during development, or input from colleagues.  This is not a bad thing, rather: an opportunity for improvement and learning.  Technical humility is a great trait to have in this field. 
Learn how to create your own Programming Language here!!

Tuesday, July 7, 2015

What's New in XCode: WWDC 2014 (August)


Major Areas

  1. Swift
  2. Live Design
  3. Visual Debugging
  4. Performance Testing

 Swift Overview

  • A brand new language.  
  • Framework header files are available in Swift syntax.
  • Playgrounds allows executing your code more rapidly, as you are authoring it.
  • QuickHelp shows a short in-line description, at the time you are using auto-complete.
  • When using inferred types, such as "let x = ...", swift can tell you what the inferred type is that will be assigned, by using mouse over on the statement. 
  • Can have .h, .m and .swift files side by side, working together. 

Design Features Overview

  • XCode 6 now allows using storyboards to develop OS10 applications.
  • Using custom fonts will now show up in interface builder on the canvas. 
  • Sprite kit level editor lets us visually assemble scenes. 
  • New way to localize applications:  Export all localizable assets into XLIFF (XML Localization Interchange File Format), which is an industry standard format.  Then import the translated file back into XCode to merge in the localized content into the project.
  • @IBDesignable allows flagging your class for having certain elements show up in IB. 
  • @IBInspectable allows flagging certain variables to be configured and shown in IB. 

Debugging Overview

  • XCode 6 shows how the block got into the stack queue.  In the stack trace that looks like: "Enqueued from com.apple.uikit...." 
  • If you are developing an App Extension, XCode automatically attaches the debugger to your extension when you bring up the notification centre on the device. 
  • New debug instrumentation guages for finding problems in File and Network IO. 
  • View Debugger allows inspecting the view hierarchy to understand why things don't look in the expected fashion.

Performance Overview

  • Instruments has a new UI. 
  • XCode Server gets Trigger support that gives custom behavior to your CI bots.  (Run command line scripts After integration step occurs).  Can run "On Success", "On Test Failures" or "On Build Errors".  
  • Performance test support added to the XCTest framework.   Wrap your code in [self measureBlock:^{ //your code }];     XCode will tell you if the speed of your code has improved or regressed.  
  • "Profile" option from the context menu when right clicking on the test itself allows regenerating profiles for individual tests. 
  • New report that summarizes performance tests. 


Swift Demo (Daniel Dunbar)

  • Module names can now be specified for classes in Interface builder.  So you can use short class names, and avoid naming collisions by using different modules. 
  • Can now define our own modules in our own frameworks, and use them in both Swift and Objective-C.   For example you can put all model code into a "Core" type of module.
  • In Swift, you no longer need to manually import individual headers from a module.  Just import the module itself, and all the public classes will be accessible.   
  • You will get inline auto-complete quick help docs even when using your own classes. 
  • Typed Collection support allows specifying a cast to a type, for example:  " as Game[]" so now the compiler knows that we are dealing with an array of Game objects going forward.
  • iOS8 has a new "separatorEffect" visual property for TableViews.  (Set to a UIVisualEffect)
  • Objective-C Headers are dynamically translated to the Swift syntax on-the-fly, preserving original API comments.
  • Automatic Type inferrence automatically finds the right enumeration type.  So you can just type things like:  .Dark, and it will know which enum to use based on parameter type.  
  • A Header is automatically generated for you in the format:  "ModuleName-Swift.h".   You can import this header into any Objective-C file in order to gain access to all Swift classes within that Module. 
  • Option+Double Click opens Quick Help for any Symbol or Build Setting.  Quick help works across Swift and Objective-C. 

Interface Builder Demo (Jon Hess)

  • Playground shows you values of variables on the right.  Press + on any of the inspected variables in the right pane to bring up a persistent preview of any variable.  Results update immediately as you change the code. 
  • Desaturation effect example:  UIColor(white: 1.0, alpha: 1.0 - 0.3).set()  
  • Option + Click to open any resource in the assistant.  Such as the storyboard. 
  • @IBDesignable indicates that your object should be of specified type at Design type, not just at Run Time.  So in IB, your class will be executed by Interface builder, and look as you intended it to according to your code-behind. 
  • override func prepareForInterfaceBuilder() {  }   can be overridden to make sure that the view is set up to properly show up in IB.  Set up a default image here, or anything you need to do. 
  • @IBInspectable can be applied on member variables, which exposes them as fields in IB that can be set. 
  • In IB you can click on a View, then go "Debug Selected Views", and the related code to draw that View will be called, allowing you to debug into it without running your project from scratch.   
  • New Feature: Universal Storyboards allows to target to both the iPad and iPhone.  To enable:  click on your storyboard, and in the File inspector, enable:  "Use Size Classes". 
  • You can specify which constraints participate for which size classes.
  • You can specify what segues do based on size class.  (For example:  Popover on the iPad, and a Modal on the iPhone). 
  • Preview tool allows viewing how your app will look on multiple screen sizes at the same time.  To activate:  Open the "Enhanced Preview Editor", and select" Preview: Main_iPhone.storyboard, for example.  Then on the bottom press + to add additional device types to the same preview screen. 
  • Size classes can be selected from IB's bottom Bar, that defaults to "Any".  Choose "Regular" to work with the largest size class (iPad).  The bottom bar will turn blue, to remind you that you are editing the design for a specific size class. 
  • Any changes done in IB when selecting a specific size class will only be applied to that size class. 
  • New Aspect Ratio constraint allows to pin the relationship between width and height. 

Debugger Demo (Ken Orr)

  • You can now mouse-over a UIView in the code, and click the QuickLook Icon to see a rendering of that view, to make sure that you are in the right place in the code.  Also works for Mac apps for NSView.
  • - (id) debugQuickLookObject is a new method you can implement on any of your classes.  It will be called by XCode when you initiate QuickLook from the debugger.
  • New "Debug View Hierarchy" button on the bottom.  Shows view snapshots, frames and a visual representation of your views.   Allows inspecting object types and their properties at run time.  
  • When you click on a view in the "Debug View Hierarchy" view, you can also navigate the "Bread-Crumb" on top to see how the view is embedded, and who owns it.  Now you know which area in the code is responsible for drawing any given view you're seeing, without having to guess. 
  • Twist the view sideways in the View Debugger.  
  • The Left slider allows separating views in the hierarchy further.
  • The Right slider allows hiding view from the front to the back, exposing underlying views. 
  • "Show Constraints" button hides all other views, and only shows you the view you selected, and its' constraints. 

Performance Demo (Kate Stone)

  • extension is a new Swift feature (Similar to category), which allows adding methods to a class. 
  • Example:  New File --> Test Case Class --> PerfTests. 
    • By default will contain the following methods:  setUp(), tearDown(), testExample(), testPerformanceExample()
  • testPerformanceExample() contains measureBlock { ... } by default. 
  • Performance test runs a few times to find an average run timing, and consistency of run-to-run timing.  
  • Mouse over the "No baseline..." warning after running the test.  And fill in the Baseline values to establish a baseline for the test. 
  • Right click the test --> "Profile", to launch instruments to profile that specific test only. 
  • Instruments doesn't immediately record anymore.  You can first change the settings now, before you start recording. 
  • Click and drag in the memory chart to filter a range of allocations in the timeline. 
  • Stack trees view in instruments shows a statistical breakdown of allocations by object type. 
  • XCode server gives a dashboard report of tests over time, success/failure history, and device specific results. 

LLVM Compiler - New Features (August 2014)

Here are some notable points from WWDC 2014 "What's new in LLVM" (August, 2014):

  1. 64-Bit iOS Support.  In XCode 6, the "Standard Architectures" build setting now builds for 64 bit architectures by default.    

  2. arm64 is an entirely new architecture.  So the entire application needs to be built for 64 bit support, including all libraries you depend on.  If you use a lot of libraries, you need to work with your vendors to obtain 64 bit versions. 

  3. "Migration Hints" include: Function type checking, Objective-C Bool type, Type size independence.

  4. C Function calls now must have prototypes defined, prior to calling the function. If a call to a C function is made for which no prototype has been defined, the following error results:  "implicit declaration of function 'other_function' is invalid in C99"

  5. New project setting: "Enable Strict Checking of objc_msgSend Calls" = YES is a recommended setting that enforces you to have strict type checking every time objc_msgSend is used.  The proper way to use objc_msgSend is: 

      • typedef void (*send_type)(void *, SEL, int); 
      • send_type func = (send_type)objc_msgSend;
      • func(object, sel_getUid("foo:"), 5);  
    This is done to let the compiler know what the final receiving type is.  (For optimization purposes)

  6. New Objective-C Boolean Type.   Previously, in 32-bit iOS, a bool is a Signed Character.  Now it's a new type:  BOOL ("_Bool").   If boolean variables were having non-boolean values put into them (such as a -1), the result of the calculation with those values will be different between 32-bit and 64-bit architectures.  This is something to watch out for. 

  7. Pointers are now also 64-bit.  So if we have places in the code that cast from a smaller integer type to a new 64-bit pointer, we now get a compiler warning:  "cast to 'void *' from smaller integer type 'int'  for a piece of code like this:   return (void*)i;   (where i is an int).   

  8. The C language typedefs should be used to address this:   
    1. intptr_t, uintptr_t for saving pointers to integers.    
    2. size_t for array indeces.   
    3. ptrdiff_t for pointer differences.   

  9. The long type is 4 bytes on 32-bit iOS, and is 8-bytes in 64-bit iOS. 

  10. Objective-C Modernization Tool:  Scans older legacy code to identify opportunities to use new features that adopt best practices.   Accessible from "Edit --> Refactor --> Modernize...".   Select which targets to modernize.   Then you select what Options to modernise.  It's a good idea to go 1 option at a time, in order to make it more manageable. 
    1. Add attribute annotations: Adds annotations such as: NS_RETURNS_INNER_POINTER 
    2. Atomicity of inferred properties: Scans your classes for getter/setter methods that should be instead encased in properties, and converts them to properties, adding appropriate Interface definition, such as:
    3. - (NSString *)name; 
      - (void)setName:(NSString *)newName; 
      Will be replaced by: 
       @property (nonatomic, copy) NSString *name;
    1. Infer designated initializer methods: Allows you to tell the compiler which is the main designated initializer for the class. This Option scans all your classes, finds and marks your designated initializers for you.  Example:  - (instancetype)initWithName:(NSString *)name NS_DESIGNATED_INITIALIZER;
    2. Infer instancetype for method result type:   Makes our initializers more strongly typed.  You get increased type safety.  For explanation, visit:  http://nshipster.com/instancetype/
    3. Infer protocol conformance: Scans classes and finds if all required methods of a particular protocol are implemented.  If they are, then it will add the protocol conformance line in the Header file.   More descriptive and maintainable. 
    4. Infer readonly properties:  Scans for properties which are only read, and puts the "readonly" modifier on them to make that more explicit. 
    5. Infer readwrite properties
    6. ObjC literals: Shortens your code, replacing things like: [NSNumber numberWithInteger:42] with @42 
    7. ObjC subscripting
    8. Only modify public headers
    9. Use NS_ENUM/NS_OPTIONS macros:  New style Enum macroes that specify the type and size to the compiler.  For example: 
    10. typedef  NS_ENUM(NSInteger, UYLType) 

       UYLTypeDefault, 
       UYLTypeSmall, 
       UYLTypeLarge 
      };

  11. User-Defined Modules:  modern alternatives to precompiled headers, which are more fragile.  They also give you:  Fast Compilation, Clear Semantics and Swift Interoperability. 
    1. You can only have 1 pre-compiled header at a time. 
    2. Precompiled headers are fragile because they can be included more than once in a single compilation, or DEFINEs interfering with each other, messing up the inner workings of the imported framework.  for example:  #define count 100 can break your imported libraries by messing up their internal logic. 
    3. Modules are "semantic import", not "textual inclusion", therefore not fragile. 
    4. To define a module, go to the "Packaging" grouping in your XCode build settings, set "Defines Module" to Yes. 
    5. To import a module:   @import ModuleName;  (Import into another target)
    6. #import <ModuleName/ModuleName.h>  (The compiler is smart enough to realize if the framework being imported is modular, and perform an implicit import, rather than a textual one.  But it's good to update to use @import instead to remove ambiguity). 
    7. Do not expose non-modular imports, such as  #import "Postgres.h", in your API headers. Only do textual imports in the implementation. 
    8. You can still define a Macro on the Command line or in XCode build settings, such as:  "-DDEBUG=1" if you want to affect frameworks which are modular.  (Instead of doing:  "#define DEBUG 1" in the source the old way.)

  12. PGO (Profile Guided Optimization) 
    1. Without optimization, compiler assumes that all inputs to your code are equally likely.  It can't know the most used code paths in order to profile the code.  This feature allows providing a profile to the compiler in order to optimize the execution based on the most-used scenario.  This can result in up to %20 performance boost while running your app. 
    2. An "Instrumented App" is generated as a profile, and specified in your project settings, to guide the compiler to optimize your app for that specific profile.  Optimizations include: 
      1. "Inline more aggressively for 'hot' functions", 
      2. "Lay out most common common code paths contiguously"
      3. "Better register allocation"
      4. Other
    3. To collect a profile:  Product --> Perform Action --> "Generate Optimization Profile" command.  Important to exercise all of the performance-oriented code.  (If you have a game with 3 levels, make sure to play all the levels).  
    4. Build with PGO:   Project Build Settings:  "Use Optimization Profile": "Yes" for the release configuration. 
    5. You have to update your profile after you changed the code quite a bit, because you gradually lose the optimization level.  "Out of date" profile warnings will pop up over time, as you change your code.  
    6. Can use Performance tests to drive the profiling.  But the performance tests should be realistic to how users use your app. 

  13. Vectorization in LLVM
    1. Loop vectorization is a compiler optimization that accelerates loops by providing vector hints to the compiler.  Temp vector variables are used to process more of the workload in parallel. 
    2. Now Analysis of complicated loops have been improved.  More loops can now be vectorized.  Loop vectorizer works together with PGO to make better decisions. 
    3. Improved ARM64 and X86 code generation:  Vectorizer understands the underlying process architecture. ,  Generate better optimized code sequences. 
    4. Specialization of loop values:   Creates a second vectorized version of your loop in which required variables are assumed to allow continuous memory access.  Vectorization is applied to it as normal, and the optimized version of the loop is used if that variable condition is true.  Otherwise, the regular optimized version of the loop is used. 
    5. New kind of vectorizer:  SLP Vectorizer.  (Superworld Level Parallelism:  Parallelism beyond loops).   Glues multiple scalars in your code into vector instructions.   Processes multiple scalars at the same time instead of sequentially.  (Speeds up numerically complex applications). 
    6. In XCode 6: Loop and SLP vectorizers are enabled by default in Release mode. 

  14. Acceleration of Javascript Code.  
    1. WebKit is the heart of the Safari web browser.  
    2. Interpreter executes javascript. 
    3. Two JITs (just in time compilers) accelerate JavaScript.   
    4. Interpreter --> Fast JIT --> Optimizing JIT  --> LLVM JIT (new)
    5. There are trade-offs between quality of code and time spent in the compiler. 
    6. Now LLVM is added to the chain to optimize functions which are run thousands of times.   (Heavy Games for example ported to JavaScript from C++, such as Quake 3)
    7. Javascript is dynamically typed.  WebKit uses statistical evidence of the type used previously and optimize for that type.   Then checks are added to prevent overflows by making assumptions and verifying them.  If the assumptions are broken, fall back to the regular interpreter.  (Only it can handle extreme cases, when type actually changes) 
    8. "On-stack replacement" migrates the state of the program from LLVM back to WebKit, and continue execution in the interpreter. 
    9. Compiling with LLVM is very beneficial for math-intensive applications. 
    10. OS10 and iOS on both 32bit and 64 bit now use LLVM in safari. 
Learn how to create your own Programming Language here!!

Monday, March 16, 2015

Writing Instrumental music based on your influences.

I wrote this tune using Joe Satriani's formula:  using spacious effects and relaxed feel, to give an otherworldly quality, and a rich synth arrangement to showcase the solo electric guitar.  It follows a theme - improv - theme layout, like many instrumental styles, where the middle section deviates from the rhythm, pace and mood of the main themes.  I tried to change it up throughout the tune to keep it progressive, and showcase the interplay between piano and guitar in the mid section.  I believe a piece of music should contain all 3 elements in a strong fashion, which are: Melody, Harmony and Rhythm.





Monday, January 26, 2015

Using an app to organize our band notes


JamCat 

I was in a few bands back in the day.  One was a wedding band that would play a gig every 2 weeks. Things were kind of a mess.   Everyone would have a different set of notes.   People would be missing certain songs in their books.   The notes themselves wound not match from band mate to band mate.   We also never had a song list for a gig, but instead the keyboard player would call out what would be the next song, and then everyone would have to remember what number it was in the book, flip to it, and then switch effects or patches on their instrument...   Sometimes we would have 2 minute breaks in between songs, resulting in audience members calling out "let's go already!!".  Super embarrassing.  I was not able to change how things were done in that band.  But after that experience I became very conscious about having a good way to organize stuff.

I found this site JamCatApp.com thats actually free, that allows creating set lists, and sharing them in our band.  Everyone in the band can edit them at the same time.   We would put the notes for all the songs there, and then post comments on each song, if we had to change something.  Pretty handy.
They also have a nice iOS app that i'm using, which works together with the site.
http://JamCatApp.com

My favorite feature so far has to be the set list creator where you can put notes on everything, and put in fillers in between the sets.

Some iPad screens:






























The website:


The Mobile Startup: Episode 5: Some thoughts about tech, and work.

Knowing that You're Bad! I think that if you have never thought of yourself as a bad engineer before, then you are probably a Bad e...