SlideShare una empresa de Scribd logo
1 de 45
Introduction to
Cocoa
Programming for
Mac OS X
Arthur Clemens
27 May 2008 - Amsterdam
What we are going to create
What are
we going to
make?
What will you learn?

XCode Tools
Interface Builder
Objective-C
How to open and process files:
open dialog, drag on icon, drag on app

Extending classes
Image resizing
Messaging
Saving




27 May 2008 | Introduction to Cocoa | 3
XCode Tools


 http://developer.apple.com/


27 May 2008 | Introduction to Cocoa | 4
New application




27 May 2008 | Introduction to Cocoa | 5
XCode interface




27 May 2008 | Introduction to Cocoa | 6
Interface builder




27 May 2008 | Introduction to Cocoa | 7
Drag and drop the interface




27 May 2008 | Introduction to Cocoa | 8
Create AppController class




                                          “AppController”




27 May 2008 | Introduction to Cocoa | 9
Instantiate AppController




27 May 2008 | Introduction to Cocoa | 10
Adding outlets




27 May 2008 | Introduction to Cocoa | 11
Adding actions




27 May 2008 | Introduction to Cocoa | 12
Setting properties




27 May 2008 | Introduction to Cocoa | 13
Make connections




27 May 2008 | Introduction to Cocoa | 14
Creating files




                                           ctrl-drag

27 May 2008 | Introduction to Cocoa | 15
Testing UI output

AppController.m

- (IBAction)exportImage:(id)sender
{
      NSLog(@quot;export:%@quot;, sender);
}

- (IBAction)updateSliderValue:(id)sender
{
      NSLog(@quot;updateSliderValue:%fquot;, [sender floatValue]);
}




27 May 2008 | Introduction to Cocoa | 16
Availability of UI objects

AppController.m

- (id)init
{
       self = [super init];
if (self) {
       NSLog(@quot;exportButton=%@quot;, exportButton);
    }
returnself;
}

- (void)awakeFromNib
{
      NSLog(@quot;exportButton=%@quot;, exportButton);
}




27 May 2008 | Introduction to Cocoa | 17
Selectors: setting the size textfield

AppController.m

- (void)awakeFromNib
{
[imageSizeText setStringValue:@quot;quot;];
}

- (IBAction)updateSliderValue:(id)sender
{
      [imageSizeText setStringValue:[sender stringValue]];
}




27 May 2008 | Introduction to Cocoa | 18
Objective-C is C with extensions
object instance:
[NSMutableArray alloc]

pointer to object:
NSMutableArray* list;
list = [NSMutableArray alloc];

initialize object:
NSMutableArray* list;
list = [NSMutableArray alloc];
[list init];

shorthand:
NSMutableArray* list = [[NSMutableArray alloc] init];

destroy:
[list release];




27 May 2008 | Introduction to Cocoa | 19
Methods
method that takes an argument:
selector =addObject:
[list addObject:foo];

multiple arguments:
[list insertObject:foo atIndex:5];

selector =insertObject:atIndex:
return values:
int x = [list count];




27 May 2008 | Introduction to Cocoa | 20
Memory management with reference counting
                       allocates memory and returns object with retain count of 1
-alloc
at 0 the object is deallocated and the memory freed
                                     makes a copy of an object, and returns it with retain count of 1
-copy

                                     retain count ++
-retain

                    retain count --
-release
retain count = number of references to the object
                                     decreases the reference count of an object by 1 at some stage in the future
-autorelease

                                     NSMutableArray* list =
                                               [[[NSMutableArray alloc] init] autorelease];

                                     or:
                                     [NSNumber numberWithInt:5];
                                     convenience constructor, see:
                                     + (NSNumber *)numberWithInt:(int)value
Cocoa class methods return autoreleased objects



27 May 2008 | Introduction to Cocoa | 21
Member variables: storing the image file path
AppController.h

@interface AppController : NSObject{
   IBOutlet NSTextField *imageSizeText;
   IBOutlet NSImageView *imageView;
   IBOutlet NSButton *exportButton;
   IBOutlet NSSlider *slider;
       NSString* imageFilePath;
}
- (void)setImageFilePath:(NSString*)newFilePath;

AppController.m

- (void)setImageFilePath:(NSString*)newFilePath
{
       [newFilePath retain];
       [imageFilePath release];
       imageFilePath = newFilePath;
}
- (NSString*)imageFilePath
{
return imageFilePath;
}
- (void)dealloc
{
   [self setImageFilePath:nil];
   [super dealloc];
}
                                                   Very simple rules for memory management in Cocoa
                                                               http://www.stepwise.com/Articles/Technical/2001-03-11.01.html
27 May 2008 | Introduction to Cocoa | 22
Opening an image file in a dialog window
AppController.m

- (IBAction)showOpenPanel:(id)sender
{
    NSOpenPanel *op = [NSOpenPanel openPanel];
    [op beginSheetForDirectory:nil
                  file:nil
                 types:[NSImage imageFileTypes]
            modalForWindow:[NSApp mainWindow]
             modalDelegate:self
            didEndSelector:@selector(openPanelDidEnd:returnCode:contextInfo:)
              contextInfo:nil];
}
- (void)openPanelDidEnd:(NSOpenPanel *)op                            only PNG:
          returnCode:(int)returnCode                                 [NSArray arrayWithObject:@quot;pngquot;]
         contextInfo:(void *)ci                                      PNG and GIF:
{                                                                    [NSArray arrayWithObjects:@quot;pngquot;,@quot;gifquot;,nil]
if (returnCode != NSOKButton) return;
    NSString *path = [op filename];
}

