SlideShare a Scribd company logo
Core What?
                       Chris Adamson • @invalidname
                                 CocoaConf
                         Mar 17, 2012 • Chicago, IL




Monday, March 19, 12
Monday, March 19, 12
Core Foundation




Monday, March 19, 12
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
CF Concepts
                • Opaque Types

                • Naming Conventions

                • Memory-management conventions

                • Relationship to Foundation ("toll free
                  bridging")



Monday, March 19, 12
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
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
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
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
TF-Bridged Types
                                         NSArray = CFArray
                                NSMutableArray = CFMutableArray
                                     NSCalendar = CFCalendar
                                 NSCharacterSet = CFCharacterSet
                         NSMutableCharacterSet = CFMutableCharacterSet
                                          NSData = CFData
                                 NSMutableData = CFMutableData
                                          NSDate = CFDate
                                    NSDictionary = CFDictionary
                            NSMutableDictionary = CFMutableDictionary
                                      NSNumber = CFNumber
                                    NSTimer = CFRunLoopTimer
                                           NSSet = CFSet
                                   NSMutableSet = CFMutableSet
                                        NSString = CFString
                                NSMutableString = CFMutableString
                                          NSURL = CFURL
                                    NSTimeZone = CFTimeZone
                                  NSInputStream = CFReadStream
                                 NSOutputStream = CFWriteStream
                              NSAttributedString = CFAttributedString
                        NSMutableAttributedString = CFMutableAttributedString

                               From cocoadev.com
Monday, March 19, 12
So, anyways…




Monday, March 19, 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
UInt32 size = sizeof(iPodEQPresets);
    OSStatus presetsErr = AudioUnitGetProperty(
                              iPodEQUnit,
                              kAudioUnitProperty_FactoryPresets,
                              kAudioUnitScope_Global,
                              0,
                              &iPodEQPresets,
                              &size);




Monday, March 19, 12
Wait, what?




Monday, March 19, 12
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
Monday, March 19, 12
Monday, March 19, 12
Fun with strings




Monday, March 19, 12
//     perform substitutions - strip anything that can't be in an
      //     XML attribute (note for future: if highlights are disappearing,
      //     this is probably why... they'll generate a parsing error and
      //     get thrown away, possibly nuking the whole notes file)

      [cleanedUpString replaceOccurrencesOfString:@"—"
                                       withString:@"--"
      ! ! ! ! ! ! ! ! !                   options:0
                                            range:NSMakeRange(0,
                                               [cleanedUpString length])];

      [cleanedUpString replaceOccurrencesOfString:@"“"
                                       withString:@"""
      ! ! ! ! ! ! ! ! !                   options:0
                                            range:NSMakeRange(0,
                                               [cleanedUpString length])];




Monday, March 19, 12
Monday, March 19, 12
CFStringTransform
              Perform in-place transliteration on a mutable string.

              Boolean CFStringTransform (
                 CFMutableStringRef string,
                 CFRange *range,
                 CFStringRef transform,
                 Boolean reverse
              );




Monday, March 19, 12
Demo




Monday, March 19, 12
CFStringTransform
              Perform in-place transliteration on a mutable string.

              Boolean CFStringTransform (
                 CFMutableStringRef string,
                 CFRange *range,
                 CFStringRef transform,
                 Boolean reverse
              );




Monday, March 19, 12
Transform Identifiers for CFStringTransform
     Constants that identify transforms used with CFStringTransform.

     const             CFStringRef   kCFStringTransformStripCombiningMarks;
     const             CFStringRef   kCFStringTransformToLatin;
     const             CFStringRef   kCFStringTransformFullwidthHalfwidth;
     const             CFStringRef   kCFStringTransformLatinKatakana;
     const             CFStringRef   kCFStringTransformLatinHiragana;
     const             CFStringRef   kCFStringTransformHiraganaKatakana;
     const             CFStringRef   kCFStringTransformMandarinLatin;
     const             CFStringRef   kCFStringTransformLatinHangul;
     const             CFStringRef   kCFStringTransformLatinArabic;
     const             CFStringRef   kCFStringTransformLatinHebrew;
     const             CFStringRef   kCFStringTransformLatinThai;
     const             CFStringRef   kCFStringTransformLatinCyrillic;
     const             CFStringRef   kCFStringTransformLatinGreek;
     const             CFStringRef   kCFStringTransformToXMLHex;
     const             CFStringRef   kCFStringTransformToUnicodeName;
     const             CFStringRef   kCFStringTransformStripDiacritics;

Monday, March 19, 12
ICU Transforms
                • Any-Remove              • Any-Hex

                • Any-Lower, Any-Upper,   • Any-Hex/XML
                  Any-Title
                                          • Any-Accents
                • Any-NFD, Any-NFC,
                  Any-NFKD, Any-NFKC      • Any-Publishing

                • Any-Name                • Fullwidth-Halfwidth

          Or a custom transform following the ICU syntax, see
          http://userguide.icu-project.org/transforms/general
Monday, March 19, 12
ICU Transforms




Monday, March 19, 12
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
Unique IDs




Monday, March 19, 12
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
CFUUID
                  Creating CFUUID Objects
                  CFUUIDCreate
                  CFUUIDCreateFromString
                  CFUUIDCreateFromUUIDBytes
                  CFUUIDCreateWithBytes

                  Getting Information About CFUUID Objects
                  CFUUIDCreateString
                  CFUUIDGetConstantUUIDWithBytes
                  CFUUIDGetUUIDBytes

Monday, March 19, 12
Demo




Monday, March 19, 12
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
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
Monday, March 19, 12
Network Stuff




Monday, March 19, 12
CFNetwork
                • Non-blocking socket-level APIs (CFSocket,
                  CFStream)

                • Host name resolution

                • HTTP/HTTPS/FTP, with authentication

                • Bonjour



Monday, March 19, 12
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
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
Hypothetical CN Use




Monday, March 19, 12
Hypothetical CN Use




Monday, March 19, 12
Hypothetical CN Use




Monday, March 19, 12
Monday, March 19, 12
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
Dead Ends




Monday, March 19, 12
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
Monday, March 19, 12
PDF
                       Abandon all hope ye who parse here…




Monday, March 19, 12
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
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
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
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
Drawing a page
    if (NULL != _currentPDFPage) {
    ! CGContextRef context = UIGraphicsGetCurrentContext();

    !       // background
    !       CGContextSetFillColorWithColor(context,
    !       ! ! ! ! ! ! ! ! [UIColor grayColor].CGColor);
    !       CGContextFillRect(context, self.bounds);

    !       // draw pdf page
    !       CGContextSetFillColorWithColor(context,
    !       ! ! ! ! ! ! ! ! [UIColor whiteColor].CGColor);
    !       CGContextFillRect(context, self.bounds);
    !       CGContextDrawPDFPage(context, _currentPDFPage);
    }

Monday, March 19, 12
Oops.




Monday, March 19, 12
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
-(void) resetTransform {
   ! CGAffineTransform centerToOrigin =
   ! ! CGAffineTransformMakeTranslation(
   ! ! ! ! ! ! ! ! ! ! self.bounds.size.width / 2.0,
   ! ! ! ! ! ! ! ! ! ! self.bounds.size.height / -2.0);
   ! CGAffineTransform flip = CGAffineTransformMakeScale(
   ! ! ! ! ! ! ! ! ! ! 1.0, -1.0);
   ! CGAffineTransform originToCenter =
   ! ! CGAffineTransformInvert(centerToOrigin);
   ! self.pdfTransform = CGAffineTransformConcat(
   ! ! ! ! ! ! ! ! ! ! centerToOrigin, flip);
   ! self.pdfTransform = CGAffineTransformConcat(
   ! ! ! ! ! ! ! ! ! self.pdfTransform, originToCenter);
   ! [self setNeedsDisplay];
   }




Monday, March 19, 12
Draw with transform
    if (NULL != _currentPDFPage) {
    ! CGContextRef context = UIGraphicsGetCurrentContext();

    !       // background
    !       CGContextSetFillColorWithColor(context,
    !       ! ! ! ! ! ! ! ! [UIColor grayColor].CGColor);
    !       CGContextFillRect(context, self.bounds);

    !       // draw pdf page
    !       CGContextSaveGState (context);
    !       CGContextConcatCTM(context, self.pdfTransform);
    !       CGContextSetFillColorWithColor(context,
    !       ! ! ! ! ! ! ! ! [UIColor whiteColor].CGColor);
    !       CGContextFillRect(context, self.bounds);
    !       CGContextDrawPDFPage(context, _currentPDFPage);
    !       CGContextRestoreGState(context);
    }
Monday, March 19, 12
PDF Drawing Demo




Monday, March 19, 12
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
Create PDF Context
       CFMutableDictionaryRef pdfDict =
       ! CFDictionaryCreateMutable(NULL, 0,
       ! ! &kCFTypeDictionaryKeyCallBacks,
       ! ! &kCFTypeDictionaryValueCallBacks);
       CFDictionarySetValue(pdfDict, kCGPDFContextTitle,
       ! ! ! ! ! ! ! ! CFSTR("Exported PDF"));
       CFDictionarySetValue(pdfDict, kCGPDFContextCreator,
       ! ! ! ! ! ! ! ! CFSTR("CocoaConf demo app"));

       CGRect *pageRect = malloc (sizeof (CGRect));
       // TODO: use a box
       *pageRect = CGRectMake (0.0, 0.0, 612.0, 792.0);
       CGContextRef pdfContext = CGPDFContextCreateWithURL(
       ! ! ! ! ! ! ! ! url, pageRect, pdfDict);


Monday, March 19, 12
Draw into PDF context
 CGContextBeginPage (pdfContext, pageRect);
 CGContextDrawPDFPage(pdfContext,
 ! ! ! ! ! ! self.pdfView.currentPDFPage);
 NSString *watermarkString = [NSString
 ! stringWithFormat:@"Created at CocoaConf at %@",
 ! ! [NSDate date]];
 const char* watermarkCString = [watermarkString
 UTF8String];
 NSInteger watermarkLength = [watermarkString length];
 CGContextSelectFont(pdfContext, PDF_EXPORT_FONT_NAME,
 ! ! PDF_EXPORT_FONT_SIZE, kCGEncodingMacRoman);
 CGContextRotateCTM(pdfContext, 0.25 * M_PI);
 CGContextSetFillColorWithColor(pdfContext,
 ! ! ! ! ! ! [UIColor redColor].CGColor);
 CGContextShowTextAtPoint(pdfContext, 300.0, 150.0,
 ! ! ! ! ! ! watermarkCString, watermarkLength);
 CGContextEndPage(pdfContext);
Monday, March 19, 12
Exporting PDF Demo




Monday, March 19, 12
Accessing PDF
                           Contents


                • It can't be that hard, can it?




Monday, March 19, 12
Monday, March 19, 12
Monday, March 19, 12
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
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
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
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
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
void scanContentStream (CGPDFContentStreamRef stream) {
   ! NSLog (@"scanContentStream()");
   ! CGPDFOperatorTableRef operatorTable =
   ! ! ! ! ! ! CGPDFOperatorTableCreate();
   ! CGPDFOperatorTableSetCallback(operatorTable, "TJ",
   ! ! ! ! ! ! contentStreamTJOperatorCallback);
   ! CGPDFOperatorTableSetCallback(operatorTable, "Tj",
   ! ! ! ! ! ! contentStreamTjOperatorCallback);
   ! CGPDFOperatorTableSetCallback(operatorTable, "Td",
   ! ! ! ! ! ! contentStreamTdOperatorCallback);
   ! CGPDFOperatorTableSetCallback(operatorTable, "TD",
   ! ! ! ! ! ! contentStreamTDOperatorCallback);
   ! CGPDFOperatorTableSetCallback(operatorTable, "Tm",
   ! ! ! ! ! ! contentStreamTmOperatorCallback);
   ! CGPDFOperatorTableSetCallback(operatorTable, "T*",
   ! ! ! ! ! ! contentStreamTStarOperatorCallback);
   ! CGPDFScannerRef streamScanner = CGPDFScannerCreate(stream,
   ! ! ! ! ! ! operatorTable, NULL);
   ! NSLog (@"created scanner");
   ! bool scanned = CGPDFScannerScan(streamScanner);
   ! NSLog (@"scan result: %@", scanned ? @"true" : @"false");
   ! CGPDFScannerRelease(streamScanner);
   }
Monday, March 19, 12
A simple(!) Tj operator
                             callback
  void contentStreamTjOperatorCallback (CGPDFScannerRef scanner,
  ! ! ! ! ! ! ! ! ! ! ! ! ! void *info) {
  ! CGPDFStringRef pdfStringToShow;
  ! bool popped = CGPDFScannerPopString(
  ! ! ! ! ! ! ! scanner, &pdfStringToShow);
  ! while (popped) {
  ! ! CFStringRef stringToShow =
  ! ! ! ! CGPDFStringCopyTextString(pdfStringToShow);
  ! ! NSLog (@"contentStreamTjOperatorCallback()[%ld]: %@",
  ! ! ! ! CFStringGetLength(stringToShow), stringToShow);
  ! ! [pageText appendString:stringToShow];
  ! ! CFRelease (stringToShow);
  ! ! popped = CGPDFScannerPopString(scanner,
  ! ! ! ! ! ! ! &pdfStringToShow);
  ! }
  }

Monday, March 19, 12
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
Word to the wise: bail!
                • Many third-party PDF frameworks available
                  (licenses and capabilities vary)

                       • PSPDFKit

                       • FastPDFKit

                       • Foxit

                       • PDFTron

                       • etc…

Monday, March 19, 12
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
You know, I've learned
                        something today…




Monday, March 19, 12
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
Questions?




                       invalidname@gmail.com
                       @invalidname
                       http://www.subfurther.com/blog

Monday, March 19, 12

More Related Content

PDF
EROSについて
PDF
How to write Ruby extensions with Crystal
PPT
Using QString effectively
PDF
JavaScript Language Paradigms
PDF
Start Wrap Episode 11: A New Rope
PDF
04 - Qt Data
PDF
The Ring programming language version 1.7 book - Part 83 of 196
KEY
Object Oriented Programming in js
EROSについて
How to write Ruby extensions with Crystal
Using QString effectively
JavaScript Language Paradigms
Start Wrap Episode 11: A New Rope
04 - Qt Data
The Ring programming language version 1.7 book - Part 83 of 196
Object Oriented Programming in js

What's hot (19)

PDF
An introduction to Rust: the modern programming language to develop safe and ...
PDF
Groovy to infinity and beyond - GR8Conf Europe 2010 - Guillaume Laforge
PDF
Ruby training day1
PDF
Python 如何執行
PDF
Hey! There's OCaml in my Rust!
PDF
Thrfit从入门到精通
PDF
Racing To Win: Using Race Conditions to Build Correct and Concurrent Software
PDF
[Webinar] Scientific Computation and Data Visualization with Ruby
PDF
Blocks & GCD
PDF
Introduce to Rust-A Powerful System Language
PDF
Inheritance
PDF
J S B6 Ref Booklet
PDF
front-end dev
PDF
An Overview Of Standard C++Tr1
KEY
Writing Ruby Extensions
PDF
Infinum iOS Talks #1 - Swift under the hood: Method Dispatching by Vlaho Poluta
PDF
The Kumofs Project and MessagePack-RPC
PDF
ES6 General Introduction
PDF
Perl XS by example
An introduction to Rust: the modern programming language to develop safe and ...
Groovy to infinity and beyond - GR8Conf Europe 2010 - Guillaume Laforge
Ruby training day1
Python 如何執行
Hey! There's OCaml in my Rust!
Thrfit从入门到精通
Racing To Win: Using Race Conditions to Build Correct and Concurrent Software
[Webinar] Scientific Computation and Data Visualization with Ruby
Blocks & GCD
Introduce to Rust-A Powerful System Language
Inheritance
J S B6 Ref Booklet
front-end dev
An Overview Of Standard C++Tr1
Writing Ruby Extensions
Infinum iOS Talks #1 - Swift under the hood: Method Dispatching by Vlaho Poluta
The Kumofs Project and MessagePack-RPC
ES6 General Introduction
Perl XS by example
Ad

Similar to Core What? (20)

ZIP
Cocoa text talk.key
KEY
Agile Iphone Development
PDF
Objective-C A Beginner's Dive (with notes)
PDF
Objective-C A Beginner's Dive
PDF
Session 2 - Objective-C basics
PPTX
Objective c slide I
PDF
오브젝트C(pdf)
PDF
Lecture 04
PDF
The Dark Depths of iOS [CodeMash 2011]
PDF
MacRuby - When objective-c and Ruby meet
PDF
Write native iPhone applications using Eclipse CDT
PDF
iOS Programming Intro
PDF
To Swift 2...and Beyond!
PDF
Louis Loizides iOS Programming Introduction
PDF
Text Layout With Core Text
KEY
iPhone Development Intro
PDF
Assignment1 B 0
KEY
Objective-C Survives
PDF
iPhone for .NET Developers
PPT
Cocoa text talk.key
Agile Iphone Development
Objective-C A Beginner's Dive (with notes)
Objective-C A Beginner's Dive
Session 2 - Objective-C basics
Objective c slide I
오브젝트C(pdf)
Lecture 04
The Dark Depths of iOS [CodeMash 2011]
MacRuby - When objective-c and Ruby meet
Write native iPhone applications using Eclipse CDT
iOS Programming Intro
To Swift 2...and Beyond!
Louis Loizides iOS Programming Introduction
Text Layout With Core Text
iPhone Development Intro
Assignment1 B 0
Objective-C Survives
iPhone for .NET Developers
Ad

More from Chris Adamson (20)

PDF
Whatever Happened to Visual Novel Anime? (AWA/Youmacon 2018)
PDF
Whatever Happened to Visual Novel Anime? (JAFAX 2018)
PDF
Media Frameworks Versus Swift (Swift by Northwest, October 2017)
PDF
Fall Premieres: Media Frameworks in iOS 11, macOS 10.13, and tvOS 11 (CocoaCo...
PDF
CocoaConf Chicago 2017: Media Frameworks and Swift: This Is Fine
PDF
Forward Swift 2017: Media Frameworks and Swift: This Is Fine
PDF
Firebase: Totally Not Parse All Over Again (Unless It Is) (CocoaConf San Jose...
PDF
Building A Streaming Apple TV App (CocoaConf San Jose, Nov 2016)
PDF
Firebase: Totally Not Parse All Over Again (Unless It Is)
PDF
Building A Streaming Apple TV App (CocoaConf DC, Sept 2016)
PDF
Video Killed the Rolex Star (CocoaConf San Jose, November, 2015)
PDF
Video Killed the Rolex Star (CocoaConf Columbus, July 2015)
PDF
Revenge of the 80s: Cut/Copy/Paste, Undo/Redo, and More Big Hits (CocoaConf C...
PDF
Core Image: The Most Fun API You're Not Using, CocoaConf Atlanta, December 2014
PDF
Stupid Video Tricks, CocoaConf Seattle 2014
PDF
Stupid Video Tricks, CocoaConf Las Vegas
PDF
Core Image: The Most Fun API You're Not Using (CocoaConf Columbus 2014)
PDF
Stupid Video Tricks (CocoaConf DC, March 2014)
PDF
Stupid Video Tricks
PDF
Introduction to the Roku SDK
Whatever Happened to Visual Novel Anime? (AWA/Youmacon 2018)
Whatever Happened to Visual Novel Anime? (JAFAX 2018)
Media Frameworks Versus Swift (Swift by Northwest, October 2017)
Fall Premieres: Media Frameworks in iOS 11, macOS 10.13, and tvOS 11 (CocoaCo...
CocoaConf Chicago 2017: Media Frameworks and Swift: This Is Fine
Forward Swift 2017: Media Frameworks and Swift: This Is Fine
Firebase: Totally Not Parse All Over Again (Unless It Is) (CocoaConf San Jose...
Building A Streaming Apple TV App (CocoaConf San Jose, Nov 2016)
Firebase: Totally Not Parse All Over Again (Unless It Is)
Building A Streaming Apple TV App (CocoaConf DC, Sept 2016)
Video Killed the Rolex Star (CocoaConf San Jose, November, 2015)
Video Killed the Rolex Star (CocoaConf Columbus, July 2015)
Revenge of the 80s: Cut/Copy/Paste, Undo/Redo, and More Big Hits (CocoaConf C...
Core Image: The Most Fun API You're Not Using, CocoaConf Atlanta, December 2014
Stupid Video Tricks, CocoaConf Seattle 2014
Stupid Video Tricks, CocoaConf Las Vegas
Core Image: The Most Fun API You're Not Using (CocoaConf Columbus 2014)
Stupid Video Tricks (CocoaConf DC, March 2014)
Stupid Video Tricks
Introduction to the Roku SDK

Recently uploaded (20)

PPTX
KOM of Painting work and Equipment Insulation REV00 update 25-dec.pptx
PDF
Network Security Unit 5.pdf for BCA BBA.
PDF
A comparative study of natural language inference in Swahili using monolingua...
PPTX
TechTalks-8-2019-Service-Management-ITIL-Refresh-ITIL-4-Framework-Supports-Ou...
PDF
A comparative analysis of optical character recognition models for extracting...
PDF
Univ-Connecticut-ChatGPT-Presentaion.pdf
PDF
gpt5_lecture_notes_comprehensive_20250812015547.pdf
PPTX
Machine Learning_overview_presentation.pptx
PDF
Build a system with the filesystem maintained by OSTree @ COSCUP 2025
PDF
NewMind AI Weekly Chronicles - August'25-Week II
PDF
Assigned Numbers - 2025 - Bluetooth® Document
PDF
Encapsulation_ Review paper, used for researhc scholars
PDF
Approach and Philosophy of On baking technology
PPTX
Tartificialntelligence_presentation.pptx
PDF
Unlocking AI with Model Context Protocol (MCP)
PPTX
Programs and apps: productivity, graphics, security and other tools
PPTX
Digital-Transformation-Roadmap-for-Companies.pptx
PPT
Teaching material agriculture food technology
PDF
Empathic Computing: Creating Shared Understanding
PDF
Getting Started with Data Integration: FME Form 101
KOM of Painting work and Equipment Insulation REV00 update 25-dec.pptx
Network Security Unit 5.pdf for BCA BBA.
A comparative study of natural language inference in Swahili using monolingua...
TechTalks-8-2019-Service-Management-ITIL-Refresh-ITIL-4-Framework-Supports-Ou...
A comparative analysis of optical character recognition models for extracting...
Univ-Connecticut-ChatGPT-Presentaion.pdf
gpt5_lecture_notes_comprehensive_20250812015547.pdf
Machine Learning_overview_presentation.pptx
Build a system with the filesystem maintained by OSTree @ COSCUP 2025
NewMind AI Weekly Chronicles - August'25-Week II
Assigned Numbers - 2025 - Bluetooth® Document
Encapsulation_ Review paper, used for researhc scholars
Approach and Philosophy of On baking technology
Tartificialntelligence_presentation.pptx
Unlocking AI with Model Context Protocol (MCP)
Programs and apps: productivity, graphics, security and other tools
Digital-Transformation-Roadmap-for-Companies.pptx
Teaching material agriculture food technology
Empathic Computing: Creating Shared Understanding
Getting Started with Data Integration: FME Form 101

Core What?

  • 1. Core What? Chris Adamson • @invalidname CocoaConf Mar 17, 2012 • Chicago, IL Monday, March 19, 12
  • 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
  • 10. TF-Bridged Types NSArray = CFArray NSMutableArray = CFMutableArray NSCalendar = CFCalendar NSCharacterSet = CFCharacterSet NSMutableCharacterSet = CFMutableCharacterSet NSData = CFData NSMutableData = CFMutableData NSDate = CFDate NSDictionary = CFDictionary NSMutableDictionary = CFMutableDictionary NSNumber = CFNumber NSTimer = CFRunLoopTimer NSSet = CFSet NSMutableSet = CFMutableSet NSString = CFString NSMutableString = CFMutableString NSURL = CFURL NSTimeZone = CFTimeZone NSInputStream = CFReadStream NSOutputStream = CFWriteStream NSAttributedString = CFAttributedString NSMutableAttributedString = CFMutableAttributedString From cocoadev.com 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
  • 13. UInt32 size = sizeof(iPodEQPresets); OSStatus presetsErr = AudioUnitGetProperty( iPodEQUnit, kAudioUnitProperty_FactoryPresets, kAudioUnitScope_Global, 0, &iPodEQPresets, &size); 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
  • 18. Fun with strings Monday, March 19, 12
  • 19. // perform substitutions - strip anything that can't be in an // XML attribute (note for future: if highlights are disappearing, // this is probably why... they'll generate a parsing error and // get thrown away, possibly nuking the whole notes file) [cleanedUpString replaceOccurrencesOfString:@"—" withString:@"--" ! ! ! ! ! ! ! ! ! options:0 range:NSMakeRange(0, [cleanedUpString length])]; [cleanedUpString replaceOccurrencesOfString:@"“" withString:@""" ! ! ! ! ! ! ! ! ! options:0 range:NSMakeRange(0, [cleanedUpString length])]; Monday, March 19, 12
  • 21. CFStringTransform Perform in-place transliteration on a mutable string. Boolean CFStringTransform ( CFMutableStringRef string, CFRange *range, CFStringRef transform, Boolean reverse ); Monday, March 19, 12
  • 23. CFStringTransform Perform in-place transliteration on a mutable string. Boolean CFStringTransform ( CFMutableStringRef string, CFRange *range, CFStringRef transform, Boolean reverse ); Monday, March 19, 12
  • 24. Transform Identifiers for CFStringTransform Constants that identify transforms used with CFStringTransform. const CFStringRef kCFStringTransformStripCombiningMarks; const CFStringRef kCFStringTransformToLatin; const CFStringRef kCFStringTransformFullwidthHalfwidth; const CFStringRef kCFStringTransformLatinKatakana; const CFStringRef kCFStringTransformLatinHiragana; const CFStringRef kCFStringTransformHiraganaKatakana; const CFStringRef kCFStringTransformMandarinLatin; const CFStringRef kCFStringTransformLatinHangul; const CFStringRef kCFStringTransformLatinArabic; const CFStringRef kCFStringTransformLatinHebrew; const CFStringRef kCFStringTransformLatinThai; const CFStringRef kCFStringTransformLatinCyrillic; const CFStringRef kCFStringTransformLatinGreek; const CFStringRef kCFStringTransformToXMLHex; const CFStringRef kCFStringTransformToUnicodeName; const CFStringRef kCFStringTransformStripDiacritics; Monday, March 19, 12
  • 25. ICU Transforms • Any-Remove • Any-Hex • Any-Lower, Any-Upper, • Any-Hex/XML Any-Title • Any-Accents • Any-NFD, Any-NFC, Any-NFKD, Any-NFKC • Any-Publishing • Any-Name • Fullwidth-Halfwidth Or a custom transform following the ICU syntax, see http://userguide.icu-project.org/transforms/general 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
  • 52. Drawing a page if (NULL != _currentPDFPage) { ! CGContextRef context = UIGraphicsGetCurrentContext(); ! // background ! CGContextSetFillColorWithColor(context, ! ! ! ! ! ! ! ! ! [UIColor grayColor].CGColor); ! CGContextFillRect(context, self.bounds); ! // draw pdf page ! CGContextSetFillColorWithColor(context, ! ! ! ! ! ! ! ! ! [UIColor whiteColor].CGColor); ! CGContextFillRect(context, self.bounds); ! CGContextDrawPDFPage(context, _currentPDFPage); } 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
  • 55. -(void) resetTransform { ! CGAffineTransform centerToOrigin = ! ! CGAffineTransformMakeTranslation( ! ! ! ! ! ! ! ! ! ! self.bounds.size.width / 2.0, ! ! ! ! ! ! ! ! ! ! self.bounds.size.height / -2.0); ! CGAffineTransform flip = CGAffineTransformMakeScale( ! ! ! ! ! ! ! ! ! ! 1.0, -1.0); ! CGAffineTransform originToCenter = ! ! CGAffineTransformInvert(centerToOrigin); ! self.pdfTransform = CGAffineTransformConcat( ! ! ! ! ! ! ! ! ! ! centerToOrigin, flip); ! self.pdfTransform = CGAffineTransformConcat( ! ! ! ! ! ! ! ! ! self.pdfTransform, originToCenter); ! [self setNeedsDisplay]; } Monday, March 19, 12
  • 56. Draw with transform if (NULL != _currentPDFPage) { ! CGContextRef context = UIGraphicsGetCurrentContext(); ! // background ! CGContextSetFillColorWithColor(context, ! ! ! ! ! ! ! ! ! [UIColor grayColor].CGColor); ! CGContextFillRect(context, self.bounds); ! // draw pdf page ! CGContextSaveGState (context); ! CGContextConcatCTM(context, self.pdfTransform); ! CGContextSetFillColorWithColor(context, ! ! ! ! ! ! ! ! ! [UIColor whiteColor].CGColor); ! CGContextFillRect(context, self.bounds); ! CGContextDrawPDFPage(context, _currentPDFPage); ! CGContextRestoreGState(context); } Monday, March 19, 12
  • 57. PDF Drawing Demo 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
  • 59. Create PDF Context CFMutableDictionaryRef pdfDict = ! CFDictionaryCreateMutable(NULL, 0, ! ! &kCFTypeDictionaryKeyCallBacks, ! ! &kCFTypeDictionaryValueCallBacks); CFDictionarySetValue(pdfDict, kCGPDFContextTitle, ! ! ! ! ! ! ! ! CFSTR("Exported PDF")); CFDictionarySetValue(pdfDict, kCGPDFContextCreator, ! ! ! ! ! ! ! ! CFSTR("CocoaConf demo app")); CGRect *pageRect = malloc (sizeof (CGRect)); // TODO: use a box *pageRect = CGRectMake (0.0, 0.0, 612.0, 792.0); CGContextRef pdfContext = CGPDFContextCreateWithURL( ! ! ! ! ! ! ! ! url, pageRect, pdfDict); Monday, March 19, 12
  • 60. Draw into PDF context CGContextBeginPage (pdfContext, pageRect); CGContextDrawPDFPage(pdfContext, ! ! ! ! ! ! self.pdfView.currentPDFPage); NSString *watermarkString = [NSString ! stringWithFormat:@"Created at CocoaConf at %@", ! ! [NSDate date]]; const char* watermarkCString = [watermarkString UTF8String]; NSInteger watermarkLength = [watermarkString length]; CGContextSelectFont(pdfContext, PDF_EXPORT_FONT_NAME, ! ! PDF_EXPORT_FONT_SIZE, kCGEncodingMacRoman); CGContextRotateCTM(pdfContext, 0.25 * M_PI); CGContextSetFillColorWithColor(pdfContext, ! ! ! ! ! ! [UIColor redColor].CGColor); CGContextShowTextAtPoint(pdfContext, 300.0, 150.0, ! ! ! ! ! ! watermarkCString, watermarkLength); CGContextEndPage(pdfContext); Monday, March 19, 12
  • 62. Accessing PDF Contents • It can't be that hard, can it? 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
  • 70. void scanContentStream (CGPDFContentStreamRef stream) { ! NSLog (@"scanContentStream()"); ! CGPDFOperatorTableRef operatorTable = ! ! ! ! ! ! CGPDFOperatorTableCreate(); ! CGPDFOperatorTableSetCallback(operatorTable, "TJ", ! ! ! ! ! ! contentStreamTJOperatorCallback); ! CGPDFOperatorTableSetCallback(operatorTable, "Tj", ! ! ! ! ! ! contentStreamTjOperatorCallback); ! CGPDFOperatorTableSetCallback(operatorTable, "Td", ! ! ! ! ! ! contentStreamTdOperatorCallback); ! CGPDFOperatorTableSetCallback(operatorTable, "TD", ! ! ! ! ! ! contentStreamTDOperatorCallback); ! CGPDFOperatorTableSetCallback(operatorTable, "Tm", ! ! ! ! ! ! contentStreamTmOperatorCallback); ! CGPDFOperatorTableSetCallback(operatorTable, "T*", ! ! ! ! ! ! contentStreamTStarOperatorCallback); ! CGPDFScannerRef streamScanner = CGPDFScannerCreate(stream, ! ! ! ! ! ! operatorTable, NULL); ! NSLog (@"created scanner"); ! bool scanned = CGPDFScannerScan(streamScanner); ! NSLog (@"scan result: %@", scanned ? @"true" : @"false"); ! CGPDFScannerRelease(streamScanner); } Monday, March 19, 12
  • 71. A simple(!) Tj operator callback void contentStreamTjOperatorCallback (CGPDFScannerRef scanner, ! ! ! ! ! ! ! ! ! ! ! ! ! void *info) { ! CGPDFStringRef pdfStringToShow; ! bool popped = CGPDFScannerPopString( ! ! ! ! ! ! ! scanner, &pdfStringToShow); ! while (popped) { ! ! CFStringRef stringToShow = ! ! ! ! CGPDFStringCopyTextString(pdfStringToShow); ! ! NSLog (@"contentStreamTjOperatorCallback()[%ld]: %@", ! ! ! ! CFStringGetLength(stringToShow), stringToShow); ! ! [pageText appendString:stringToShow]; ! ! CFRelease (stringToShow); ! ! popped = CGPDFScannerPopString(scanner, ! ! ! ! ! ! ! &pdfStringToShow); ! } } 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