- Kendall Gelner: @kendalldevdiary
- Visual debugger buttons below view:
- Show Clipped Views
- Show Constraints
- Flex
- Toolbar to view details about views
- Michael Schneider, Hivebrain Software
- Sample cascade classifier code
- Problem: recognize indicators in a Counter Strike radar HUD
- TensorFlow
- OpenCV
- Other choices
- Convolutional neural network: deep learning
- Template matching: match a known image, not good with variance
- Contour matching: matching curves? edge detection
- Cascade classifier: facial recognition. Been around for a long time, runs fast
- Starts with a rough and quick test
- If the image passes, cascades on to the next, more-specific test
- An algorithm may have 30-50 of these stages
- Only detects a face if all stages pass
- Example: does the image have an eye? If yes: does it have a nose? If yes: does it have a mouth? etc
- The gist of how it works:
- Import OpenCV
- Use .mm file extension for Objective-C++
- Load classifier
- Start a video camera from CvVideoCamera, giving it an image view to display in
- Give it a delegate, for camera permissions
processImage:
delegate method called for each frame of the videofilter:
method: boost the red to make it easier to identify red dots in the image
- Caveat: only works on grayscale images
- Edge detection is real easy
- Ultimately took about 20k good and 20k bad images to reliably detect
- Lessons learned
- Smaller images (32x32) train faster
- Steve Scott
- Ben DiFrancesco
- How it works:
- Define a source
- Choose a target language
- Read stream of source characters
- Break characters into language components
- Process instructions in source language
- Generate instructions in target language
- Write and finalize source of target language
- Define a source
- Define a target language
- For our purposes: Swift is the target language
- Read stream of source characters and break into language components
- Tokenization
- Tokens need two pieces of info
- Kind of language element it references
- Original characters from the source
- Token types:
- One type, arbitrary value: like an integer
- Multiple types, specific values: such as keywords like BEGIN or END
- Tokenizer: walks over stream of characters, returns a stream of tokens
- Process instructions in source language: parsing
- Succeed if the program is valid, fail if invalid
- Grammar: definition of set of valid programs
- For simplest Bitsy program:
BEGIN ws {ws} END
- Just a BEGIN, then some whitespace, then an END
- For simplest Bitsy program:
- More complete grammar definition:
Program = BEGIN <block> END
<block> = { <loop> | <break> }
<loop = LOOP <block> END
<break> = BREAK
- Generate instructions in the target language
- Code generation: produce code in the target language that has the same effects as those expressed in the source language
- For example, in the parsing for a loop:
print("while true {")
, then parse the block of the loop, thenprint("}")
- For example, in the parsing for a loop:
- More complex parsing: less literal, more mechanistic. Use token values in code generation.
- Code generation: produce code in the target language that has the same effects as those expressed in the source language
- Chris Risner
- Why the cloud?
- Speed, scale, economics
- Azure app service
- Web apps
- Mobile apps
- DB storage
- User authentication
- Logic
- Push notifications
- Backend jobs
- Slides
- Didn't attend this one
- Basel Farag
- Code and slides
- Didn't attend this one
- Slides
- Didn't attend this one
- Josh Michaels
- "Pop apps killed the indie stars"
- "Pop": a work that appeals to a wide audience
- Pop and indie aren't mutually exclusive
- "Niche": work that appeals to a limited audience
- Consider things that push your audience from pop to niche:
- 60% of people wear glasses: can't use VR headsets
- 40% of people speak English: everyone else can't use your English-only app
- 75-90% of people just won't pay for apps
- Things that will reduce your target market
- Require login/registration
- Require specific OS version
- Require specific hardware features
- Require accessory (like Watch)
- Require specific language
- Require up-front payment
- Gotta be free if you want mass appeal
- Appeal to as wide an audience as possible
- Derek Rozycki and Kirk Chambers, Possible Mobile
- Automation is not the focus of this talk. Discussing QA strategies.
- State diagram: similar to user flow diagram
- Can be the basis for a test plan
- Has nothing to do with development: can develop a QA testing plan from this even before development begins
- Now you've got a happy path
- Deconstructions: state deconstruction, transition deconstruction
- Negative testing: check unexpected input, invalid data from the server, etc
- Repeat tests: users don't launch the app, go to the video section, and tab a button once: they use the app repeatedly
- Don't just test happy path: users will always find a way off the road
- Always do upgrade tests
- Make sure there are no database/data issues
- Ensure no debug options are left in place
- Make sure data, settings, and authentication are retained
- Test different flows into your app
- App icon tap: where does the user land? Is the network available?
- Notification tap
- came back from multitasking chooser
- Deeplink: does it matter where the user came from? What happens to the current state of the app?
- Hardware states: different device sizes and orientations, with each OS you support
- Memory limits
- Permissions, or lack thereof
- Denied by default, granted at runtime
- Can be turned off at any point
- Parental controls allow disabling hardware features: for example, the camera can be disabled entirely. Be careful of assumptions about what hardware can do.
- Your app doesn't live in a vacuum
- For example, in early days, Pokemon Go only worked around midnight because servers were overloaded during daylight hours
- State transitions
- Does the app go from state 1 to state 2 seamlessly?
- What if the app is killed and the API goes from state 1 to state 3 before the app is relaunched? Can it cleanly proceed to state 3?
- Accountability: changes need to be documented. QA can't test requirement changes that happen in a phone call and don't get written down.
- Estimating time needed for QA
- Kind of depends on complexity of the app
- Need to be in early planning to get a sense of how complex development will be, as a way to estimate time needed for QA
- Florian Harr: @evilsx
- Three typical types of mentors
- Life mentor: Dumbledore
- Buddy mentor: Morpheus
- Career mentor: Walter White
- 5 ways to fail as a mentor
- Neglect the relationship
- Eg: go out of town without keeping in touch, that kind of thing
- Make yourself available: email, slack, etc
- Not admitting a mismatch
- Share common morals/ethics
- Mismatch is not your fault
- Help the mentee find a better mentor for them
- Breaking confidentiality
- Provide a safe zone
- Put office politics aside
- Share your perspective
- Don't share what you've discussed
- A break of trust is unforgivable
- Creating a copy of yourself
- Don't impose your will or micromanage
- Your job is to guide and help, not control
- Allow room for mistakes on both sides
- Neglect the relationship
- What could have been done better?
- Set expectations and goals
- Celebrate their achievements
- Clearly communicate possible rewards
- Give feedback regularly
- Give them the benefit of working with you directly
- What's easy for you might not be easy for them
- Offer to include them in everything possible
- Don't restrict it to technology: they'll get the technical aspect, help them master the rest of the job
- Establish a safe zone
- Provide positive reinforcement
- Stay open minded
- Go the extra mile
- Lead by example
- "When you're brave, move your feet" ("when you pray"?)
- Give more than they ask for
- Respect confidentiality as a basic right
- Set expectations and goals
- Mentors inspire us to do what we do
- Proper mentorship:
- Helps retain great talent
- Solves problems in the long term
- Mutually beneficial
- Help business stay vital and fresh
- Summary
- Approach each mentorship differently
- Take a genuine interest in your mentee as a person
- It's not (exclusively) about technology
- Give more than they ask for
- Solve for the long-term
- Lead by example
- Justin Williams
- Code sample and slides
- Framework-first development
- Dynamic frameworks
- Better separation of concerns
- Better testability
- Faster incremental compilation
- Build for all frameworks
- Even if you're not shipping for tvOS or watchOS, you're ready to do so later on
- Use schemes: one per target/platform
- Pre-compiled frameworks
- Dependency management
- CocoaPods, Carthage, or living in the stone age
- Carthage
- Decentralized
- Based off git repos and Xcode projects: no podspec
- Builds dynamic frameworks only
- Semantic Cathaging
- Handy things
- Data parsing & persistence
- Realm
- Easy to adopt
- Native bindings for Swift and Obj-C
- Stable, well documented
- Downside: Swift ABI stability pain, and it's a startup that might go away
- Realm
- Network requests and operations
- Use NSURLSession instead of Alamofire et al
- Result based
- Protocol oriented
- Powered by operation queues
- Use NSURLSession instead of Alamofire et al
- Stephen Tramer: @stramerpdx
- Slides and code
- Warning!
- This talk applies to Swift 3b6
- No stable API
- Swift libraries are about 5mb bigger because they include all the Swift libraries you use
- Bitcode may affect direct calls to Swift
- Preparing for migration
- Heavily annotate Objective-C will nullability modifiers
- Generics:
NSDictionary<NSString *, NSNumber *> *mapCounts;
- Enums: use
NS_ENUM()
andNS_OPTIONS()
- [Lots of more complicated stuff. Kind of spaced.]
- Aaron Douglas: @astralbodies
- Slides
- RxSwift
- Reactive programming
- A pattern surrounding data flows and propagating change
- Example: Excel spreadsheet. If you change a value in a cell, cells that reference it in formulas will update
- Asynchronous data flow
- Functional programming
- Map, reduce filter
- Avoiding state
- Immutable data
- What is RxSwift?
- Based on ReactiveX (originally designed for .NET)
- Ports in many languages
- Extends the observer pattern
- Related to iterable pattern
- Swift provides some protocols with equivalence: SequenceType, GeneratorType
- Observer pattern
- Object notifies its observers when it changes
- Ex: NSNotificationCenter
- Iterator pattern
- Generators and sequences
- RxMarbles
- DisposableBag: can do one for the whole app, but typically use one for each view controller
- Don't need to be all-in: you can update just parts of the app to use Rx
- FRP iOS Learning resources
- Matt Blackmon: @stilgar_black
- Different modes of search
- Discovery: finding something specific ("I want pizza")
- Re-discovery: someone's found something and want to get back to it. Example: Walter's Pizza was good, where was that?
- Index based searching: Spotlight
- Get your content in Spotlight
- Import MobileCoreServices and CoreSpotlight
- Create a
CSSearchableItemAttributeSet
- Set the properties on the attribute set: need at least
title
- Create a
CSSearchableItem
using the attribute set and unique identifiers - Tell Spotlight about it:
CSSearchableIndex.defaultSearchableIndex.indexSearchItems([item])
- Now, the item will appear in the Spotlight results.
- But: only shows a title, and uses the app icon
- Improve the attribute set
thumbnailData
property: use JPG. Appears as icon at left in search results.contentDescription
property: description below the title in the search results. This text is searchable, too.- Title gets a better ranking
- When the user taps a search result
- App delegate:
continueUserActivity
- User activity
activityType
will be "com.apple.corespotlightitem"- Not sure if there's a constant for this, not mentioned in the talk
userActivity.userInfo["kCSSearchableItemActivityIdentifier"]
is the search item title? Seems like it should be the identifier supplied.- Jump to the appropriate part of the app
- App delegate:
- Get your content in Spotlight
- Usage based searching: user navigates to a portion of the app
- Create
NSUserActivity
object with a custom activityType, use reverse DNS to ensure it's custom - Set
title
andeligibleForSearch
properties, optionallykeywords
- Set this object to the
userActivity
property on your view controller- Property is not on UIViewController, it's inherited from UIResponder
- Get some lifecycle benefits: the activity is made active when the view controller appears
activity.becomeCurrent()
: let the system know that this NSUserActivity is the one the user is currently doing- If this happens a lot on an activity, it gets better positioning in search ranking
- Useful for Handoff
- Used for Siri reminders
- Can also set an attribute set on the activity using
contentAttributeSet
property, to set a thumbnail and description - On the attribute set, use the
relatedUniqueIdentifier
property to indicate the unique ID of the searchable item. That way, an item won't appear in search twice if it's both searchable and a user activity- These are now tied together: delete one and both go
- Also tied together for ranking
- Create
- Best option for unique IDs: Universal URL
- Steps to implement universal URLs:
- Build your website
- apple-app-site-association
- Prepare your website
- Use a meta tag: content includes app ID and
app-argument
- Use title tag and OpenGraph description meta tag
- Can include meta tag with
itemprop="ratingValue" value=4
to show rating in the search results - Test in App Search API Validation Tool
- Use a meta tag: content includes app ID and
- Prepare the app
- Associated Domains in Capabilities:
applinks:mydomain.com
- Use the universal URL as the
uniqueIdentifier
on searchable items - Set
webpageURL
on the activity to the universal URL, pluseligibleForPublicIndexing
- Counted as a "vote" for your item as a search result for a search term. Users without your app could start seeing your website as a search result in Spotlight.
- Associated Domains in Capabilities:
- In
continueUserActivity
activityType
will beNSUserActivityTypeBrowsingWeb
- Advice
- Implementation
- When debugging, delete your app often. Don't just re-install. Only by re-installing can you wipe the on-device index. Or, wipe the simulator.
- Check if CoreSpotlight is available on the device before starting to use it. iPad 2 doesn't support it. Check
isIndexingAvailable
- Almost all apps can make use of NSUserActivity
- Consider iOS 10. Added maturity to these APIs.
- Improving rankings
- Add actions for navigation or phone calls if you use them
- Keep your content current. Search index items have an expiration (something like three weeks). Remove items that have been deleted, update items that have changed. Don't index things that shouldn't stick around for a while.
- Don't spam the index: hundreds is good, thousands is maybe OK
- Get to your content fast. It's timed, from touch to the time that the content is shown. Don't show interstitials or ads—just get there fast.
- Implementation
- David Ferrero
- API Mocker