2014年8月27日 星期三

Storyboard透過segue傳值

//Storyboard透過Segue跳轉會呼叫這個methods
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
    //判斷segue identifier是否是你要的
    if ([[segue identifier] isEqualToString:@"showDetail"]) {
        NSIndexPath *indexPath = [self.tableView indexPathForSelectedRow];
        NSManagedObject *object = [[self fetchedResultsController] objectAtIndexPath:indexPath];
        //呼叫目的地的ViewController的方法來傳值
        [[segue destinationViewController] setDetailItem:object];
    }

}

2014年8月26日 星期二

實作MRC轉ARC


  1. 把所有的dealloc拿掉,release、autorelease、retain都拿掉。
  2. 把第三方的code加上不轉ARC的標籤(-fno-objc-arc)。(如果想強制轉,改加-fobjc-arc)


  1.  
  2. 到Build Settings把Objective-C Automatic Reference Counting設為Yes
  3. 到xcode的選單列的Edit底下的Refactor,選Convert to Objective-C ARC...

2014年8月20日 星期三

取得NSCalendar格式的NSDateComponents

NSDateComponents *dateComps = [[NSCalendar currentCalendar] components: NSHourCalendarUnit fromDate:[NSDate date]];
    NSLog(@"hour:%i minutes:%i day:%i", dateComps.hour, dateComps.minute, dateComps.day);

這樣dateComps.hour會回傳當地的小時,而沒有列舉出來的(例如,dateComps.minute或dateComp.day)都只會回傳時間的總秒數。

如果想列出其他的日曆值,必需把列舉加進去
NSDateComponents *dateComps = [[NSCalendar currentCalendar] components: NSHourCalendarUnit | NSMinuteCalendarUnit | NSDayCalendarUnit fromDate:[NSDate date]];


也可以把NSCalendar轉成NSDate
NSDateComponents *dateComps = [[NSCalendar currentCalendar] components: NSYearCalendarUnit | NSMonthCalendarUnit | NSDayCalendarUnit | NSHourCalendarUnit fromDate:[NSDate date]];
    NSDate *date = [[NSCalendar currentCalendar] dateFromComponents:dateComps];

    NSLog(@"now : %@", date);
如果只有設小時,那轉成NSDate,會變成0001年01月01日hour時00分00秒

2014年8月18日 星期一

用UIView animateWithDuration來做出二個Frame之間的連續動作

這個類別方法你可以把他想像成是「展示二個frame設定之間的連續動作」,因此,你只能一次設定一個frame之間的轉變,如果有多的,它也只會做最後的一步,要做多重的轉變動畫,就要在completion中多次呼叫這個方法,我的範例如下:

-(void) _setScaleWithView:(UIView *)view alpha:(float) alpha xScale:(float) xScale yScale:(float) yScale{
    
    view.frame = CGRectMake(view.frame.origin.x, view.frame.origin.y, view.frame.size.width + xScale , view.frame.size.height + yScale);
    view.alpha = alpha;
}

-(void) _scalingView:(UIView *)view{
    CGRect rect = view.frame;
    [UIView animateWithDuration:0.5
                          delay:0.0
                        options:UIViewAnimationOptionBeginFromCurrentState
                     animations:(void (^)(void)) ^{
                         [self _setScaleWithView:view alpha:0.5 xScale:-2 yScale:-2];
                     }
                     completion:^(BOOL finished){
                         [UIView animateWithDuration:0.2 animations:^{
                             [self _setScaleWithView:view alpha:1.0 xScale:2*2 yScale:2*2];
                         } completion:^(BOOL finished) {
                             [UIView animateWithDuration:0.5 animations:^{
                                 [self _setScaleWithView:view alpha:0.5 xScale:-2*2 yScale:-2*2];
                                 } completion:^(BOOL finished) {
                                 [UIView animateWithDuration:0.2 animations:^{
                                     [self _setScaleWithView:view alpha:1.0 xScale:2*2 yScale:2*2];
                                 } completion:^(BOOL finished) {
                                     [UIView animateWithDuration:0.5 animations:^{
                                         [self _setScaleWithView:view alpha:0.5 xScale:-2*2 yScale:-2*2];
                                     } completion:^(BOOL finished) {
                                         [UIView animateWithDuration:0.2 animations:^{
                                             [self _setScaleWithView:view alpha:1.0 xScale:2 yScale:2];
                                         } completion:^(BOOL finished) {
                                             view.frame = rect;
                                             view.alpha = 1;
                                         }];
                                     }];
                                 }];
                                 
                             }];
                         }];
                     }];

}

2014年8月1日 星期五

APNS與GCM的推播能在Server保留多久

GCM

http://developer.android.com/google/gcm/adv.html#ttl

Setting an Expiration Date for a Message

The Time to Live (TTL) feature lets the sender specify the maximum lifespan of a message using the time_to_live parameter in the send request. The value of this parameter must be a duration from 0 to 2,419,200 seconds, and it corresponds to the maximum period of time for which GCM will store and try to deliver the message. Requests that don't contain this field default to the maximum period of 4 weeks.

APNS

http://stackoverflow.com/questions/8608849/how-long-does-a-push-notification-sit-in-queue-before-being-removed
Official developer documentation isn't clear about this. From developer.apple.com:
Apple Push Notification Service includes a default Quality of Service (QoS) component that performs a store-and-forward function. If APNs attempts to deliver a notification but the device is offline, the QoS stores the notification. It retains only one notification per application on a device: the last notification received from a provider for that application. When the offline device later reconnects, the QoS forwards the stored notification to the device. The QoS retains a notification for a limited period before deleting it.
But according to PCWorld, it's 28 days:
If the app is running, it gets the notification immediately. If the app isn't running, the notification is held in the phone to be consumed at the app's next launch. If the iPhone is offline when the sender attempts delivery, APNS attempts to send the notification for 28 days.
While 28 days may have been true in 2009, I wouldn't be surprised if its different today. The ambiguity in the documentation is a great excuse for Apple to change this timeout period willy-nilly.