コードスニペット(Push通知編 アプリ側)
Push通知のコードスニペット
実装手順
- Push通知の設定
- デバイストークンの送信
- Push通知を受け取る
1. Push通知の設定
iOS7以下とiOS8以上で仕様が違う
import UIKit
class RemotePushManager {
class func registerForRemoteNotifications(application: UIApplication) {
if #available(iOS 8.0, *) {
let settings = UIUserNotificationSettings(forTypes: [.Alert, .Badge, .Sound], categories: nil)
application.registerUserNotificationSettings(settings)
application.registerForRemoteNotifications()
} else {
application.registerForRemoteNotificationTypes([.Alert, .Badge, .Sound])
}
}
}
import UIKit
@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {
var window: UIWindow?
func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
RemotePushManager.registerForRemoteNotifications(application)
return true
}
2. デバイストークンの送信
自前サーバーへデバイストークンを送信する
//MARK: - リモートプッシュ通知
func application(application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: NSData) {
let characterSet: NSCharacterSet = NSCharacterSet(charactersInString: "<>")
let deviceTokenString: String = (deviceToken.description as NSString)
.stringByTrimmingCharactersInSet(characterSet)
.stringByReplacingOccurrencesOfString(" ", withString: "") as String
print(deviceTokenString)
//TODO : デバイストークンの送信
}
func application(application: UIApplication, didFailToRegisterForRemoteNotificationsWithError error: NSError) {
}
3. Push通知を受け取る
import UIKit
class RemotePushManager {
class func received(application: UIApplication, launchOptions: [NSObject: AnyObject]?) {
if let launchOptions = launchOptions {
if let aps = launchOptions["aps"] as? [NSObject: AnyObject] {
print(aps["alert"])
print(aps["sound"])
print(aps["badge"])
}
}
}
}
import UIKit
@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {
var window: UIWindow?
func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
RemotePushManager.registerForRemoteNotifications(application)
if let launchOptions = launchOptions {
if let option : NSDictionary = launchOptions[UIApplicationLaunchOptionsRemoteNotificationKey] as? NSDictionary {
self.application(application, didReceiveRemoteNotification: option as [NSObject : AnyObject])
}
}
return true
}
//Push通知受信時とPush通知をタッチして起動したとき
func application(application: UIApplication, didReceiveRemoteNotification userInfo: [NSObject : AnyObject]) {
RemotePushManager.received(application, launchOptions: userInfo)
switch application.applicationState {
case .Inactive:
break
case .Active:
break
case .Background:
break
}
}
}
APNSから受信するデータは、下記のようなイメージ
{
"aps":{
"alert": "New Message",
"badge": 3,
"sound": "sound1.aiff",
"content-available": 1 // -> サイレントプッシュ
},
"name": "value"
}
サーバー側
サーバーサイトは、下記のようなライブラリを使うと便利です。
コードスニペット (UIWebView編)
UIWebViewのコードスニペット
よく使いそうなメソッドをExtension化しました。
import UIKit
extension UIWebView {
/**
UIWebViewを表示する(サーバーのファイル)
*/
func open(urlString: String) {
self.loadRequest(NSURLRequest(URL: NSURL(string: urlString)!))
}
/**
UIWebViewを表示する(ローカルファイル)
*/
func openLocalFile(fileName: String, ofType: String) {
let path: NSString = NSBundle.mainBundle().pathForResource(fileName, ofType:ofType)!
self.open(path as String)
}
/**
ユーザーエージェントの取得
*/
func userAgent() -> String {
return self.stringByEvaluatingJavaScriptFromString("navigator.userAgent") ?? ""
}
/**
ユーザーエージェントの変更
*/
func updateUserAgent(str: String) {
if let userAgent = self.stringByEvaluatingJavaScriptFromString("navigator.userAgent") {
let customUserAgent = userAgent.stringByAppendingString(" \(str)")
let dic = ["UserAgent" : customUserAgent]
NSUserDefaults.standardUserDefaults().registerDefaults(dic)
}
}
/**
JSの関数を呼ぶ(戻り値なし)
*/
func jsFunc(jsString: String) {
self.stringByEvaluatingJavaScriptFromString(jsString)
}
/**
JSの関数を呼ぶ(戻り値あり)
*/
func jsFuncCallBack(jsString: String) -> NSDictionary? {
let result = self.stringByEvaluatingJavaScriptFromString(jsString)
if let resultData = result?.dataUsingEncoding(NSUTF8StringEncoding) {
return try! NSJSONSerialization.JSONObjectWithData(resultData, options: NSJSONReadingOptions.MutableContainers) as? NSDictionary
}
return nil
}
/**
ページ内アンカー移動
*/
func internalAnchor(request: NSURLRequest, anchorName: String) {
let names = request.URL?.absoluteString.componentsSeparatedByString("#")
jsFunc("window.location.hash = \"\(names?.first!)\"")
}
}
UIWebViewのDelegateをクラス化しました。
import UIKit
typealias WebViewDidFinishLoad = (UIWebView) -> ()
typealias WebViewDidStartLoad = (UIWebView) -> ()
typealias WebViewDidFailLoadWithError = (UIWebView, NSError?) -> ()
class WebViewDelegate: NSObject, UIWebViewDelegate {
var webViewDidFinishLoad: WebViewDidFinishLoad?
var webViewDidStartLoad: WebViewDidStartLoad?
var webViewDidFailLoadWithError: WebViewDidFailLoadWithError?
func setupWebViewDidFinishLoad(webViewDidFinishLoad: WebViewDidFinishLoad) {
self.webViewDidFinishLoad = webViewDidFinishLoad
}
func setupWebViewDidStartLoad(webViewDidStartLoad: WebViewDidStartLoad) {
self.webViewDidStartLoad = webViewDidStartLoad
}
func setupWebViewDidFailLoadWithError(webViewDidFailLoadWithError: WebViewDidFailLoadWithError) {
self.webViewDidFailLoadWithError = webViewDidFailLoadWithError
}
//MARK: - UIWebViewDelegate
//Pageがすべて読み込み終わった時呼ばれるデリゲートメソッド.
func webViewDidFinishLoad(webView: UIWebView) {
if webViewDidFinishLoad != nil{
if let block = webViewDidFinishLoad {
block(webView)
}
}
}
//Pageがloadされ始めた時、呼ばれるデリゲートメソッド.
func webViewDidStartLoad(webView: UIWebView) {
if webViewDidStartLoad != nil{
if let block = webViewDidStartLoad {
block(webView)
}
}
}
func webView(webView: UIWebView, didFailLoadWithError error: NSError?) {
if webViewDidFailLoadWithError != nil{
if let block = webViewDidFailLoadWithError {
block(webView, error)
}
}
}
}
外部HTMLファイルを読みには、
import UIKit
class ViewController: UIViewController {
@IBOutlet weak var webView: UIWebView!
var webViewDelegate = WebViewDelegate()
let requestURL = "http://www.apple.com/jp/iphone-6s/"
override func viewDidLoad() {
super.viewDidLoad()
setup()
}
override func viewWillAppear(animated: Bool) {
super.viewWillAppear(animated)
webView.open(requestURL)
}
func setup() {
webViewDelegate.setupWebViewDidStartLoad { (webView) -> () in
print(__FUNCTION__)
}
webViewDelegate.setupWebViewDidFinishLoad { (webview) -> () in
print(__FUNCTION__)
}
webViewDelegate.setupWebViewDidFailLoadWithError { (WebView, error) -> () in
print(error)
}
webView.delegate = webViewDelegate
}
}
ローカルHTMLファイルを読むには
webView.openLocalFile("index", ofType: "html")
HTMLを直接書くには、
func createHTML() -> String {
let sMessage = "Hello"
let sMeta = "<meta name=\"viewport\" content=\"initial-scale=1.0,minimum-scale=1.0,maximum-scale=1.0,user-scalable=no\">";
let sStyle = "<style>html,body{background-color:#eaeae9;}p{font-size:14px;font-weight:bold;width:80%;marg
in:50px auto;}</style>";
let sHtmlHead = "<head>" + sMeta + sStyle + "</head>";
let sHtmlBody = "<body><p>" + sMessage + "</p></body>";
return "<html>" + sHtmlHead + sHtmlBody + "</html>";
}
webView.loadHTMLString(createHTML(), baseURL: nil)
コードスニペット (UIButton編)ボタン押下時のアニメーション
ボタン押下時のアニメーションをつけるコードスニペット
UIButtonのExtensionにアニメーションを追加してみました。
import UIKit
extension UIButton{
/**
* ボタン押下時のアニメーション
*/
func pushAnimation() {
let defaultButton = self.bounds
UIView.animateWithDuration(1.5,
delay: 0.0,
usingSpringWithDamping: 0.2,
initialSpringVelocity: 10,
options: UIViewAnimationOptions.CurveEaseInOut,
animations: { () -> Void in
self.bounds = CGRectMake(
defaultButton.origin.x,
defaultButton.origin.x,
defaultButton.size.width + 40,
defaultButton.size.height)
}) { (finished) -> Void in
self.bounds = CGRectMake(
defaultButton.origin.x,
defaultButton.origin.x,
defaultButton.size.width,
defaultButton.size.height)
}
}
}
使い方
@IBAction func tappedButton(sender: UIButton) {
sender.pushAnimation()
}
コードスニペット (UIView編)プロパティへのショートカット
UIViewのプロパティへのショートカット用のコードスニペット
extension化しました。
extension UIView {
/**
上の位置を取得
:returns: 上の位置
*/
func top() -> CGFloat {
return self.frame.origin.y
}
/**
右の位置を取得
:returns: 右の位置
*/
func right() -> CGFloat {
return self.frame.origin.x + self.frame.size.width
}
/**
下の位置を取得
:returns: 下の位置
*/
func bottom() -> CGFloat {
return self.frame.origin.y + self.frame.size.height
}
/**
左の位置の取得
:returns: 左の位置
*/
func left() -> CGFloat {
return self.frame.origin.x
}
/**
UIViewの幅を取得
:returns: UIViewの幅
*/
func width() -> CGFloat {
return self.frame.size.width
}
/**
UIViewの高さを取得
:returns: UIViewの高さ
*/
func height() -> CGFloat {
return self.frame.size.height
}
/**
UIViewのoriginを取得
:returns: UIViewのorigin
*/
func origin() -> CGPoint {
return self.frame.origin
}
/**
UIViewのサイズを取得
:returns: UIViewのサイズ
*/
func size() -> CGSize {
return self.frame.size
}
}
使い方
print("w : \(self.view.width()) - h : \(self.view.height())")
コードスニペット(Carthageインストール、設定編)
Carthageインストールと設定のコードスニペット
ゴール
Alamofire(通信用ライブラリ)を利用できるようにする。
手順
- Carthageのダウンロードとインストール
- 外部ライブラリの導入
- プロジェクトに外部ライブラリを追加
1.Carthageのダウンロードとインストール
以下、ターミナルからコマンドを入力する。 インストール済みの方は、飛ばしてください。
1.1. Homebrewの導入
ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)" brew update
1.2. Carthageの導入
brew install carthage
2.外部ライブラリの導入
以下、ターミナルからコマンドを入力する。
2.1. ライブラリを導入したいプロジェクトのディレクトリへ移動
2.2. Cartfileを作成
vim Cartfile
2.3. 外部ライブラリの追加 今回は、Alamofireというライブラリを追加する
github "Alamofire/Alamofire"
2.4. 外部ライブラリをビルド
carthage update --platform iOS
上記まで進むと、Buildディレクトリ配下にフレームワークが作られる。 /Carthage/Build/iOS/Alamofire.framework