AppController.h

                                                                                    ... and update the NIB file
- (IBAction)showOpenPanel:(id)sender;

27 May 2008 | Introduction to Cocoa | 23
Connecting the menu in IB




27 May 2008 | Introduction to Cocoa | 24
Putting the image into the view
AppController.m

- (BOOL)importImageFromPath:(NSString*)path
{
     NSImage *image = [[[NSImage alloc] initWithContentsOfFile:path] autorelease];
     if (!image) return NO;
     [imageView setImage:image];
     return YES;
}

Update:

- (void)openPanelDidEnd:(NSOpenPanel *)op
           returnCode:(int)returnCode
          contextInfo:(void *)ci
{
   if (returnCode != NSOKButton) return;
   NSString *path = [op filename];
[self importImageFromPath:path];
       [self setImageFilePath:path];
}



27 May 2008 | Introduction to Cocoa | 25
Opening the image file when dragging on app icon
Step 1: add code

AppController.m

- (BOOL)application:(NSApplication *)theApplication
        openFile:(NSString *)path
{
     // do a check on filetype here...
     BOOL result = [self importImageFromPath:path];
     if (!result) return NO;
     [self setImageFilePath:path];
     return YES;
}

Step 2: edit app document types...

Step 3: set the File’s Owner delegate...




27 May 2008 | Introduction to Cocoa | 26
Opening target info




Command-i




    27 May 2008 | Introduction to Cocoa | 27
Set the app delegate in IB




27 May 2008 | Introduction to Cocoa | 28
Drag and drop onto the app window
We need to extend the image view.

Step 1: create a new subclass for
NSImageView: ImageView

Step 2: edit the code

@interface ImageView : NSImageView
{
}




Step 3: drag new .h file onto IB and set view to new subclass...

Step 4: add drag and drop methods...




27 May 2008 | Introduction to Cocoa | 29
Set image view to new subclass in IB




27 May 2008 | Introduction to Cocoa | 30
Drag and drop methods
ImageView.m

@implementation ImageView

#pragma mark Drag and drop

- (NSDragOperation)draggingEntered:(id<NSDraggingInfo>)sender
{
return NSDragOperationLink;
}
- (BOOL)prepareForDragOperation:(id<NSDraggingInfo>)sender
{
returnYES;
}
- (BOOL)performDragOperation:(id<NSDraggingInfo>)sender
{
return YES;
}
- (void)concludeDragOperation:(id<NSDraggingInfo>)sender
{
   [super concludeDragOperation:sender];
}

@end

27 May 2008 | Introduction to Cocoa | 31
Testing: loading an image from the app bundle
Drag image on XCode: Resources




AppController.m

- (void)awakeFromNib
{
   [imageSizeText setStringValue:@quot;quot;];
   NSString* path = [[NSBundle mainBundle] pathForImageResource:@quot;anteprima.com.pngquot;];
   [self importImageFromPath:path];
}



27 May 2008 | Introduction to Cocoa | 32
Show image in real size
Override NSImageView’s drawRect:

ImageView.m

- (void)drawRect:(NSRect)rect
{
   if ([self image]) {

        NSRect imageRect;
        imageRect.origin = NSZeroPoint;
        imageRect.size = [[self image] size];

        NSRect drawRect = imageRect;
        [[self image] drawInRect:drawRect
                   fromRect:imageRect
                  operation:NSCompositeSourceOver
                   fraction:1.0];
    }
}

The image is now oriented bottom left.

27 May 2008 | Introduction to Cocoa | 33
Orient to top left
Flip coordinate system:

ImageView.m

- (BOOL)isFlipped
{
return YES;
}




27 May 2008 | Introduction to Cocoa | 34
Use a transformation to flip the image
Update drawRect in ImageView.m
- (void)drawRect:(NSRect)rect
{
if ([self image]) {

        NSRect imageRect;
        imageRect.origin = NSZeroPoint;
        imageRect.size = [[self image] size];

     NSAffineTransform* transform = [NSAffineTransform transform];
[transform translateXBy:0.0
yBy:1.0 * imageRect.size.height];
     [transform scaleXBy:[zoomFactor floatValue]
               yBy:-[zoomFactor floatValue]];
     [transform concat];

        NSRect drawRect = imageRect;
        [[self image] drawInRect:drawRect
                   fromRect:imageRect
                  operation:NSCompositeSourceOver
                   fraction:1.0];
    }
}
27 May 2008 | Introduction to Cocoa | 35
Store zoom factor in image view
ImageView.h

@interface ImageView : NSImageView {
  NSNumber* zoomFactor;
}

ImageView.m

- (void)setZoomFactor:(NSNumber*)newZoomFactor
{
    [newZoomFactor retain];
    [zoomFactor release];
    zoomFactor = newZoomFactor;
    [self setNeedsDisplay:YES];
}
- (void)dealloc
{
    [self setZoomFactor:nil];
    [super dealloc];
}
- (id)initWithFrame:(NSRect)frame {
    if (![super initWithFrame:frame]) {
return nil;
    }
    [self setZoomFactor:[NSNumber numberWithFloat:1]];
return self;
}

