【swift】アプリ内でmailerを立ち上げてーバグリポート機能の実装【CoffeeNote開発記録】

参考にさせていただいたサイト

MFMailComposeViewController Class Reference

アプリから画像を添付してメールを送信する方法 | CrossBridge

MFMailComposeViewController - Send email in your apps

準備

  • プロジェクトのターゲットのところから、MessageUI.frameworkをプロジェクトに追加する。

  • MessageUIをimportして、MFMailComposeViewControllerDelegateを追加。

import MessageUI

class SettingViewController: UIViewController, MFMailComposeViewControllerDelegate {
    // 省略
}

コーディング

そしたらMFMailComposerViewControllerクラスのメソッドを使ってメールを送る処理を書いていく。

メソッド一覧は以下。

MFMailComposeViewController Class Reference

実際の処理の流れは以下のようになる

  1. canSendMailメソッドでメールの送信が可能か確認する
  2. MFMailComposeViewControllerクラスのインスタンスを生成
  3. delegate(CMFMailComposeViewControllerDelegate)を設定
  4. 必要に応じてメールの件名/宛先(TO,CC,BCC)/添付ファイル/本文を設定する モーダルでビューを表示する

ソースは以下

  @IBAction func reportButtonPushed(sender: AnyObject) {
    
    // check if can send an email
    if MFMailComposeViewController.canSendMail()==false {
      println("Email Send Failed")
      return
    }
    
    var mailViewController = MFMailComposeViewController()
    
    mailViewController.mailComposeDelegate = self
    
    mailViewController.setSubject("Bug Report")
    
    var toRecipients = ["yuta.totz@gmail.com"]
    mailViewController.setToRecipients(toRecipients)
    
    mailViewController.setMessageBody("", isHTML: false)
    
    self.presentViewController(mailViewController, animated: true, completion: nil)
  }

このままだと表示されたメールの画面が閉じないので、閉じる処理を書いていく

メールのアプリを送信完了/失敗するか、キャンセルボタンが押されるとdidFinishWithResultメソッドが呼ばれるのでこれを利用する。

switch文でMFMailComposeResultSavedとかを使うときにエラーがでたが、以下の記事で解決。

switch statement - Sending emails - MFMailComposeResult - Stack Overflow

こんな感じ。

  func mailComposeController(controller: MFMailComposeViewController!, didFinishWithResult result: MFMailComposeResult, error: NSError!) {
    
    switch result.value {
    case MFMailComposeResultCancelled.value:
      println("Email Send Cancelled")
      break
    case MFMailComposeResultSaved.value:
      println("Email Saved as a Draft")
      break
    case MFMailComposeResultSent.value:
      println("Email Sent Successfully")
      break
    case MFMailComposeResultFailed.value:
      println("Email Send Failed")
      break
    default:
      break
    }
    
    self.dismissViewControllerAnimated(true, completion: nil)
  }

【swift】半角全角を判定してフォントを使い分けてサイズとかも変更する【CoffeeNote開発記】

だいたいのローカライズが済んだときに申請前のテストでいじってたら、日本語のときにすげーださくなってるときに気付いた。

こんな感じ。

photo 2.PNG

英語かっこいいのに、日本語だせぇ。。

ということでシステム設定言語に応じてフォントを切り替える設定をしてみようと思ったのだけど。

なんかstackoverflowとかでは対処法としてそのときの位置情報を取得する、ってのがあったけどそれだと設定してる言語とずれることがたびたび生じそうだったので、twitterでつぶやくと以下のようなリプライをいただいた。

返り値の配列の一つ目に設定している言語が返ってくるらしい。

ということでこれならできそう。

こんな記事も参考にしながら。

iOSの言語設定に応じて設定されるNSLocaleの値について簡単にまとめてみる - Qiita

...と思ったら

英語と日本語の混在する可能性もあることに気付いた。

その可能性を考慮したほうがいいと思ったので、 半角と全角を判定してフォントを切り替えるという方法をとることにした。

以下のサイトによると

NSString 半角・全角の判定 - Qiita

- canBeConvertedToEncoding:を使うといいと書いてあったので使ってみるけどswiftで書き換えてみたら、自分の実力不足のせいでうまくいかず笑

公式リファレンスをのぞいてみると dataUsingEncoding:allowLossyConversion:が代わりに推奨されていたのでそっちを使うことにした。

NSString Class Reference

そしてソースは以下のような感じに。

    // set propety font for title
    if ((cell.titleLabel.text?.dataUsingEncoding(NSASCIIStringEncoding, allowLossyConversion: false)) != nil) {
      cell.titleLabel.font = UIFont(name: "HelveticaNeue-UltraLight", size: 42.0)
    }else {
      cell.titleLabel.font = UIFont(name: "HiraKakuProN-W3", size: 32.0)
      cell.titleLabel.alpha = 0.8
    }

