2015年10月30日 星期五

在iOS App裡加入Fan page與App Store link

Screenshot

在App裡面,我們經常會需要連結到自己的粉絲團,或是App Store頁面請使用者評分。
接下來講解怎麼實做。

連到粉絲團

下面這一段code的思考模式是這樣,我們會先用canOpenURL去檢查使用者是否安裝了Facebook app,
若有則用原生的facebook app開啟粉絲團頁面,若無則使用safari去開啟行動網頁。
如果不知道自己的粉絲團id可以使用 http://findmyfbid.com/ 查詢。

NSURL *facebookAppLink = [NSURL URLWithString:@"fb://profile/yourid"];
NSURL *facebookURL = [NSURL URLWithString:@"https://m.facebook.com/yourid"];

if ([[UIApplication sharedApplication] canOpenURL:facebookAppLink]) {
    [[UIApplication sharedApplication] openURL:facebookAppLink];
} else {
    [[UIApplication sharedApplication] openURL:facebookURL];
}

在iOS9你很可能會遇到這樣的錯誤

CanOpen[2255:1002610] -canOpenURL: failed for URL:
 "fb://" - error: "(null)"

這裡要特別注意的是,在iOS9之後必需要在info.plist裡面設置LSApplicationQueriesSchemes,
這樣canOpenURL才會回傳YES,沒有設定他只會回傳NO。所以要到info.plist裡面加入
LSApplicationQueriesSchemes,新增一個fb item,類別是String,這樣就可以了。

scheme

圖片裡有很多item是因為我有整合facebook登入,如果要打開粉絲團頁面其實只需要fb那個就可以。

App Store頁面

網路上有很多人採用openURL的方式來打開App Store連結,如下所示。
但我個人覺得這個方式打開的速度有點慢,因為它會先打開safari,然後再跳轉到原生App Store裡面,
大概會lag幾秒,使用者體驗不是很優。

NSString *iTunesLink = @"itms://itunes.apple.com/us/app/apple-store/id375380948?mt=8";
[[UIApplication sharedApplication] openURL:[NSURL URLWithString:iTunesLink]];

其實在iOS6之後就有新增一個SKStoreProductViewController類別可以在App內打開App Store頁面,
不用跳出自己的App就可以讓使用者評分了,這樣感覺是不是好很多了?

首先引入StoreKit,並讓自己的ViewController遵從SKStoreProductViewControllerDelegate。

@import StoreKit;

@interface ViewController : UIViewController<SKStoreProductViewControllerDelegate>
@end

打開頁面