27 May 2008 | Introduction to Cocoa | 36
Connect the slider value to
the image size

Replace updateSliderValue in AppController.m

- (IBAction)updateSliderValue:(id)sender
{
    [imageView setZoomFactor:[sender objectValue]];
}


Update drawRect in ImageView.m

[transform translateXBy:0.0
             yBy:[zoomFactor floatValue] * imageRect.size.height];




27 May 2008 | Introduction to Cocoa | 37
Getting the image size
Using NSNotification messages

ImageView.m

- (void)notifyImageUpdated
{
   [[NSNotificationCenter defaultCenter] postNotificationName:@quot;imageUpdatedquot;
                                   object:[self imageSize]];
}
- (NSValue*)imageSize
{
   NSSize imageSize = [[self image] size];
   imageSize.width *= [zoomFactor floatValue];
   imageSize.height *= [zoomFactor floatValue];
return [NSValue valueWithSize:imageSize];
}

Add to setZoomFactor:

[self notifyImageUpdated];



27 May 2008 | Introduction to Cocoa | 38
Receiving the notification
Add toawakeFromNib inAppController.m
[[NSNotificationCenter defaultCenter] addObserver:self
                          selector:@selector(handleImageUpdated:)
                            name:@quot;imageUpdatedquot;
                           object:nil];

Unsubscribe before AppController is destroyed:

- (void)dealloc
{
   [[NSNotificationCenter defaultCenter] removeObserver:self];
   [self setImageFilePath:nil];
   [super dealloc];
}

Update the text field

- (void)handleImageUpdated:(NSNotification*)note
{
   NSSize size = [[note object] sizeValue];
   [imageSizeText setStringValue:[NSString stringWithFormat:@quot;%.0f x %.0fquot;, size.width, size.height]];
}




27 May 2008 | Introduction to Cocoa | 39
Update the text field when the image is loaded
Override tosetImage inImageView.m
- (void)setImage:(NSImage *)image
{
   [super setImage:image];
   [self notifyImageUpdated];
}




27 May 2008 | Introduction to Cocoa | 40
Update the file path when the image is dragged
Update concludeDragOperation in ImageView.m
- (void)concludeDragOperation:(id <NSDraggingInfo>)sender
{
   [super concludeDragOperation:sender];
   NSPasteboard *pboard = [sender draggingPasteboard];
   NSString* draggedFilePath = nil;
   if ( [[pboard types] containsObject:NSFilenamesPboardType] ) {
       NSArray *files = [pboard propertyListForType:NSFilenamesPboardType];
       draggedFilePath = [files objectAtIndex:0];
   }
   [[NSGraphicsContext currentContext] setImageInterpolation:NSImageInterpolationHigh];
   [[NSNotificationCenter defaultCenter] postNotificationName:@quot;imageDraggedquot; object:draggedFilePath];
}

Register for notifications inAppController.m
[[NSNotificationCenter defaultCenter] addObserver:self
                          selector:@selector(handleImageDragged:)
                            name:@quot;imageDraggedquot;
                           object:nil];

- (void)handleImageDragged:(NSNotification*)note
{
   NSString* imagePath = [note object];
   [self setImageFilePath:imagePath];
}



27 May 2008 | Introduction to Cocoa | 41
Export the image: Categories
Categories are the prototypes of Cocoa.

Extend a class without subclassing
PrettyPrintCategory.h

@interface NSArray (PrettyPrintElements)
- (NSString *)prettyPrintDescription;
@end

PrettyPrintCategory.m

#import quot;PrettyPrintCategory.hquot;

@implementation NSArray (PrettyPrintElements)
- (NSString *)prettyPrintDescription {
   // implementation code here...
}

@end

Create new Cocoa class ImageViewAdditions (m and h files)

27 May 2008 | Introduction to Cocoa | 42
A category on NSImageView
ImageViewAdditions.h

@interface NSImageView (ImageViewAdditions)
- (NSImage*)imageOfSize:(NSSize)size;
@end

ImageViewAdditions.m

@implementation NSImageView (ImageViewAdditions)

- (NSImage*)imageOfSize:(NSSize)size
{
      NSImage* sourceImage = [self image];
      NSRect scaledRect;
      scaledRect.origin = NSZeroPoint;
      scaledRect.size.width = size.width;
      scaledRect.size.height = size.height;
      NSImage* copyOfImage = [[[NSImage alloc] initWithSize:size] autorelease];
      [copyOfImage lockFocus];
      [[NSGraphicsContext currentContext] setImageInterpolation:NSImageInterpolationHigh];
      [sourceImage drawInRect:scaledRect
                                             fromRect:NSZeroRect
                                            operation:NSCompositeSourceOver
                                             fraction:1.0];
      [copyOfImage unlockFocus];
return copyOfImage;
}

@end

27 May 2008 | Introduction to Cocoa | 43
Export the image
In AppController.m:
- (IBAction)exportImage:(id)sender
{
    NSSize size = [[imageView imageSize] sizeValue];
    NSString* path = [self createFilePath:imageFilePath
                         size:size];
NSImage* imageCopy = [imageView imageOfSize:size];
    [self saveImage:imageCopy
           toPath:path];
}

