俺の備忘録

趣味でITエンジニアをやってるものです

Google Analytics を使ってみた〜導入編〜

今回はGoogleAnalyticsをiosアプリに組み込みたいと思います。
ちなみにライブラリの導入にはCocoaPodsを使用します。

環境

手順

*CocoaPodsは導入しているものとします。

PodFileの作成

ターミナルでGoogleAnalyticsを導入したいディレクトリまで移動します。
GoogleAnalyticsを導入したいディレクトリで

$ pod init

とコマンドを打ちます。 *「$」は打ち込む必要はありません
するとそのディレクトリに「PodFile」というファイルができていると思います。
あと、「プロジェクト名.xcworkspace」というファイルも生成されていると思います。今度からは「プロジェクト名.xcodeproj」ではなく、「プロジェクト名.xcworkspace」を開いてプロジェクトを編集していきます。

GoogleAnalyticsライブラリの導入

先ほど作成した「PodFile」をXcode、テキストエディット、vimなどで開きます。ダブルクリックするとテキストエディットで開くと思います。

# Uncomment this line to define a global platform for your project
# platform :ios, ‘8.0’
# use_frameworks!

target 'プロジェクト名' do

end

target 'プロジェクト名Tests' do

end

target 'プロジェクト名UITests' do

end

PodFileの中身はこんな感じになっていると思います。
これを以下のように編集します

# Uncomment this line to define a global platform for your project
# platform :ios, ‘8.0’

use_frameworks!  //「#」を消す

target 'プロジェクト名' do

pod 'Google/Analytics'  //これを追加

end

target 'プロジェクト名Tests' do

end

target 'プロジェクト名UITests' do

end

*「//」以下は追加する必要はありません。
編集したらターミナルでPodFileのあるディレクトリまで移動し

$ pod install

と打ち込みます。*「$」は打ち込む必要はありません。
これで導入は完了です。

Bridge Header File の追加

GoogleAnalyticsライブラリはObjective-cで書かれているので、BridgeHeaderFileを作成します。
BridgeHeaderFileとはObjectice-cで書かれたライブラリをSwiftでも使用できるようにできるものです。
まず、プロジェクトを開いた状態で、File → New → File でHeader Fileを選択し、objective-cファイルを作成します。f:id:daikon0413:20160331143207p:plain
するとこのような画面が出てくるので
f:id:daikon0413:20160331143317p:plain
Create Bridge Header をクリックします。
すると、BridgeHeaderが自動生成されます。
BridgeHeaderを以下のように編集します。

#import <GoogleAnalytics/GAI.h>
#import <GoogleAnalytics/GAIFields.h>
#import <GoogleAnalytics/GAILogger.h>
#import <GoogleAnalytics/GAIDictionaryBuilder.h>

GoogleAnalyticsアカウントの作成

次はGoogleAnalyticsのアカウントを作成します。
GoogleAnalyticsの公式サイトhttps://www.google.com/intl/ja_JP/analytics/にアクセスします。
サイト右上にある「アカウント作成」ボタンをクリックします。
あとは指示に従って必要な情報を入力していきます。
そして、最後に「トラッキングIDを取得」をクリックしてアカウントが作成されます。
移動先の画面のトラッキングIDをメモしておきましょう。 *トラッキングIDは管理画面から確認可能です。

AppDelegateでGoogleAnalyticsを設定する

AppDelegate.swiftのdidFinishLaunchingWithOptionsメソッドを以下のように編集します。

func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
        // Override point for customization after application launch.
        
        //GoogleAnalyticsの設定
        GAI.sharedInstance().trackUncaughtExceptions = true
        GAI.sharedInstance().dispatchInterval = 20
        GAI.sharedInstance().logger.logLevel = .Verbose
        GAI.sharedInstance().trackerWithTrackingId("トラッキングID")
        
        return true
    }

これでアプリ起動時に設定が読み込まれます。

ラッキングしてみる

「トラッキング」とは追跡などという意味で、ここではユーザの動きを追跡するということですね。
適当なViewControllerにトラッキングの設定を書いていきます。

override func viewWillAppear(animated: Bool) {
        //analytics
        let tracker = GAI.sharedInstance().defaultTracker
        tracker.set(kGAIScreenName, value: "Home")
        let params = GAIDictionaryBuilder.createScreenView().build() as [NSObject : AnyObject]
        tracker.send(params)
}

作成できたらシュミレータを起動します。
起動したら、GoogleAnalayticsのサイトにアクセスし、レポートのリアルタイム確認ページを開きます。

f:id:daikon0413:20160331132837p:plain

アクティブユーザが1になっているかどうか確認します。
1になっていれば成功です。

<Swift> Social.framewarkをインポートしてみた

