Sending an iCal as attachment in rails 3
Sending iCal files in rails can sometimes be a pain. The trick is to set the mime type for the attachment and all should be fine.
In the example below the “calendar_entry” variable is a reference to the class that is used to build up the iCal. Now you can use something like icalendar which is what l have used as well.
All you need to do is set the mime type as below and set the content as below as well.
attachments["meeting.ics"] = {:mime_type => 'text/calendar;,
:content => calendar_entry.to_ical}
The to_ical method will return the ical object. I dont recommend reading in a file like below as that tends to write the ical out and some mail clients dont like it
:content => File.read("public/#{@entry.id}.ics")}
Generating PDF documents programmatically in iOS
In some apps there might come a time where you will need to generate your own documents on the fly and be able to export them to the user, either to preview, email or to save the document on the device for later use.
The UIKit framework in iOS provides a easy way to create a graphics context which allows you to generate a PDF file or PDF data object. You should then be able to create extra pages and draw them into the pdf context. Here is how you can start creating your own PDF document.
Setup of PDF Context
So what we first do is setup file name for the file.
NSArray* documentDirectories = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask,YES); NSString* documentDirectory = [documentDirectories objectAtIndex:0]; NSString *pdfFileName = [documentDirectory stringByAppendingPathComponent:@"mypdf.pdf"];
Once that is done, we can start the graphics context to file and return the context reference so that we can render to it.
UIGraphicsBeginPDFContextToFile(pdfFileName, CGRectZero, nil); CGContextRef context = UIGraphicsGetCurrentContext();
Before we can start drawing anything, we need to mark the beginning of a new page. When you are finished drawing on a page and need to start a new page, just call the same line and reset your offset back to 0 again.
UIGraphicsBeginPDFPageWithInfo(CGRectMake(0, 0, 612, 792), nil);
If you are going to generate data that could possibly go over multiple pages, I would recommend to setup a pageOffset before creating a page. You can use this to calculate if you have reached the end of a page, so that you can create a new PDF page context.
CGFloat pageOffset = 0;
Drawing to the PDF Page.
Drawing objects to a PDF page is easy, below are some examples of what you can draw.
Text
NSString *myString = @"My PDF Heading"; [myString drawInRect:CGRectMake(20, pageOffset, 200, 34) withFont:[UIFont fontWithName:@"HelveticaNeue-Bold" size:13] lineBreakMode:UILineBreakModeWordWrap alignment:UITextAlignmentLeft];
Image
UIImage *myImage = [UIImage imageNamed:@"logo.png"]; [myImage drawInRect:CGRectMake(20, pageOffset, myImage.size.width, myImage.size.height)];
Link
Besides drawing graphics content, you can also setup a link which can direct a user to another page in the PDF or to an external file or URL.
To create a simple link, you will need to setup a link and a destination. Below we setup firstly a destination, then a link which goes back to that destination inside the current PDF file.
UIGraphicsAddPDFContextDestinationAtPoint(@"Chapter1", CGPointMake(0, 0)); UIGraphicsSetPDFContextDestinationForRect(@"Chapter1", CGRectMake(50, 50, 200, 44));
If you would like to create a link to an external URL, you can use the following.
UIGraphicsSetPDFContextURLForRect(<#NSURL *url#>, <#CGRect rect#>);
Finishing the PDF and exporting the data
Once you have finished creating your PDF you must first remove the PDF rendering context.
UIGraphicsEndPDFContext();
Now you have access to use the PDF and export it how you wish. To access the file to attach it in the MFMailComposeViewController, you can do the following.
[mailComposer addAttachmentData:[NSData dataWithContentsOfFile:pdfFileName] mimeType:@"application/pdf" fileName:@"myGeneratedPDF.pdf"];
If you would like to know more about PDF rendering, you can refer to the Apple docs on
Generating PDF Content.
Using Concerns in Ruby on Rails Development
Concerns are a great way to mix in common model behaviours and keep your code clean and not have to resort to STI.
So lets take a look at what a concern looks like. Below l have a Module called “Auditable” which extens ActiveSupport Concern.
The purpose of this is to record statistics on objects as they are created and destroyed. Now this comes in handy when you want to analyse how your customers are using your ruby on rails application.
module Auditable
extend ActiveSupport::Concern
included do
has_many :audits, as: :auditable
after_create :record_creation
before_destroy :record_deletion
end
def record_creation
Audit.record_created(self)
end
def record_deletion
Audit.record_deletion(self)
end
end
That module gives any Active Recored model that includes it the instant ability to track when its deleted or created via a Audit record which you can see Auditable can have many of. Anything included in the include block below acts on the model the same as if you where to call has_many or validates within the model itself
included do // Declarations go here end
The last step is to include the concern in your model like so
include Auditable
Now some people say you have to load the folder app in application.rb, this is not the case if you store your concerns like we do under “app/concerns”. This keeps them in the right place and also does not require you to specify them in the app.rb file
Doccy is about to launch. Simplest way to create documents
We have been working away on a new service launching soon called Doccy. It turns all your old documents into powerful templates that you can then use to build documents in less then a minute.
We support all your favourite formats just as Word (.docx), Pages and Open Office.
Now we are expecting to launch come early jan but in the mean time head over to http://www.doccyapp.com to subscribe and kept informed of when we do.
What Click Frenzy did wrong
I have never really been one to comment on other peoples work but there are a few things l need to get off my chest relating to development.
Now l am not saying l get it right all the time every time hell no we all make mistakes. But there have been a few obvious ones made with the launch of the new deals site “Click Frenzy”. Now l was like everyone else and registered to see what its all about and a few things poped out at me that really l would have thought would have been addressed but there is one that l hate and well this should be a standard on the web
1. WWW Redirect. Go to your browser and type in clickfrenzy.com.au without the www and see what happens, ill give you a hint nothing.

The server was not setup to redirect to www.clickfrenzy.com.au or at least point to site. Now its a good practice l am told by the company behind our SEO Web Marketers Crew that your site should really work of either www or no www i.e should redirect to one of them from the other if need be for SEO reasons. You can read this google article here for more info on doing this.
So yes this is my pet hate and l cant stand sites that dont do this as l dont type the www as l see it as pointless but hey thats just one mans opinion on the matter
Facebook style sidemenu from scratch with Rubymotion
In the process of developing our little internal game using RubyMotion we ran into an issue using the pod MFSideMenu and the RubyMotion framework so we decided to write our own and here is what we came up with.
We created a Menu Manager class to handle the instance of the menu and its actions such as the slide in and out. It also has the nice shadow affect on it as well
class MenuManager
attr_accessor :navigationController, :menu, :visible
SHADOW_WIDTH = 10.0
@@instance = nil
#Used to simply maintain state of sidemenu
@@visible = false
def self.instance
return @@instance unless @@instance.nil?
@navigationController = UINavigationController.alloc.initWithRootViewController(DashboardController.build)
@navigationController.navigationBar.tintColor = UIColor.colorWithRed 168.0/255, green: 15.0/255, blue: 17.0/255, alpha: 1.0
@menu = SideMenuController.build
@@instance = MenuManager.new(@navigationController, @menu)
@@instance
end
def initialize(navigationController, menuController)
@navigationController = navigationController
@menu = menuController
end
def setupMenuView
self.navigationController.view.superview.insertSubview(self.menu.view, belowSubview: self.navigationController.view)
pathRect = self.navigationController.view.bounds
pathRect.size.width = SHADOW_WIDTH
self.navigationController.view.layer.shadowPath = UIBezierPath.bezierPathWithRect(pathRect).CGPath
self.navigationController.view.layer.shadowOpacity = 0.75
self.navigationController.view.layer.shadowRadius = SHADOW_WIDTH
self.navigationController.view.layer.shadowColor = UIColor.blackColor.CGColor
end
def toggleMenuState
destination = self.navigationController.view.frame
if destination.origin.x > 0
destination.origin.x = 0
@visible = false
else
destination.origin.x += 254.5
@visible = true
end
UIView.animateWithDuration 0.25,
animations: -> { self.navigationController.view.frame = destination}
navigationController.visibleViewController.view.userInteractionEnabled = !(destination.origin.x > 0)
end
def self.menuButton(target, action)
menuBarButtonItem = UIBarButtonItem.alloc.initWithImage(UIImage.imageNamed("navBar/menu-icon.png"),
style: UIBarButtonItemStyleBordered,
target: target,
action: "#{action}")
return menuBarButtonItem
end
end
You will also need a UITableViewController which is the actual view seen by the user. No in our case we have hard coded this controller but if we were to make this into a gem we would extract that as params passed in of course but you get the idea.
class SideMenuController < UITableViewController
def self.build
@controller ||= alloc.initWithNibName(nil, bundle: nil)
end
def viewDidLoad
super
@controllers = [ProfileController.build,
DashboardController.build,
LeaderboardController.build,
GuideController.build,
OptionsController.build,
StoreController.build]
@labels = ["Profile", "Dashboard", "Leaderboard", "How to Play", "Options", "Store"]
tableView.separatorStyle = UITableViewCellSeparatorStyleNone
tableView.backgroundColor = UIColor.clearColor
tableView.backgroundView = UIImageView.alloc.initWithImage(UIImage.imageNamed("menu/bg.png"))
#Need to set this dynamically to handle the first cell being larger then the rest
tableView.rowHeight = 50
end
def tableView(tableView, heightForRowAtIndexPath: indexPath)
if (indexPath.row == 0)
height = 80
else
height = 50
end
return height
end
def tableView(tableView, cellForRowAtIndexPath: indexPath)
@reuseIdentifier ||= "MenuCell"
cell = tableView.dequeueReusableCellWithIdentifier(@reuseIdentifier) ||
UITableViewCell.alloc.initWithStyle(UITableViewCellStyleDefault, reuseIdentifier: @reuseIdentifier)
if (indexPath.row == 0)
height = 50
else
height = 10
end
bg = UIImageView.alloc.initWithFrame(CGRectZero)
# cell.setBackgroundView.image = UIImage.imageNamed("awardbg.png")
#Stop blue appearing when selecting cell
# cell.setSelectionStyle(UITableViewCellSelectionStyleNone)
label = LabelFactory.makeLabel([[80, height], [150.0, 30.0]],
text: @labels[indexPath.row],
font: DesignFactory.fontSaturator(20.0),
align: UITextAlignmentLeft,
color: UIColor.whiteColor)
cell.contentView.addSubview label
return cell
end
def tableView(tableView, numberOfSectionsInTableView: sections)
return 1
end
def tableView(tableView, numberOfRowsInSection: section)
return @controllers.length
end
def tableView(tableView, didSelectRowAtIndexPath:indexPath)
menuManager = MenuManager.instance
#Return only the controller we want to display but needs to be in array
menuManager.navigationController.viewControllers = [@controllers[indexPath.row]]
menuManager.toggleMenuState
end
end
Now all thats left to do is set it up in the app delegate like so
menuManager = MenuManager.instance
@window.rootViewController = menuManager.navigationController
#Need to call this here for MenuManager to know about the UIView
@window.makeKeyAndVisible
#Need to call this here for now till we start passing through the @window to MenuManager
menuManager.setupMenuView
You might notice we have a call to a class called LabelFactory in there as well. This is just a class we created to help with the creation of labels and their style for our app. You can just replace this with a normal UILabel call.
One of our readers pointed out l never showed how to call the method from the UIController so here is an example call that you would make in the ViewDidLoad method
self.navigationItem.leftBarButtonItem = MenuManager.menuButton(self, "showMenu")