- (NSString*)createFilePath:(NSString*)imageFilePath size:(NSSize)size
{
   NSString *pathExtension = [imageFilePath pathExtension];
   NSString* barePath = [imageFilePath stringByDeletingPathExtension];
return [NSString stringWithFormat:@quot;%@_%.0fx%.0f.pngquot;, barePath, size.width, size.height];
}

- (BOOL)saveImage:(NSImage*)image toPath:(NSString*)path
{
      NSData *imageAsData = [image TIFFRepresentation];
      NSBitmapImageRep *imageRep = [NSBitmapImageRep imageRepWithData:imageAsData];
      NSData* fileData = [imageRep representationUsingType:NSPNGFileType properties:nil];
      NSString* filePath = [path stringByExpandingTildeInPath];
BOOL success = [fileData writeToFile:[path stringByExpandingTildeInPath] atomically:YES];
return YES;
}


27 May 2008 | Introduction to Cocoa | 44
Result




27 May 2008 | Introduction to Cocoa | 45

Más contenido relacionado

Último

Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers:  A Deep Dive into Serverless Spatial Data and FMECloud Frontiers:  A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
Safe Software
 
Why Teams call analytics are critical to your entire business
Why Teams call analytics are critical to your entire businessWhy Teams call analytics are critical to your entire business
Why Teams call analytics are critical to your entire business
panagenda
 
Artificial Intelligence: Facts and Myths
Artificial Intelligence: Facts and MythsArtificial Intelligence: Facts and Myths
Artificial Intelligence: Facts and Myths
Joaquim Jorge
 

Último (20)

Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers:  A Deep Dive into Serverless Spatial Data and FMECloud Frontiers:  A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
 
Polkadot JAM Slides - Token2049 - By Dr. Gavin Wood
Polkadot JAM Slides - Token2049 - By Dr. Gavin WoodPolkadot JAM Slides - Token2049 - By Dr. Gavin Wood
Polkadot JAM Slides - Token2049 - By Dr. Gavin Wood
 
How to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerHow to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected Worker
 
MINDCTI Revenue Release Quarter One 2024
MINDCTI Revenue Release Quarter One 2024MINDCTI Revenue Release Quarter One 2024
MINDCTI Revenue Release Quarter One 2024
 
AWS Community Day CPH - Three problems of Terraform
AWS Community Day CPH - Three problems of TerraformAWS Community Day CPH - Three problems of Terraform
AWS Community Day CPH - Three problems of Terraform
 
2024: Domino Containers - The Next Step. News from the Domino Container commu...
2024: Domino Containers - The Next Step. News from the Domino Container commu...2024: Domino Containers - The Next Step. News from the Domino Container commu...
2024: Domino Containers - The Next Step. News from the Domino Container commu...
 
Strategies for Landing an Oracle DBA Job as a Fresher
Strategies for Landing an Oracle DBA Job as a FresherStrategies for Landing an Oracle DBA Job as a Fresher
Strategies for Landing an Oracle DBA Job as a Fresher
 
Powerful Google developer tools for immediate impact! (2023-24 C)
Powerful Google developer tools for immediate impact! (2023-24 C)Powerful Google developer tools for immediate impact! (2023-24 C)
Powerful Google developer tools for immediate impact! (2023-24 C)
 
presentation ICT roal in 21st century education
presentation ICT roal in 21st century educationpresentation ICT roal in 21st century education
presentation ICT roal in 21st century education
 
Why Teams call analytics are critical to your entire business
Why Teams call analytics are critical to your entire businessWhy Teams call analytics are critical to your entire business
Why Teams call analytics are critical to your entire business
 
Partners Life - Insurer Innovation Award 2024
Partners Life - Insurer Innovation Award 2024Partners Life - Insurer Innovation Award 2024
Partners Life - Insurer Innovation Award 2024
 
Scaling API-first – The story of a global engineering organization
Scaling API-first – The story of a global engineering organizationScaling API-first – The story of a global engineering organization
Scaling API-first – The story of a global engineering organization
 
Automating Google Workspace (GWS) & more with Apps Script
Automating Google Workspace (GWS) & more with Apps ScriptAutomating Google Workspace (GWS) & more with Apps Script
Automating Google Workspace (GWS) & more with Apps Script
 
Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024
Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024
Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024
 
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
 
Artificial Intelligence: Facts and Myths
Artificial Intelligence: Facts and MythsArtificial Intelligence: Facts and Myths
Artificial Intelligence: Facts and Myths
 
Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...
Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...
Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...
 
Boost PC performance: How more available memory can improve productivity
Boost PC performance: How more available memory can improve productivityBoost PC performance: How more available memory can improve productivity
Boost PC performance: How more available memory can improve productivity
 
Top 5 Benefits OF Using Muvi Live Paywall For Live Streams
Top 5 Benefits OF Using Muvi Live Paywall For Live StreamsTop 5 Benefits OF Using Muvi Live Paywall For Live Streams
Top 5 Benefits OF Using Muvi Live Paywall For Live Streams
 
