Life as Clay

Archive for January 2012

Tree

leave a comment »

A large red oak fell in our yard last summer…

Written by Clay

January 26, 2012 at 16:21

Cocoa Programming for Mac OS X, 4th Edition: Chapter 3 Challenge

leave a comment »

Howdy. I previously wrote some entries about the solutions to the challenges in the Cocoa Programming book, 3rd Edition, by Aaron Hillegass. The 4th edition is good. Like the first edition, however, I find the description of the challenges to be a little vague.

I think he does that on purpose. The solutions usually are simpler than they appear.

The Chapter 3 challenge is, “NSDateFormatter’s setDateFormat: to customize the format string on the date objects in your LotteryEntry class.”.

Here’s what you do.

  • Look for NSDateFormatter in the Xcode documentation. Once you find it, search for the setDateFormat: method. You’ll find that you have to send a string to the method. Perhaps most useful is a link at the top of the class to the “Data Formatting Guide.” Once there, click to the “Date Formatters” page. Aha… here’s where the good info it.
  • Search again for the method name — but only search on this page — for setDateFormat:. You’ll find examples of the type of string that you can use for the date formatter. Copy one of those strings. It will look something like: @"yyyy-MM-dd 'at' HH:mm" or @"yyyy'-'MM'-'dd'T'HH':'mm':'ss"
  • Open LotteryEntry.m in your editor window and find the - (NSString *)description method implementation.
  • What you’re going to do is to replace the formatting that you entered during the chapter with your new format. Your previous method looked like:
- (NSString *)description
{
NSDateFormatter *df = [[NSDateFormatter alloc] init];
[df setTimeStyle:NSDateFormatterNoStyle];
[df setDateStyle:NSDateFormatterMediumStyle];

NSString *result;
result = [[NSString alloc] initWithFormat:@"%@ = %d and %d",
[df stringFromDate:entryDate],
firstNumber, secondNumber];
return result;
}
  • You want to replace the messages that your sending to your date formatter. Your new method should look like this (with the date string you found):
- (NSString *)description
{
NSDateFormatter *df = [[NSDateFormatter alloc] init];
[df setDateFormat:@"yyyy-MM-dd 'at' HH:mm"];

NSString *result;
result = [[NSString alloc] initWithFormat:@"%@ = %d and %d",
[df stringFromDate:entryDate],
firstNumber, secondNumber];
return result;
}

That’s it! Run your program and look at the log to see the new format. You can browse through the documentation a bit more to learn more about creating custom formats.

Written by Clay

January 25, 2012 at 16:14

Posted in Cocoa, Objective-C, Tutorial

Tagged with , ,

Paperclip, S3 & Delayed Job in Rails on Heroku – Jan 2012

with 2 comments

Edit: I forgot to mention here that with Paperclip 2.4.5 you have to use the ‘paperclip-aws’ gem in order for Paperclip to work with Amazon’s newer ‘aws-sdk’ gem. That is no longer true with Paperclip 2.5.

I followed this good tutorial on how to push paperclip image processing to the background with delayed_job. My Rails app is deployed to Heroku on the cedar stack. I’ve had problems with the NoMethod errors using delayed_job 3.0.0, so I downgraded to 2.1.4. Also using paperclip version 2.4.5. In the end, I found that I could ditch the struct presented in the aforementioned tutorial and just call handle_asynchronously on my reprocessing method. This is what the codes looks like:


class Image < ActiveRecord::Base
  attr_accessible :profile_pic,
                  :caption,
                  :note,
                  :pic_file_name,
                  :pic_content_type,
                  :pic_file_size,
                  :pic_updated_at,
                  :pic,
                  :pic_attributes,
                  :processing
  
  belongs_to :imageable, :polymorphic => true
  
  # Added for paperclip-aws
  def self.s3_config
      @@s3_config ||= YAML.load(ERB.new(File.read("#{Rails.root}/config/s3.yml")).result)[Rails.env]    
  end
  
  has_attached_file :pic,
                    :styles => { 
                      :large => "500x500>",
                      :thumb => "100x100>", 
                      :tiny => "50>x50>", 
                      :smallest => "24>x24>" },   
                      :default_url => '/:attachment/:style/missing.png',               
                      
                      # Added for paperclip-aws
                      :storage => :aws,
                      :s3_permissions => :authenticated_read,
                      :path => "images/:id/:style/:filename",
                      :s3_credentials => {
                        :access_key_id => self.s3_config['access_key_id'],
                        :secret_access_key => self.s3_config['secret_access_key']
                      },
                      :bucket => self.s3_config['bucket'],
                      :s3_protocol => "https"    
                      
  validates_attachment_content_type :pic, :content_type => [ /^image\/(?:jpeg|gif|png)$/, nil ]
  
  # How to implement on Heroku with processing in the background
  # http://madeofcode.com/posts/42-paperclip-s3-delayed-job-in-rails
  
  # cancel post-processing now, and set flag...
     before_pic_post_process do |image|
       if !image.processing && image.pic_changed?
         image.processing = true
         false # halts processing
       end
     end
     
     # call method from after_save that will be processed in the background
     after_save do |image| 
       if image.processing
         processImageJob(image)
       end
     end
     
     def processImageJob(image)
         image.regenerate_styles!
     end
     handle_asynchronously :processImageJob
     
     # generate styles (downloads original first)
     def regenerate_styles!
       self.pic.reprocess! 
       self.processing = false   
       self.save(:validations => false)
     end
     
     # detect if our source file has changed
     def pic_changed?
       self.pic_file_size_changed? || 
       self.pic_file_name_changed? ||
       self.pic_content_type_changed? || 
       self.pic_updated_at_changed?
     end
                      
end

Written by Clay

January 12, 2012 at 14:29

Posted in Code, Rails, Ruby

Tagged with , , , , ,