There sure are a lot of "Core" frameworks in iOS, but what do they do for you? Core Foundation is often assumed to just be a C version of the familiar Objective-C objects in Foundation, but wait... what's this CFPlugIn? That sure doesn't have an NS-equivalent. And collections like CFBagRef and CFTreeRef, what are they? What's this CFUUID that Apple says I have to use instead of -[UIDevice uniqueIDentifier]?
That's just the beginning: beyond Core Foundation, there's even more C-only functionality to be had. Core Graphics' CGPDF functions let you draw to and from PDFs, and even parse their notoriously nasty innards. And there are more interesting C-only treats in Core Text, Core Telephony, and others.
In this session, we'll make peace with iOS' C frameworks by getting used to the conventions of allocators, opaque types, run loops, and the toll-free bridge, and tour some of the unique functionality that's only available at this level of the iOS stack.
4. Core Foundation
“Core Foundation is a library with a set of
programming interfaces conceptually derived
from the Objective-C-based Foundation
framework but implemented in the C language.”
Monday, March 19, 12
5. CF Concepts
• Opaque Types
• Naming Conventions
• Memory-management conventions
• Relationship to Foundation ("toll free
bridging")
Monday, March 19, 12
6. Opaque Types
• References (pointers) to structs you cannot
directly access
• Not a “class”, per se. Gives you
implementation hiding but not (much)
polymorphism
• Individual instances are still “objects”
Monday, March 19, 12
7. Naming Conventions
• Opaque type references end in "Ref":
CFArrayRef, CFStringRef, etc.
• Functions that take a type start with that
type's name: CFStringGetLength(),
CFArrayGetObjectAtIndex()
• Functions take target object as first parameter
(sometimes second, as in Create functions)
Monday, March 19, 12
8. Memory Management
• You own or co-own an object by getting a reference
to it by any function with Create or Copy in its name,
or by explicitly calling CFRetain()
• You don't own objects you obtain by calling
functions without these words (e.g., "Get")
• You CFRelease() objects you own and are done with
• Some objects have different cleanup:
AudioQueueDispose(), CGPDFDocumentRelease()
Monday, March 19, 12
9. Toll-Free Bridging
• Many CF opaque types are identical to NS equivalents in
Foundation, and can be cast at zero cost
CFStringRef myCFString = (CFStringRef) myNSString;
NSString *myNSString = (NSString*) myCFString;
• With ARC, use
• __bridge_transfer to give ARC ownership
• __bridge_retained to relieve ARC of ownership
• __bridge to keep ARC out of it.
Monday, March 19, 12
12. /** Get the list of presets for the AUiPodEQ unit as a
CFArrayRef / NSArray of AUPreset structs (note: these
are structs, not NSObjects/ids... use
CFArrayGetValueAtIndex()).
*/
-(CFArrayRef) iPodEQPresets;
Monday, March 19, 12
15. objectAtIndex:
Returns the object located at index.
- (id)objectAtIndex:(NSUInteger)index
CFArrayGetValueAtIndex
Retrieves a value at a given index.
const void * CFArrayGetValueAtIndex (
CFArrayRef theArray,
CFIndex idx
);
Monday, March 19, 12
27. Weird CF Collections
• CFBag — Unordered collection that allows
duplicates (compare to CFSet)
• CFBitVector — Ordered collection of bit values
• CFBinaryHeap — Mutable collection sorted by
a binary search function you provide
• CFTree — Mutable tree-structure collection
Monday, March 19, 12
29. UUID
• “Universally Unique Identifier”
• 128-bit / 16 bytes
• Usually written as hex pattern 8-4-4-12
• Standardized as RFC 4122, et. al.
• Early versions used MAC address and date; newer
versions are based on huge random numbers
Monday, March 19, 12
30. CFUUID
Creating CFUUID Objects
CFUUIDCreate
CFUUIDCreateFromString
CFUUIDCreateFromUUIDBytes
CFUUIDCreateWithBytes
Getting Information About CFUUID Objects
CFUUIDCreateString
CFUUIDGetConstantUUIDWithBytes
CFUUIDGetUUIDBytes
Monday, March 19, 12
32. UUID strength
• 340,282,366,920,938,463,463,374,607,431,768
,211,456 possible UUIDs (16 to the 32nd
power)
• 50% chance of a duplicate UUID if:
• Everyone on Earth had 600 million UUIDs, or
• You generated 1 billion UUIDs every second
for the next 100 years
Monday, March 19, 12
33. UUID and You
• -[UIDevice uniqueIdentifier] is deprecated in
iOS 5
• Guidance from Apple is for apps to use a
CFUUID to uniquely identify an installed
instance.
Monday, March 19, 12
36. CFNetwork
• Non-blocking socket-level APIs (CFSocket,
CFStream)
• Host name resolution
• HTTP/HTTPS/FTP, with authentication
• Bonjour
Monday, March 19, 12
37. Reachability
• Check SCNetworkReachabilityFlags()
to determine if you can reach a given host,
check to see if it's wifi or cellular
(kSCNetworkReachabilityFlagsIsWWAN)
• Register for callbacks with
SCNetworkReachabilitySetCallback()
Monday, March 19, 12
38. Captive Network
• App registers SSIDs of known-friendly wifi
networks with CNSetSupportedSSIDs()
• Login/TOS web sheet will be suppressed for
these wifi hotspots
• App indicates authentication success/failure
with CNMarkPortalOnline()/
CNMarkPortalOffline()
Monday, March 19, 12
43. Core Telephony
• Obj-C framework to be notified of changes in call states
• CTCallStateDialing,
CTCallStateIncoming,
CTCallStateConnected,
CTCallStateDisconnected
• CTCarrier lets you inspect carrier ID, country code,
whether it allows VoIP on its network
• No access to call numbers, call audio, etc.
Monday, March 19, 12
45. CFPlugIn
• API for discovering and implementing
executable code modules at runtime
• Plugin code is packaged as bundles
• iPhone OS 3 had a custom Audio Unit API
based on CFPlugIn
• But it was removed in iOS 4. Uh oh…
Monday, March 19, 12
47. PDF
Abandon all hope ye who parse here…
Monday, March 19, 12
48. Portable Document
Format (PDF)
• Open format, ISO standard
• 9 versions since 1.0 in 1993
• Basically an extensible container format, a
subset of PostScript, and a font-bundling/
replacement system
Monday, March 19, 12
49. CGPDF
• Core Graphics API for:
• Rendering PDF content in Quartz
• Providing a PDF context for Quartz drawing
commands
• Parsing PDF contents
Monday, March 19, 12
50. CGPDFDocument…
• Open PDF doc with URL, then get metadata
with CGPDFDocumentGetVersion,
CGPDFDocumentGetInfo,
CGPDFDocumentGetID,
CGPDFDocumentAllowsPrinting, etc
NSURL *pdfURL = [NSURL fileURLWithPath:pdfPath];
self.pdfDocument = CGPDFDocumentCreateWithURL(
(__bridge CFURLRef) pdfURL);
Monday, March 19, 12
51. CGPDFPage
• From CGPDFDocumentGetPage()
• CGPDFPageGetBoxRect() — gets
rectangles describing important spaces like
physical media area (kCGPDFMediaBox) or
meaningful content (kCGPDFArtBox)
• Metadata in CGPDFPageGetDictionary()
Monday, March 19, 12
54. PDF coordinate system
• PDF coordinate system puts (0,0) at upper
left; increasing Y values go down (similar to
UIKit)
• Need to scale Y by -1.0 and translate prior to
drawing
Monday, March 19, 12
58. Drawing into PDF
• Create a PDF drawing context with
CGPDFContextCreateWithURL()
• Start each page with CGContextStartPage()
• Draw with Quartz as usual
• End pages with CGContextEndPage()
• CFContextRelease() to finish writing to file
Monday, March 19, 12
65. Parsing PDFs is Hard
• Document and pages have metadata
dictionary
• One dictionary item is "Contents", value is a
content stream
• Content stream may be contents, or an array
of content streams
Monday, March 19, 12
66. Content streams
• Content streams contain everything you see
on the page: fonts, graphics, text
• Stream is literally that: a start to end stream of
data and drawing instructions
• Generally no representation of the structure of
the content (paragraphs, lines, words)
Monday, March 19, 12
67. Trivial example: ABC
BT
/F13 12 Tf
288 720 Td
(ABC) Tj
ET
1. Select Helvetica font (/F13)
2. Move to coordinates (288, 720)
3. Stroke characters "ABC"
Monday, March 19, 12
68. Text Operators
• Text state: Tf (font), Tfs (font size), Tc
(character spacing), Tw (word spacing)…
• Text position: Tm (matrix for new position), TD/
Td (next line with offset matrix), …
• Text showing: Tj (show string), TJ (show array
of glyphs)
Monday, March 19, 12
69. Handling the Operators
• Set up a CGPDFScanner with a given content
stream
• Register callback functions for the operators
you want to deal with
• Call CGPDFScannerScan()
Monday, March 19, 12
72. It gets worse!
• You'd think it would be enough to grab content
streams, scan for Tj operators, build up a string.
But…
• The streams and their contents are not
guaranteed to be in reading order (and often
aren't)
• Need to process all the text moving, styling, font
operators just to find where stuff is on the page
Monday, March 19, 12
73. Word to the wise: bail!
• Many third-party PDF frameworks available
(licenses and capabilities vary)
• PSPDFKit
• FastPDFKit
• Foxit
• PDFTron
• etc…
Monday, March 19, 12
74. Or you can plan on
dealing with
• Multiple font types (Type 1, Type 3, TrueType),
composite fonts, CJKV issues, Unicode
mappings, glyphs, glyph metrics…
• Color-space conversions, halftone screens,
transparency/translucency…
• Images, graphics commands (fills, strokes,
etc.)…
Monday, March 19, 12
75. You know, I've learned
something today…
Monday, March 19, 12
76. Takeaways
• C-based frameworks in iOS have a lot of neat
stuff that doesn't exist in Foundation or Cocoa
Touch
• Granted, it also has duplication and dead-
end Carbon legacies
• Look around docs and headers, ask
questions, find stuff
Monday, March 19, 12
77. Questions?
invalidname@gmail.com
@invalidname
http://www.subfurther.com/blog
Monday, March 19, 12