2012年8月17日 星期五

Nokogiri

想不到 太久沒寫 Ruby

當時好用的 HTML Parser 工具 hpricot 已經終止了

不過還好還有 Nokogiri

以前使用過 hpricot 的朋友

可以完全無痛移植 Nokogiri

 C:\DevKit>gem install nokogiri
Fetching: nokogiri-1.5.5-x86-mingw32.gem (100%)
Successfully installed nokogiri-1.5.5-x86-mingw32
1 gem installed
Installing ri documentation for nokogiri-1.5.5-x86-mingw32...
Installing RDoc documentation for nokogiri-1.5.5-x86-mingw32...

一樣快速好用歐 並且支援 xpath, css, tag屬性 搜尋




require 'nokogiri'
require 'open-uri'

# Get a Nokogiri::HTML:Document for the page we’re interested in...

doc = Nokogiri::HTML(open('http://www.google.com/search?q=tenderlove'))

# Do funky things with it using Nokogiri::XML::Node methods...

####
# Search for nodes by css
doc.css('h3.r a').each do |link|
puts link.content
end

####
# Search for nodes by xpath
doc.xpath('//h3/a').each do |link|
puts link.content
end

####
# Or mix and match.
doc.search('h3.r a.l', '//h3/a').each do |link|
puts link.content
end




APNS 架設

APNS 憑證流程 官方最新必看

How to build an Apple Push Notification provider server 舊的方式(可參考)

Installing the SSL Certificate and Key on the Server



仔細看 步驟二、步驟三 即可匯出 p12

執行底下指令 就可將 p12 轉 pem

 openssl pkcs12 -in CertificateName.p12 -out CertificateName.pem -nodes

grocer - 另一個 APNS 選擇

https://github.com/highgroove/grocer

好處:支援中文,支援度、擴充性更高

C:\Users\APNS>gem install grocer
Fetching: grocer-0.1.0.gem (100%)
Successfully installed grocer-0.1.0
1 gem installed
Installing ri documentation for grocer-0.1.0...
Installing RDoc documentation for grocer-0.1.0...



$pusher = Grocer.pusher(
  certificate: 'C:\Users\Ruby\APNS\push_test.pem',
  gateway:     "gateway.sandbox.push.apple.com" # optional;  defaults to gateway.push.apple.com.
)


n = Grocer::Notification.new(
      device_token: '12345',
      alert:        "Hello iPhone!",
      badge:        1)
$pusher.push(n)

Gem for APNS

PS: 這個版本 目前送中文會有問題

A gem for the Apple Push Notification Service


C:\Users\user\>gem install apns
Fetching: apns-0.9.0.gem (100%)
Successfully installed apns-0.9.0
1 gem installed
Installing ri documentation for apns-0.9.0...
Installing RDoc documentation for apns-0.9.0...


push.rb
require 'rubygems'
require 'apns'
# https://github.com/jpoz/APNS
    # APNS.host = 'gateway.push.apple.com'
    # gateway.sandbox.push.apple.com is default
    # APNS.pem  = '/path/to/pem/file'
    # this is the file you just created
   
    # APNS.port = 2195
    # this is also the default. Shouldn't ever have to set this, but just in case Apple goes crazy, you can.
APNS.pem  = 'C:\Users\APNS\apns.pem'
    device_token = '123abc456def'
    APNS.send_notification(device_token, 'Hello iPhone!' )
    APNS.send_notification(device_token, :alert => 'Hello iPhone!', :badge => 1, :sound => 'default')

如何在 Windows 上 安裝 Thin

如果安裝 Thin 一直出現這樣的錯誤
 error: cannot convert 'stat*' to '_stati64*' for argument '2' to 'int _fstati64(int
, _stati64*)'



參考來源
ruby - Cannot install thin on windows - Stack Overflow

假設已經裝好 DevKit
還沒裝好請參考 Development Kit · oneclick/rubyinstaller Wiki · GitHub