Workshop - Best of Both Worlds_ Combine KG and Vector search for enhanced R...
Workshop - Best of Both Worlds_ Combine  KG and Vector search for  enhanced R...Workshop - Best of Both Worlds_ Combine  KG and Vector search for  enhanced R...
Workshop - Best of Both Worlds_ Combine KG and Vector search for enhanced R...
 

Destacado

How Race, Age and Gender Shape Attitudes Towards Mental Health
How Race, Age and Gender Shape Attitudes Towards Mental HealthHow Race, Age and Gender Shape Attitudes Towards Mental Health
How Race, Age and Gender Shape Attitudes Towards Mental Health
ThinkNow
 
Social Media Marketing Trends 2024 // The Global Indie Insights
Social Media Marketing Trends 2024 // The Global Indie InsightsSocial Media Marketing Trends 2024 // The Global Indie Insights
Social Media Marketing Trends 2024 // The Global Indie Insights
Kurio // The Social Media Age(ncy)
 

Destacado (20)

2024 State of Marketing Report – by Hubspot
2024 State of Marketing Report – by Hubspot2024 State of Marketing Report – by Hubspot
2024 State of Marketing Report – by Hubspot
 
Everything You Need To Know About ChatGPT
Everything You Need To Know About ChatGPTEverything You Need To Know About ChatGPT
Everything You Need To Know About ChatGPT
 
Product Design Trends in 2024 | Teenage Engineerings
Product Design Trends in 2024 | Teenage EngineeringsProduct Design Trends in 2024 | Teenage Engineerings
Product Design Trends in 2024 | Teenage Engineerings
 
How Race, Age and Gender Shape Attitudes Towards Mental Health
How Race, Age and Gender Shape Attitudes Towards Mental HealthHow Race, Age and Gender Shape Attitudes Towards Mental Health
How Race, Age and Gender Shape Attitudes Towards Mental Health
 
AI Trends in Creative Operations 2024 by Artwork Flow.pdf
AI Trends in Creative Operations 2024 by Artwork Flow.pdfAI Trends in Creative Operations 2024 by Artwork Flow.pdf
AI Trends in Creative Operations 2024 by Artwork Flow.pdf
 
Skeleton Culture Code
Skeleton Culture CodeSkeleton Culture Code
Skeleton Culture Code
 
PEPSICO Presentation to CAGNY Conference Feb 2024
PEPSICO Presentation to CAGNY Conference Feb 2024PEPSICO Presentation to CAGNY Conference Feb 2024
PEPSICO Presentation to CAGNY Conference Feb 2024
 
Content Methodology: A Best Practices Report (Webinar)
Content Methodology: A Best Practices Report (Webinar)Content Methodology: A Best Practices Report (Webinar)
Content Methodology: A Best Practices Report (Webinar)
 
How to Prepare For a Successful Job Search for 2024
How to Prepare For a Successful Job Search for 2024How to Prepare For a Successful Job Search for 2024
How to Prepare For a Successful Job Search for 2024
 
Social Media Marketing Trends 2024 // The Global Indie Insights
Social Media Marketing Trends 2024 // The Global Indie InsightsSocial Media Marketing Trends 2024 // The Global Indie Insights
Social Media Marketing Trends 2024 // The Global Indie Insights
 
Trends In Paid Search: Navigating The Digital Landscape In 2024
Trends In Paid Search: Navigating The Digital Landscape In 2024Trends In Paid Search: Navigating The Digital Landscape In 2024
Trends In Paid Search: Navigating The Digital Landscape In 2024
 
5 Public speaking tips from TED - Visualized summary
5 Public speaking tips from TED - Visualized summary5 Public speaking tips from TED - Visualized summary
5 Public speaking tips from TED - Visualized summary
 
ChatGPT and the Future of Work - Clark Boyd
ChatGPT and the Future of Work - Clark Boyd ChatGPT and the Future of Work - Clark Boyd
ChatGPT and the Future of Work - Clark Boyd
 
Getting into the tech field. what next
Getting into the tech field. what next Getting into the tech field. what next
Getting into the tech field. what next
 
Google's Just Not That Into You: Understanding Core Updates & Search Intent
Google's Just Not That Into You: Understanding Core Updates & Search IntentGoogle's Just Not That Into You: Understanding Core Updates & Search Intent
Google's Just Not That Into You: Understanding Core Updates & Search Intent
 
How to have difficult conversations
How to have difficult conversations How to have difficult conversations
How to have difficult conversations
 
Introduction to Data Science
Introduction to Data ScienceIntroduction to Data Science
Introduction to Data Science
 
Time Management & Productivity - Best Practices
Time Management & Productivity -  Best PracticesTime Management & Productivity -  Best Practices
Time Management & Productivity - Best Practices
 
The six step guide to practical project management
The six step guide to practical project managementThe six step guide to practical project management
The six step guide to practical project management
 
Beginners Guide to TikTok for Search - Rachel Pearson - We are Tilt __ Bright...
Beginners Guide to TikTok for Search - Rachel Pearson - We are Tilt __ Bright...Beginners Guide to TikTok for Search - Rachel Pearson - We are Tilt __ Bright...
Beginners Guide to TikTok for Search - Rachel Pearson - We are Tilt __ Bright...
 