今回はiOSアプリにSNS投稿機能つけたいなぁ、と思ったのでSocial.framewarkを使っていきたいと思います

環境
手順

まずはSocial.framewarkをインポートします

import UIKit
import Social //Socialをインポート

class resultViewController: UIViewController {

    override func viewDidLoad() {
        super.viewDidLoad()
    }

}

次にstoryboardで投稿ボタンを設置します。

そして、以下のアクションを追加

@IBAction func tweetBtn(sender: AnyObject) {
        let twitterViewController = SLComposeViewController(forServiceType: SLServiceTypeTwitter)
        twitterVC.setInitialText("Twitterに投稿")[f:id:daikon0413:20160327173940p:plain][f:id:daikon0413:20160327174214p:plain]
        presentViewController(twitterViewController, animated: true, completion: nil)
    }
    
    @IBAction func facebookBtn(sender: AnyObject) {
        let facebookViewController = SLComposeViewController(forServiceType: SLServiceTypeFacebook)
        facebookVC.setInitialText("FaceBookに投稿")
        presentViewController(facebookViewController, animated: true, completion: nil)
    }

あとは関連付けをして完成です!



f:id:daikon0413:20160327173940p:plain f:id:daikon0413:20160327174214p:plain

<Swift> UIImageViewをドラッグしてみた

環境

まずはデリゲートの宣言と動かすUIImageViewの作成

class playViewController: UIViewController, UIGestureRecognizerDelegate {
       @IBOutlet var moveImage: UIImageView!

       override func viewDidLoad() {
        super.viewDidLoad()

        myImg.frame = CGRectMake(120, 135, 80, 80)
        whiteImg.image = UIImage(named: "sample.png")
        //UIImageViewの移動を許可
        myImg.userInteractionEnabled = true
        myImg.addSubview(self.view)
        
        let pan: UIGestureRecognizer = UIPanGestureRecognizer.init(target: self, action: "panAction:")
        myImg.addGestureRecognizer(pan)
    }
}

続いてドラッグ中の処理を記述

func panAction(sender: UIPanGestureRecognizer) {
        //移動した位置の座標を取得
        let point: CGPoint = sender.translationInView(self.view)
        //移動した座標のx,y座標を中心にする
        let movePoint = CGPointMake(productImg.center.x + point.x, productImg.center.y + point.y)
        productImg.center = movePoint
        print(movePoint)
        //移動距離の初期化
        sender.setTranslation(CGPointZero, inView: self.view)
        if sender.state == UIGestureRecognizerState.Ended {
            print("移動終了")
        }
    }

これで終わりです。
おそらく動くと思います。

NiftyCloud mobile backend を使ってみた

来年の1月28日にParseがサービスを終了するらしいので、NiftyCloud mobile backend を使ってみることにしました。

まずは試しにツイッターみたいなアプリを作ってみようと思います。

環境

xcode7、swift2

機能

  • ユーザ登録
  • テキストを投稿
  • 投稿したテキストをタイムラインに表示

完成品はこんな感じです
f:id:daikon0413:20160309143002g:plain

手順

※NiftyColud mobile backend の導入は省きます

1 必要なパーツを配置

  • ログイン・会員登録を行うViewController
  • ユーザネームを表示するhomeViewController
  • タイムラインを表示するtimeLineViewController
  • ツイートを投稿するtweetViewController

それぞれのViewに設置したUIパーツは後述します。

f:id:daikon0413:20160309143447p:plain
ストーリーボードはこんな感じです。わかりにくくてすいません。

2 会員登録・ログイン・ログアウト機能を実装

storyboardのViewControllerに

  • ユーザネーム用のUITextField
  • パスワード用のUITextField
  • ログイン、会員登録ボタン

homeViewControllerに

  • ユーザネーム表示用のUILabal
  • ログアウトボタン

を設置します。

コードはこんな感じです。
ViewController.swift

import UIKit
import NCMB //NCMBフレームワークをインポート

class ViewController: UIViewController, UITextFieldDelegate {
    
    @IBOutlet var nameField: UITextField!
    @IBOutlet var passwardField: UITextField!

    override func viewDidLoad() {
        super.viewDidLoad()
        
        nameField.delegate = self
        passwardField.delegate = self
        passwardField.secureTextEntry = true
    }

    //ユーザ登録
    @IBAction func signUp() {
        let user = NCMBUser()
        user.userName = nameField.text!
        user.password = passwardField.text!
        user.signUpInBackgroundWithBlock({(NSError error) in
            //ユーザ登録の処理
            if error != nil {
                //ユーザ登録に失敗
                print("error")
            } else {
                //ユーザ登録に成功
                self.dismissViewControllerAnimated(true, completion: nil)
            }
        })
    }
    