C:\Users\user>gem install eventmachine --pre
Fetching: eventmachine-1.0.0.rc.4-x86-mingw32.gem (100%)
Successfully installed eventmachine-1.0.0.rc.4-x86-mingw32
1 gem installed
Installing ri documentation for eventmachine-1.0.0.rc.4-x86-mingw32...
Installing RDoc documentation for eventmachine-1.0.0.rc.4-x86-mingw32...

C:\Users\user>gem install thin
Fetching: daemons-1.1.9.gem (100%)
Fetching: thin-1.4.1.gem (100%)
Temporarily enhancing PATH to include DevKit...
Building native extensions.  This could take a while...
Successfully installed daemons-1.1.9
Successfully installed thin-1.4.1
2 gems installed
Installing ri documentation for daemons-1.1.9...
Installing ri documentation for thin-1.4.1...
Installing RDoc documentation for daemons-1.1.9...
Installing RDoc documentation for thin-1.4.1...


2012年8月14日 星期二

PageControl



active_page_image.png
inactive_page_image.png


GrayPageControl.h

#import <UIKit/UIKit.h>

@interface GrayPageControl : UIPageControl
{
    UIImage* activeImage;
    UIImage* inactiveImage;
}

@end



GrayPageControl.m


#import "GrayPageControl.h"

@implementation GrayPageControl

-(id) initWithCoder:(NSCoder *)aDecoder
{
    self = [super initWithCoder:aDecoder];
    
    activeImage = [UIImage imageNamed:@"active_page_image.png"];
    inactiveImage = [UIImage imageNamed:@"inactive_page_image.png"];
    
    return self;
}

-(void) updateDots
{
    for (int i = 0; i < [self.subviews count]; i++)
    {
        UIImageView* dot = [self.subviews objectAtIndex:i];
        if (i == self.currentPage) dot.image = activeImage;
        else dot.image = inactiveImage;
    }
}

-(void) setCurrentPage:(NSInteger)page
{
    [super setCurrentPage:page];
    [self updateDots];
}

/*
// Only override drawRect: if you perform custom drawing.
// An empty implementation adversely affects performance during animation.
- (void)drawRect:(CGRect)rect
{
    // Drawing code
}
*/

@end

PickerViewController



PickerViewController.h


#import <UIKit/UIKit.h>


@interface PickerViewController : UIViewController
<UIPickerViewDelegate, UIPickerViewDataSource>

@property (nonatomic, strong) IBOutlet UIPickerView *modelPicker;
@property (nonatomic, strong) NSArray *modelArray;
@property (nonatomic, strong) NSArray *memoryArray;
@property (nonatomic, strong) IBOutlet UILabel *modelLabel;
@property (nonatomic, strong) IBOutlet UILabel *memoryLabel;

@end



PickerViewController.m

#import "PickerViewController.h"

@interface PickerViewController ()

@end

@implementation PickerViewController
@synthesize modelPicker, memoryArray, modelArray;
@synthesize memoryLabel, modelLabel;

- (void)viewDidLoad
{
    [super viewDidLoad];
    self.modelArray = [[NSArray alloc] initWithObjects:
                       @"iPad WiFi", @"iPad WiFi+3G (AT&T)",
                       @"iPad WiFi+3G (Verizon)", nil];
    
    self.memoryArray = [[NSArray alloc] initWithObjects:
                        @"16GB", @"32GB", @"64GB", nil];
}




#pragma mark -
#pragma mark PickerView DataSource

- (NSInteger)numberOfComponentsInPickerView:(UIPickerView *)pickerView {
    
    return 2;
}

- (NSInteger)pickerView:(UIPickerView *)pickerView numberOfRowsInComponent:(NSInteger)component {
    
    if (component == 0) {
        return [modelArray count];
    }
    return [memoryArray count];
}

- (NSString *)pickerView:(UIPickerView *)pickerView
             titleForRow:(NSInteger)row
            forComponent:(NSInteger)component
{
    if (component == 0) {
        return [modelArray objectAtIndex:row];
    }
    return [memoryArray objectAtIndex:row];
}


#pragma mark -
#pragma mark PickerView Delegate