これをcellForRowAtIndexPathのメソッドの最後の部分に突っ込んでcellごとにフォントを変えれるようにしてる。

フォントを変更してサイズを調整、あとフォントの違いを埋めるために透明度の調整もしてる。

画面はこんな感じに。

photo 1.PNG

日本語のフォント

英語はめちゃくちゃ種類あるのだけど、日本語はイマイチぱっとくるフォントがなかった。。

以下から標準でインストールされてるフォントの一覧がみれる。

iOS 6:フォントリスト - Apple サポート

標準では4種類くらいしか日本語のフォントはない。どんまい。。

【swift】複数のアドの設定をAdMobメディエーションで設定(NendとiAdとAdMob)【CoffeeNote開発日記】

友人にたのんでいたアイコンのデザインがなかなかいい感じになってきたのでそろそろ本気でCoffeeNoteリリースできるかなぁと思えてきたところで、最後の最後にやらなければいけない作業がアドの設定。

多分かなりめんどくさいと予測。でも頑張る。

iOSのアドについて一通りいろいろなサービスの比較記事とかを読んで、結論Nend、iAd、AdMobでいくことにした。

3つを切り替えてうまくFillされない確率を減らして、ePCMが大きいアドを表示するようにしたいところ。

とうことで、今回完全合致だったこの記事にお世話になりながら広告を設定してみる。

http://kojisatoapp.blogspot.jp/2014/03/admobnendiadadmob.html

各サービスへの登録

まずすることは各サービスへの登録

  • nend

http://nend.net/

アプリをリリースしていなくても登録はできるらしい。3日以内にアプリの審査の結果が返ってくるらしいけど、リリースしていないものの場合どうなるんだろ。

  • AdMob

https://apps.admob.com/

  • iAd

ここを参考に

http://codewithchris.com/iad-tutorial/

これがめっちゃめんどかった。


ここまでだけで結構時間かかった...。

AdMobエディメーション設定

AdMobのダッシュボードの広告の設定画面からエディメーション設定にいける。

そこでiAdとNendを追加。

とりあえずNendは保留でiAdだけ追加して先に進むことにする。

SDKのダウンロード

各アドのSDKをダウンロード。

http://developers.google.com/mobile-ads-sdk/download#downloadios

  • iAdアダプター

http://developers.google.com/mobile-ads-sdk/docs/admob/mediation-networks?hl=ja

自分のダッシュボードのAdのところの広告枠のところからSDL最新版をダウンロード


ダウンロードできたら、それぞれXcodeのプロジェクトにぶっこんでおく。

frameworkいろいろ設定

Xcodeのプロジェクトのところで下記のframeworkをインポートしておく

(TARGETS→General→Linked Frameworks and Libraries→+)

  • AdSupport.framework
  • AudioToolbox.framework
  • AVFoundation.framework
  • CoreGraphics.framework
  • MessageUI.framework
  • StoreKit.framework
  • SystemConfiguration.framework
  • CoreTelephony.framework
  • iAd.framework
  • Security.framework

PROJECT→BuildSettings→Linking→Other Linker Flagsに「-ObjC」を追加する。DebugとRelease両方。

Ad実装(swift

ここあたりを参考に

http://stackoverflow.com/questions/24760156/xcode-6-swift-ads-googlemobileadssdkios

Bridging-Header.hでGADBannerView.hをimport

#import "GADBannerView.h"

GADBannerDelegateを追加

// 冒頭
class ViewController: UIViewController, GADBannerViewDelegate {

viewDidAppearで広告の生成の部分を作成

override func viewDidAppear(animated: Bool)  {
    super.viewDidAppear(animated)

    var origin = CGPointMake(0.0,
        self.view.frame.size.height -
            CGSizeFromGADAdSize(kGADAdSizeBanner).height); // place at bottom of view

    var size = GADAdSizeFullWidthPortraitWithHeight(50) // set size to 50
    var adB = GADBannerView(adSize: size, origin: origin) // create the banner
    adB.adUnitID = MY_BANNER_UNIT_ID  //"ca-app-pub-XXXXXXXX/XXXXXXX"
    adB.delegate = self // ??
    adB.rootViewController = self // ??
    self.view.addSubview(adB) // ??
    var request = GADRequest() // create request
    request.testDevices = [ GAD_SIMULATOR_ID ]; // set it to "test" request
    adB.loadRequest(request) // actually load it (?)
}

うーん、まぁstack over flowの回答ではviewDidAppearで読んでたけど、画面が読まれるために実行される必要もない気がするので、これはviewDidLoadで自分はいい気がする。僕はそうしました。

やったーーーーーーーーー表示された!!!!嬉しい