3.プロジェクトに外部ライブラリを追加
3.1. Buil Phasesタブから、「Linked Frameworks and Library」にある+ボタンを押す

3.2. 「Add Other...」を選択する

3.3. プロジェクトのディレクトリ内から、Carthage/Build/iOSと移動し、ライブラリの.frameworkファイルを選択する

3.4. Build Phasesタブに移動し、+ボタンから、「New Run Script Phase」を選択する

3.5. Shell」の下にある黒い部分に以下のコマンドを記述します。
/usr/local/bin/carthage copy-frameworks

3.6. 「input Files」にて+ボタンを押し、以下のようにframeworkの情報を記述する
$(SRCROOT)/Carthage/Build/iOS/Alamofire.framework

さいごに
あとは、「import Alamofire」すれば利用可能です。
コードスニペット (UIColor編)
テーマ
カラーの指定は、デフォルトで用意されていもの以外は、使いづらい ということで、extensionを作りました。
UIColorのコードスニペット
extension UIColor {
//色をRGBで指定する
class func rgb(rgbValue: UInt) -> UIColor {
return UIColor(
red: CGFloat((rgbValue & 0xFF0000) >> 16) / 255.0,
green: CGFloat((rgbValue & 0x00FF00) >> 8) / 255.0,
blue: CGFloat(rgbValue & 0x0000FF) / 255.0,
alpha: CGFloat(1.0)
)
}
//画像を繰り返し表示する
class func patternImage(fileName: String) -> UIColor {
return UIColor(patternImage: UIImage(named: fileName)!)
}
}
ついでに、画像の色を変える方法も載せておきます。
画像を色ごとにいちいち用意するのが面倒なときは、画像の色ごと変えちゃいましょう。
//画像の色を変更する
func changeColorImage() {
imageView.image = UIImage(named: "alarm.png")?.imageWithRenderingMode(UIImageRenderingMode.AlwaysTemplate)
imageView.tintColor = UIColor.redColor()
}
おすすめ本のご紹介
Amazon.co.jp: 詳細! Swift 2 iPhoneアプリ開発 入門ノート Swift 2 + Xcode 7対応: 大重 美幸: 本
コードスニペット(画像をピンチイン・ピンチアウト、回転、移動したい)
テーマ
UIImageViewをピンチイン・ピンチアウトしたり、回転したり、移動できるようにカスタマイズします。
実装手順
- UIImageViewの拡張クラスを作る
- UIImageViewに1で作成したクラスを指定する
1. UIImageViewの拡張クラスを作る
import UIKit
class FlexibleImageView: UIImageView,UIGestureRecognizerDelegate {
var scale: Float = 0.0
var rotation: Float = 0.0
var isChange = false
var isReset = false
var defaultTransform: CGAffineTransform?
required init(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)!
self.setup()
}
func setup() {
self.userInteractionEnabled = true
let rotation = UIRotationGestureRecognizer(target: self, action: "doAnimation:")
rotation.delegate = self
self.addGestureRecognizer(rotation)
let pinch = UIPinchGestureRecognizer(target: self, action: "doAnimation:")
pinch.delegate = self
self.addGestureRecognizer(pinch)
self.isChange = false
self.scale = 1.0
self.rotation = 0.0
let pan = UIPanGestureRecognizer(target: self, action: "doPanAciton:")
self.addGestureRecognizer(pan)
}
//MARK: - Action
func doPanAciton(sender: UIPanGestureRecognizer) {
let translation = sender.translationInView(self.superview!)
let movedPoint = CGPointMake(self.center.x + translation.x, self.center.y + translation.y)
self.center = movedPoint
sender.setTranslation(CGPointZero, inView: self)
}
func doAnimation(sender: UIGestureRecognizer) {
if !isChange && sender.state == UIGestureRecognizerState.Began {
isChange = true
defaultTransform = self.transform
} else if isChange && sender.state == UIGestureRecognizerState.Ended {
reset()
return
}
if sender.state == UIGestureRecognizerState.Ended {
return
}
if sender.isKindOfClass(UIRotationGestureRecognizer) {
self.rotation = Float((sender as! UIRotationGestureRecognizer).rotation)
} else {
self.scale = Float((sender as! UIPinchGestureRecognizer).scale)
}
var transform = CGAffineTransformConcat(
CGAffineTransformConcat(self.defaultTransform!, CGAffineTransformMakeRotation(CGFloat(self.rotation))),
CGAffineTransformMakeScale(CGFloat(self.scale), CGFloat(self.scale)))
self.transform = transform
}
//MARK: - Private
func resetAnimation() {
if isReset == true {
UIView.animateWithDuration(0.2, animations: { () -> Void in
self.transform = self.defaultTransform!
})
}
}
func reset() {
self.isChange = false
self.scale = 1.0
self.rotation = 0.0
NSTimer.scheduledTimerWithTimeInterval(0.1, target: self, selector: "resetAnimation", userInfo: nil, repeats: false)
}
func gestureRecognizer(gestureRecognizer: UIGestureRecognizer, shouldRecognizeSimultaneouslyWithGestureRecognizer otherGestureRecognizer: UIGestureRecognizer) -> Bool {
return true
}
}
2. UIImageViewに1.で作成したクラスを指定する
StoryBoardで利用する場合は、Custom ClassのClassに「FlexibleImageView」を指定してください。 あとは、何もしなくても、ピンチイン・ピンチアウト、回転、移動できます。
おすすめ本のご紹介
エントリーにも良いと思います。