-(void)pickerView:(UIPickerView *)pickerView didSelectRow:(NSInteger)row
      inComponent:(NSInteger)component
{
    if (component == 0)
    {
        NSString *resultString = [[NSString alloc] initWithFormat:
                                  @"Model: %@",
                                  [modelArray objectAtIndex:row]];
        self.modelLabel.text = resultString;
    } else {
        NSString *resultString = [[NSString alloc] initWithFormat:
                                  @"Memory: %@",
                                  [memoryArray objectAtIndex:row]];
        self.memoryLabel.text = resultString;
    }
}


- (void)viewDidUnload
{
    [super viewDidUnload];
    // Release any retained subviews of the main view.
    // e.g. self.myOutlet = nil;
    self.memoryArray = nil;
    self.modelArray = nil;
    self.modelLabel = nil;
    self.memoryLabel = nil;
}


- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
    return (interfaceOrientation == UIInterfaceOrientationPortrait);
}

@end




2012年8月10日 星期五

Sinatra

on Windows

首先需要 安裝 Ruby
選擇安裝 Ruby Installer 一鍵安裝 免設定
在這邊安裝的版本是 Ruby 1.9.3-p194

打開 Command Line
確認一下環境&版本

C:\Users\user>ruby -v

ruby 1.9.3p194 (2012-04-20) [i386-mingw32]

C:\Users\user>gem -v

1.8.23


安裝 Sinatra

C:\Users\user>gem install sinatra

Fetching: rack-1.4.1.gem (100%)

Fetching: rack-protection-1.2.0.gem (100%)

Fetching: tilt-1.3.3.gem (100%)

Fetching: sinatra-1.3.2.gem (100%)

Successfully installed rack-1.4.1

Successfully installed rack-protection-1.2.0

Successfully installed tilt-1.3.3

Successfully installed sinatra-1.3.2

4 gems installed

Installing ri documentation for rack-1.4.1...

Installing ri documentation for rack-protection-1.2.0...

Installing ri documentation for tilt-1.3.3...

Installing ri documentation for sinatra-1.3.2...

Installing RDoc documentation for rack-1.4.1...

Installing RDoc documentation for rack-protection-1.2.0...

Installing RDoc documentation for tilt-1.3.3...

Installing RDoc documentation for sinatra-1.3.2...

寫個測試程式

# myapp.rb
require 'sinatra'

get '/' do
  'Hello world!'
end


執行

C:\Users\user>ruby myapp.rb
[2012-08-10 15:36:21] INFO  WEBrick 1.3.1
[2012-08-10 15:36:21] INFO  ruby 1.9.3 (2012-04-20) [i386-mingw32]
== Sinatra/1.3.2 has taken the stage on 4567 for development with backup from WEBrick
[2012-08-10 15:36:21] INFO  WEBrick::HTTPServer#start: pid=140360 port=4567


就跟他的網頁一樣

簡潔


製作 APNS 憑證
How to build an Apple Push Notification provider server (tutorial)

gem for APNS
https://github.com/jpoz/APNS

如何載入預設資料,使用 Core Data

Core Data on iOS 5 Tutorial: How To Preload and Import Existing Data

裡面提到兩種方式

  1. 執行App時,從其他資料匯入到資料戶,例如 JSON, XML, PLIST。
  2. 提供已經載入資料的資料庫。

在這裡我個人是採用第二種方式,

原因是,在邊寫程式邊調整資料庫的結構時,

最後也把資料庫弄好,並且整理好了,

所以在 App 第一次啟動時,

在 Core Data 初始化之前,需要先判斷 .sqlite 檔是否已經存在,

(Core Data 是 基於 SQLite 技術的物件式關連資料庫)

不存在,把之前準備好的資料庫檔 .sqlite (放在 App 的資料夾裡,跟 .h .m 放一起)

複製到 App 的 Document 目錄即可。


沒有採用第一種方式的原因是,

需要判斷是否已經載入之外,

還得另外寫匯入程式,

因為懶惰的關係,所以採用第二種方式唷!