No such module と戦う
No such module ~ のエラーに悩まされたので覚え書き。
PROJECT の build setting のframework search path に "${PODS_CONFIGURATION_BUILD_DIR}/ライブラリ名" を追記するとエラーが消えた。
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ファイルを作成します。
するとこのような画面が出てくるので
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のサイトにアクセスし、レポートのリアルタイム確認ページを開きます。
アクティブユーザが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) }
あとは関連付けをして完成です!
<Swift> UIImageViewをドラッグしてみた
環境
- Xcode7.2.2
- Swift 2.1.1
まずはデリゲートの宣言と動かす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
機能
- ユーザ登録
- テキストを投稿
- 投稿したテキストをタイムラインに表示
完成品はこんな感じです
手順
※NiftyColud mobile backend の導入は省きます
1 必要なパーツを配置
- ログイン・会員登録を行うViewController
- ユーザネームを表示するhomeViewController
- タイムラインを表示するtimeLineViewController
- ツイートを投稿するtweetViewController
それぞれのViewに設置したUIパーツは後述します。
ストーリーボードはこんな感じです。わかりにくくてすいません。
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) } }) } }
まだまだ手直しするところはありますが、ひとまずはこれで完成です。