    //ログイン
    @IBAction func signIn() {
        NCMBUser.logInWithUsernameInBackground(emailField.text!, password: passwardField.text!,
            block: ({(NCMBUser user, NSError error) in
                //ログインの処理
                if error != nil {
                    //ログインに失敗した時
                    print(error)
                } else {
                    //ログインに成功した時
                    self.dismissViewControllerAnimated(true, completion: nil)
                }
        }))
    }
}

homeViewController.swift

import UIKit
import NCMB

class homeViewController: UIViewController {
    
    @IBOutlet var label: UILabel!

/*  省略  */
    
    override func viewDidAppear(animated: Bool) {
        if NCMBUser.currentUser() != nil {
            label.text = "ようこそ\(NCMBUser.currentUser().userName)さん"
        } else {
            let segueViewController: ViewController = self.storyboard?.instantiateViewControllerWithIdentifier("introView") as! ViewController
            self.presentViewController(segueViewController, animated: true, completion: nil)
        }
    }
    
    @IBAction func signOut() {
        NCMBUser.logOut()
        let segueViewController: ViewController = self.storyboard?.instantiateViewControllerWithIdentifier("introView") as! ViewController
        segueViewController.modalTransitionStyle = UIModalTransitionStyle.PartialCurl
        self.presentViewController(segueViewController, animated: true, completion: nil)
    }

}

3 タイムラインを実装

storyboardのtimeLineViewControllerに

  • UITableView
  • ツイート用のボタン

を設置。
ツイートボタンをtweetViewControllerにつなげる。

timeLineViewController.swift

import UIKit
import NCMB

class timeLineViewController: UIViewController, UITableViewDelegate, UITableViewDataSource {
    
    @IBOutlet var timeLineTable: UITableView!
    
    var tweets = [AnyObject]()
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        timeLineTable.delegate = self
        timeLineTable.dataSource = self
    }
    
    override func viewWillAppear(animated: Bool) {
        self.loadData()
    }
    
    //データの読み込み
    func loadData() {
        tweets.removeAll()
        let query = NCMBQuery(className: "Tweets")
        query.orderByDescending("createDate")
        query.findObjectsInBackgroundWithBlock({(NSArray objects, NSError error) in
            //データ読み込みの処理
            if error != nil {
                //読み込みに失敗したのとき
                print(error)
            } else {
                //読み込みに成功したとき
                if objects.count > 0 {
                    self.tweets = objects
                    self.timeLineTable.reloadData()
                }
            }
        })
    }
    
    func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return tweets.count
    }
    
    func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
        let cell: UITableViewCell = UITableViewCell(style: UITableViewCellStyle.Subtitle, reuseIdentifier: "Cell")
        
        cell.textLabel?.text = tweets[indexPath.row].objectForKey("tweet") as? String
        
        return cell
    }
    
    //セルの編集を許可
    func tableView(tableView: UITableView, canEditRowAtIndexPath indexPath: NSIndexPath) -> Bool {
        return true
    }
    
    //セルが削除された時の処理
    func tableView(tableView: UITableView, commitEditingStyle editingStyle: UITableViewCellEditingStyle, forRowAtIndexPath indexPath: NSIndexPath) {
        let object = NCMBObject(className: "Tweets")
        object.objectId = tweets[indexPath.row].objectForKey("objectId") as? String
        object.fetchInBackgroundWithBlock({(NSError error) in
            //データの取得の処理
            if error != nil {
                //データの取得に失敗した時
                print(error)
            } else {
                //データの取得に成功した時の処理
                object.deleteInBackgroundWithBlock({(NSError error) in
                    //データの削除の処理
                    if error != nil {
                        //削除に失敗した時の処理
                        print(error)
                    } else {
                        //削除に成功した時の処理
                        self.loadData()
                        self.timeLineTable.reloadData()
                    }
                })
            }
        })
    }
}

ツイート機能を実装

storyboardのtweetViewControllerに

  • ツイート用のUITextView
  • 送信ボタン

を設置

tweetViewController.swift

import UIKit
import NCMB

class tweetViewController: UIViewController, UITextViewDelegate {
    
    @IBOutlet var tweetText: UITextView!
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        tweetText.delegate = self
    }
    
    @IBAction func sendTweet() {
        let object = NCMBObject(className: "Tweets")
        object.setObject(tweetText.text!, forKey: "tweet")
        object.setObject(NCMBUser.currentUser().userName, forKey: "createdBy")
        object.saveInBackgroundWithBlock({(NSError error) in
            //データを保存
            if (error != nil) {
                //データの保存に失敗した時
                print(error)
            }else{
                //データの保存に成功した時
                self.navigationController?.popViewControllerAnimated(true)
            }
        })
    }
}

まだまだ手直しするところはありますが、ひとまずはこれで完成です。