- (void)openAppStorePage
{
    NSString *cAppleID = @"your app id";
    if ([SKStoreProductViewController class]) {
        SKStoreProductViewController *storeViewController = [[SKStoreProductViewController alloc] init];
        storeViewController.delegate = self;
        NSDictionary *dict = [NSDictionary dictionaryWithObject:cAppleID forKey: SKStoreProductParameterITunesItemIdentifier];
        [storeViewController loadProductWithParameters:dict completionBlock:^(BOOL result, NSError * _Nullable error) {
            if (result) {
                [self.navigationController presentViewController:storeViewController animated:YES completion:nil];
            }
        }];
    }

按下關閉時要dismiss目前顯示的頁面。

- (void)productViewControllerDidFinish:(SKStoreProductViewController *)viewController {
    [viewController dismissViewControllerAnimated: YES completion: nil];
}

2015年10月20日 星期二

整合Parse與Facebook登入

其實已經有人整理好一篇文章了,照著步驟做應該沒有什麼問題。不過呢,我們至少要知道為什麼要這樣做。Apple在iOS9預設HTTP必須走TLS1.2,也就是HTTPS的形式。不過看起來目前FB的Server還沒有支援,所以必須設置例外讓連線可以接通。關於ATS以及詳細的資訊可以參考iOS9网络适配_ATS:改用更安全的HTTPS

另外,如果要對UI做本地化(Localization),記得要新增一個ParseUI.strings而不是使用原本的Localizable.strings。

客制化按鈕顏色的話,要先去除backgroundImage再設定backgroundColor。

[self.logInView.logInButton setBackgroundImage:nil forState:UIControlStateNormal];
self.logInView.logInButton.backgroundColor = [UIColor orangeColor];

2015年10月5日 星期一

做一個無限旋轉的UIView

這幾天需要做一個無限旋轉的View,有點像下圖這樣,一個開關控制風扇啟動與停止。

Fan

stackoverflow上找到一篇相關的討論,在所有答案中我最喜歡Nate的答案

// an ivar for your class:
BOOL animating;

- (void) spinWithOptions: (UIViewAnimationOptions) options {
   // this spin completes 360 degrees every 2 seconds
   [UIView animateWithDuration: 0.5f
                         delay: 0.0f
                       options: options
                    animations: ^{
                       self.imageToMove.transform = CGAffineTransformRotate(imageToMove.transform, M_PI / 2);
                    }
                    completion: ^(BOOL finished) {
                       if (finished) {
                          if (animating) {
                             // if flag still set, keep spinning with constant speed
                             [self spinWithOptions: UIViewAnimationOptionCurveLinear];
                          } else if (options != UIViewAnimationOptionCurveEaseOut) {
                             // one last spin, with deceleration
                             [self spinWithOptions: UIViewAnimationOptionCurveEaseOut];
                          }
                       }
                    }];
}

- (void) startSpin {
   if (!animating) {
      animating = YES;
      [self spinWithOptions: UIViewAnimationOptionCurveEaseIn];
   }   
}

- (void) stopSpin {
    // set the flag to stop spinning after one last 90 degree increment
    animating = NO;
}

2015年10月2日 星期五

Objective-C 基本觀念複習

雖然現在Swift已經出到2.0了,但是大多數公司還是使用Objective-C為主力語言。因此,適時複習一下觀念還是很有必要的。網路上有一些不錯的題目,例如 招聘一个靠谱的 iOS面試 iOS 工程師的一些題目如何面试 iOS 工程师?上级向的十个iOS面试问题。也有一些網友給出了自己的解答,例如:https://github.com/ChenYilong/iOSInterviewQuestions 以及 http://www.90159.com/2015/07/26/71/ 還有 http://www.jianshu.com/p/4fea8fa60d75 。不過網路上的答案終究是別人的,唯有實實在在的自己研究過一遍,才會成為自己的東西,共勉之。

下面是一些我蒐集的基本觀念文章,也許可以幫你節省一點找資料的時間。

Property

http://www.devtalking.com/articles/you-should-to-know-property/

Block

http://www.devtalking.com/articles/you-should-know-block/

物件之間的溝通

https://www.objc.io/issues/7-foundation/communication-patterns/

Category

http://tech.meituan.com/DiveIntoCategory.html

KVC, KVO

http://objccn.io/issue-7-3/
http://southpeak.github.io/blog/2015/04/23/nskeyvalueobserving-kvo/

Runloop

http://blog.ibireme.com/2015/05/18/runloop/

Deep copy & Shallow copy

https://www.zybuluo.com/MicroCai/note/50592

Runtime

http://blog.eddie.com.tw/2013/12/05/object-class-and-meta-class-in-objective-c/
http://yulingtianxia.com/blog/2014/11/05/objective-c-runtime/
http://chun.tips/blog/categories/objective-c-runtime/
http://southpeak.github.io/blog/2014/10/25/objective-c-runtime-yun-xing-shi-zhi-lei-yu-dui-xiang/

ARC釋放機制

http://blog.sunnyxx.com/2014/04/02/objc_dig_arc_dealloc/

Autorelease原理

http://blog.sunnyxx.com/2014/10/15/behind-autorelease/

Method swizzling

http://southpeak.github.io/blog/2014/11/06/objective-c-runtime-yun-xing-shi-zhi-si-:method-swizzling/