Introduction To Cocoa

  • 1. Introduction to Cocoa Programming for Mac OS X Arthur Clemens 27 May 2008 - Amsterdam
  • 2. What we are going to create What are we going to make?
  • 3. What will you learn? XCode Tools Interface Builder Objective-C How to open and process files: open dialog, drag on icon, drag on app Extending classes Image resizing Messaging Saving 27 May 2008 | Introduction to Cocoa | 3
  • 4. XCode Tools  http://developer.apple.com/ 27 May 2008 | Introduction to Cocoa | 4
  • 5. New application 27 May 2008 | Introduction to Cocoa | 5
  • 6. XCode interface 27 May 2008 | Introduction to Cocoa | 6
  • 7. Interface builder 27 May 2008 | Introduction to Cocoa | 7
  • 8. Drag and drop the interface 27 May 2008 | Introduction to Cocoa | 8
  • 9. Create AppController class “AppController” 27 May 2008 | Introduction to Cocoa | 9
  • 10. Instantiate AppController 27 May 2008 | Introduction to Cocoa | 10
  • 11. Adding outlets 27 May 2008 | Introduction to Cocoa | 11
  • 12. Adding actions 27 May 2008 | Introduction to Cocoa | 12
  • 13. Setting properties 27 May 2008 | Introduction to Cocoa | 13
  • 14. Make connections 27 May 2008 | Introduction to Cocoa | 14
  • 15. Creating files ctrl-drag 27 May 2008 | Introduction to Cocoa | 15
  • 16. Testing UI output AppController.m - (IBAction)exportImage:(id)sender { NSLog(@quot;export:%@quot;, sender); } - (IBAction)updateSliderValue:(id)sender { NSLog(@quot;updateSliderValue:%fquot;, [sender floatValue]); } 27 May 2008 | Introduction to Cocoa | 16
  • 17. Availability of UI objects AppController.m - (id)init { self = [super init]; if (self) { NSLog(@quot;exportButton=%@quot;, exportButton); } returnself; } - (void)awakeFromNib { NSLog(@quot;exportButton=%@quot;, exportButton); } 27 May 2008 | Introduction to Cocoa | 17
  • 18. Selectors: setting the size textfield AppController.m - (void)awakeFromNib { [imageSizeText setStringValue:@quot;quot;]; } - (IBAction)updateSliderValue:(id)sender { [imageSizeText setStringValue:[sender stringValue]]; } 27 May 2008 | Introduction to Cocoa | 18
  • 19. Objective-C is C with extensions object instance: [NSMutableArray alloc] pointer to object: NSMutableArray* list; list = [NSMutableArray alloc]; initialize object: NSMutableArray* list; list = [NSMutableArray alloc]; [list init]; shorthand: NSMutableArray* list = [[NSMutableArray alloc] init]; destroy: [list release]; 27 May 2008 | Introduction to Cocoa | 19
  • 20. Methods method that takes an argument: selector =addObject: [list addObject:foo]; multiple arguments: [list insertObject:foo atIndex:5]; selector =insertObject:atIndex: return values: int x = [list count]; 27 May 2008 | Introduction to Cocoa | 20
  • 21. Memory management with reference counting allocates memory and returns object with retain count of 1 -alloc at 0 the object is deallocated and the memory freed makes a copy of an object, and returns it with retain count of 1 -copy retain count ++ -retain retain count -- -release retain count = number of references to the object decreases the reference count of an object by 1 at some stage in the future -autorelease NSMutableArray* list = [[[NSMutableArray alloc] init] autorelease]; or: [NSNumber numberWithInt:5]; convenience constructor, see: + (NSNumber *)numberWithInt:(int)value Cocoa class methods return autoreleased objects 27 May 2008 | Introduction to Cocoa | 21
  • 22. Member variables: storing the image file path AppController.h @interface AppController : NSObject{ IBOutlet NSTextField *imageSizeText; IBOutlet NSImageView *imageView; IBOutlet NSButton *exportButton; IBOutlet NSSlider *slider; NSString* imageFilePath; } - (void)setImageFilePath:(NSString*)newFilePath; AppController.m - (void)setImageFilePath:(NSString*)newFilePath { [newFilePath retain]; [imageFilePath release]; imageFilePath = newFilePath; } - (NSString*)imageFilePath { return imageFilePath; } - (void)dealloc { [self setImageFilePath:nil]; [super dealloc]; } Very simple rules for memory management in Cocoa http://www.stepwise.com/Articles/Technical/2001-03-11.01.html 27 May 2008 | Introduction to Cocoa | 22
  • 23. Opening an image file in a dialog window AppController.m - (IBAction)showOpenPanel:(id)sender { NSOpenPanel *op = [NSOpenPanel openPanel]; [op beginSheetForDirectory:nil file:nil types:[NSImage imageFileTypes] modalForWindow:[NSApp mainWindow] modalDelegate:self didEndSelector:@selector(openPanelDidEnd:returnCode:contextInfo:) contextInfo:nil]; } - (void)openPanelDidEnd:(NSOpenPanel *)op only PNG: returnCode:(int)returnCode [NSArray arrayWithObject:@quot;pngquot;] contextInfo:(void *)ci PNG and GIF: { [NSArray arrayWithObjects:@quot;pngquot;,@quot;gifquot;,nil] if (returnCode != NSOKButton) return; NSString *path = [op filename]; } AppController.h ... and update the NIB file - (IBAction)showOpenPanel:(id)sender; 27 May 2008 | Introduction to Cocoa | 23
  • 24. Connecting the menu in IB 27 May 2008 | Introduction to Cocoa | 24
  • 25. Putting the image into the view AppController.m - (BOOL)importImageFromPath:(NSString*)path { NSImage *image = [[[NSImage alloc] initWithContentsOfFile:path] autorelease]; if (!image) return NO; [imageView setImage:image]; return YES; } Update: - (void)openPanelDidEnd:(NSOpenPanel *)op returnCode:(int)returnCode contextInfo:(void *)ci { if (returnCode != NSOKButton) return; NSString *path = [op filename]; [self importImageFromPath:path]; [self setImageFilePath:path]; } 27 May 2008 | Introduction to Cocoa | 25
  • 26. Opening the image file when dragging on app icon Step 1: add code AppController.m - (BOOL)application:(NSApplication *)theApplication openFile:(NSString *)path { // do a check on filetype here... BOOL result = [self importImageFromPath:path]; if (!result) return NO; [self setImageFilePath:path]; return YES; } Step 2: edit app document types... Step 3: set the File’s Owner delegate... 27 May 2008 | Introduction to Cocoa | 26
  • 27. Opening target info Command-i 27 May 2008 | Introduction to Cocoa | 27
  • 28. Set the app delegate in IB 27 May 2008 | Introduction to Cocoa | 28
  • 29. Drag and drop onto the app window We need to extend the image view. Step 1: create a new subclass for NSImageView: ImageView Step 2: edit the code @interface ImageView : NSImageView { } Step 3: drag new .h file onto IB and set view to new subclass... Step 4: add drag and drop methods... 27 May 2008 | Introduction to Cocoa | 29
  • 30. Set image view to new subclass in IB 27 May 2008 | Introduction to Cocoa | 30
  • 31. Drag and drop methods ImageView.m @implementation ImageView #pragma mark Drag and drop - (NSDragOperation)draggingEntered:(id<NSDraggingInfo>)sender { return NSDragOperationLink; } - (BOOL)prepareForDragOperation:(id<NSDraggingInfo>)sender { returnYES; } - (BOOL)performDragOperation:(id<NSDraggingInfo>)sender { return YES; } - (void)concludeDragOperation:(id<NSDraggingInfo>)sender { [super concludeDragOperation:sender]; } @end 27 May 2008 | Introduction to Cocoa | 31
  • 32. Testing: loading an image from the app bundle Drag image on XCode: Resources AppController.m - (void)awakeFromNib { [imageSizeText setStringValue:@quot;quot;]; NSString* path = [[NSBundle mainBundle] pathForImageResource:@quot;anteprima.com.pngquot;]; [self importImageFromPath:path]; } 27 May 2008 | Introduction to Cocoa | 32
  • 33. Show image in real size Override NSImageView’s drawRect: ImageView.m - (void)drawRect:(NSRect)rect { if ([self image]) { NSRect imageRect; imageRect.origin = NSZeroPoint; imageRect.size = [[self image] size]; NSRect drawRect = imageRect; [[self image] drawInRect:drawRect fromRect:imageRect operation:NSCompositeSourceOver fraction:1.0]; } } The image is now oriented bottom left. 27 May 2008 | Introduction to Cocoa | 33
  • 34. Orient to top left Flip coordinate system: ImageView.m - (BOOL)isFlipped { return YES; } 27 May 2008 | Introduction to Cocoa | 34
  • 35. Use a transformation to flip the image Update drawRect in ImageView.m - (void)drawRect:(NSRect)rect { if ([self image]) { NSRect imageRect; imageRect.origin = NSZeroPoint; imageRect.size = [[self image] size]; NSAffineTransform* transform = [NSAffineTransform transform]; [transform translateXBy:0.0 yBy:1.0 * imageRect.size.height]; [transform scaleXBy:[zoomFactor floatValue] yBy:-[zoomFactor floatValue]]; [transform concat]; NSRect drawRect = imageRect; [[self image] drawInRect:drawRect fromRect:imageRect operation:NSCompositeSourceOver fraction:1.0]; } } 27 May 2008 | Introduction to Cocoa | 35
  • 36. Store zoom factor in image view ImageView.h @interface ImageView : NSImageView { NSNumber* zoomFactor; } ImageView.m - (void)setZoomFactor:(NSNumber*)newZoomFactor { [newZoomFactor retain]; [zoomFactor release]; zoomFactor = newZoomFactor; [self setNeedsDisplay:YES]; } - (void)dealloc { [self setZoomFactor:nil]; [super dealloc]; } - (id)initWithFrame:(NSRect)frame { if (![super initWithFrame:frame]) { return nil; } [self setZoomFactor:[NSNumber numberWithFloat:1]]; return self; } 27 May 2008 | Introduction to Cocoa | 36
  • 37. Connect the slider value to the image size Replace updateSliderValue in AppController.m - (IBAction)updateSliderValue:(id)sender { [imageView setZoomFactor:[sender objectValue]]; } Update drawRect in ImageView.m [transform translateXBy:0.0 yBy:[zoomFactor floatValue] * imageRect.size.height]; 27 May 2008 | Introduction to Cocoa | 37
  • 38. Getting the image size Using NSNotification messages ImageView.m - (void)notifyImageUpdated { [[NSNotificationCenter defaultCenter] postNotificationName:@quot;imageUpdatedquot; object:[self imageSize]]; } - (NSValue*)imageSize { NSSize imageSize = [[self image] size]; imageSize.width *= [zoomFactor floatValue]; imageSize.height *= [zoomFactor floatValue]; return [NSValue valueWithSize:imageSize]; } Add to setZoomFactor: [self notifyImageUpdated]; 27 May 2008 | Introduction to Cocoa | 38
  • 39. Receiving the notification Add toawakeFromNib inAppController.m [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(handleImageUpdated:) name:@quot;imageUpdatedquot; object:nil]; Unsubscribe before AppController is destroyed: - (void)dealloc { [[NSNotificationCenter defaultCenter] removeObserver:self]; [self setImageFilePath:nil]; [super dealloc]; } Update the text field - (void)handleImageUpdated:(NSNotification*)note { NSSize size = [[note object] sizeValue]; [imageSizeText setStringValue:[NSString stringWithFormat:@quot;%.0f x %.0fquot;, size.width, size.height]]; } 27 May 2008 | Introduction to Cocoa | 39
  • 40. Update the text field when the image is loaded Override tosetImage inImageView.m - (void)setImage:(NSImage *)image { [super setImage:image]; [self notifyImageUpdated]; } 27 May 2008 | Introduction to Cocoa | 40
  • 41. Update the file path when the image is dragged Update concludeDragOperation in ImageView.m - (void)concludeDragOperation:(id <NSDraggingInfo>)sender { [super concludeDragOperation:sender]; NSPasteboard *pboard = [sender draggingPasteboard]; NSString* draggedFilePath = nil; if ( [[pboard types] containsObject:NSFilenamesPboardType] ) { NSArray *files = [pboard propertyListForType:NSFilenamesPboardType]; draggedFilePath = [files objectAtIndex:0]; } [[NSGraphicsContext currentContext] setImageInterpolation:NSImageInterpolationHigh]; [[NSNotificationCenter defaultCenter] postNotificationName:@quot;imageDraggedquot; object:draggedFilePath]; } Register for notifications inAppController.m [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(handleImageDragged:) name:@quot;imageDraggedquot; object:nil]; - (void)handleImageDragged:(NSNotification*)note { NSString* imagePath = [note object]; [self setImageFilePath:imagePath]; } 27 May 2008 | Introduction to Cocoa | 41
  • 42. Export the image: Categories Categories are the prototypes of Cocoa. Extend a class without subclassing PrettyPrintCategory.h @interface NSArray (PrettyPrintElements) - (NSString *)prettyPrintDescription; @end PrettyPrintCategory.m #import quot;PrettyPrintCategory.hquot; @implementation NSArray (PrettyPrintElements) - (NSString *)prettyPrintDescription { // implementation code here... } @end Create new Cocoa class ImageViewAdditions (m and h files) 27 May 2008 | Introduction to Cocoa | 42
  • 43. A category on NSImageView ImageViewAdditions.h @interface NSImageView (ImageViewAdditions) - (NSImage*)imageOfSize:(NSSize)size; @end ImageViewAdditions.m @implementation NSImageView (ImageViewAdditions) - (NSImage*)imageOfSize:(NSSize)size { NSImage* sourceImage = [self image]; NSRect scaledRect; scaledRect.origin = NSZeroPoint; scaledRect.size.width = size.width; scaledRect.size.height = size.height; NSImage* copyOfImage = [[[NSImage alloc] initWithSize:size] autorelease]; [copyOfImage lockFocus]; [[NSGraphicsContext currentContext] setImageInterpolation:NSImageInterpolationHigh]; [sourceImage drawInRect:scaledRect fromRect:NSZeroRect operation:NSCompositeSourceOver fraction:1.0]; [copyOfImage unlockFocus]; return copyOfImage; } @end 27 May 2008 | Introduction to Cocoa | 43
  • 44. Export the image In AppController.m: - (IBAction)exportImage:(id)sender { NSSize size = [[imageView imageSize] sizeValue]; NSString* path = [self createFilePath:imageFilePath size:size]; NSImage* imageCopy = [imageView imageOfSize:size]; [self saveImage:imageCopy toPath:path]; } - (NSString*)createFilePath:(NSString*)imageFilePath size:(NSSize)size { NSString *pathExtension = [imageFilePath pathExtension]; NSString* barePath = [imageFilePath stringByDeletingPathExtension]; return [NSString stringWithFormat:@quot;%@_%.0fx%.0f.pngquot;, barePath, size.width, size.height]; } - (BOOL)saveImage:(NSImage*)image toPath:(NSString*)path { NSData *imageAsData = [image TIFFRepresentation]; NSBitmapImageRep *imageRep = [NSBitmapImageRep imageRepWithData:imageAsData]; NSData* fileData = [imageRep representationUsingType:NSPNGFileType properties:nil]; NSString* filePath = [path stringByExpandingTildeInPath]; BOOL success = [fileData writeToFile:[path stringByExpandingTildeInPath] atomically:YES]; return YES; } 27 May 2008 | Introduction to Cocoa | 44
  • 45. Result 27 May 2008 | Introduction to Cocoa | 45