NXWineを使ってMacでWinMergeを使う

Windowsでいつも使っているWinMergeMacで使いたかったので、調べてみたところ、
MacWindowsアプリを起動するアプリはいろいろあるがNXWineでWinMergeの起動ができた。

NXWineの紹介

作者のページ


🍎 NXWine - No X11 Wine for OS X 🍷 - 😃 mattintosh note 📝

ダウンロード先


NXWine の使い方まとめ - NAVER まとめ

インストール手順

差運ロード先ページから以下のファイルをダウンロード

NXWine_20130806_1.7.0.dmg

ダウンロードファイルをインストールする

インストールすると、exeファイルに関連づけられる。

WinMergeを取得

WinMergeのページより、zip版の32bit版をダウンロード

WinMerge 日本語版

ダウンロードファイルを解凍して、任意のディレクトリに解凍。

WinMergeを起動

解凍したWinMergeのexeをダブルクリックして実行。

WinMerge/WinMergeU.exe

NXWineに関連づけされていない場合、WinMergeU.exeを右クリックしてメニューを表示し
「このアプリケーションで開く」からNXWineで開くようにすれば多分行ける。

これだけでOK!簡単だった。

EmEditorも動いた

以下のダウンロードサイトより、

ダウンロード - EmEditor (テキストエディタ)

「32 ビット ポータブル」をダウンロードし、任意のディレクトリに解凍して
EmEditor.exe」を起動すればOK。

ショートカット作成

起動用のショートカットは、exeファイルを右クリックして「エイリアスを作成」を選択し
任意の場所に作成すればよい。

Rails4.2とdeviseでFacebookとTwitter認証をテストした時に[Routing Error uninitialized constant]が発生

RailsとdeviseでFacebookTwitter認証をテストしたらログアウト時にエラー

参考情報

RailsとdeviseでFacebookTwitter認証を行う際に、以下のページを参考にした

Rails4 で Devise と OmniAuth で、Twitter/Facebook のOAuth認証と通常フォームでの認証を併用して実装 | EasyRamble
※ほとんどこのページを参考

環境

Rails 4.2.0
ruby 2.1.5p273 (2014-11-13 revision 48405) [x86_64-darwin14.0]
devise 3.4.1
omniauth 1.2.2
omniauth-facebook 1.4.1
omniauth-twitter 1.0.1

エラー内容

ログインはできるがログアウト時に以下のエラーが発生

Routing Error
uninitialized constant Users::SessionsController
エラー対応

sessions_controllerでエラーが出ているので、sessions_controller.rbファイルを作成

devise_test/app/controllers/users/sessions_controller.rb

class Users::SessionsController < Devise::SessionsController

end

※中身は空でOK

これでログアウトエラーは解決!

作業内容まとめ

実行コマンド

プロジェクト作成
$ rails new devise_test
Gemfileに追記

project/Gemfile

...

  gem 'devise'
  gem 'omniauth', '~> 1.2.1'
  gem 'omniauth-twitter', '~> 1.0.1'
  gem 'omniauth-facebook', '~> 1.4.0'
end
モジュールをインストール
$ cd devise_test
$ bundle install
トップページを作成
$ rails g controller welcome index
deviseをインストール
$ rails generate devise:install
      create  config/initializers/devise.rb
      create  config/locales/devise.en.yml
===============================================================================

Some setup you must do manually if you haven't yet:

  1. Ensure you have defined default url options in your environments files. Here
     is an example of default_url_options appropriate for a development environment
     in config/environments/development.rb:

       config.action_mailer.default_url_options = { host: 'localhost', port: 3000 }

     In production, :host should be set to the actual host of your application.

  2. Ensure you have defined root_url to *something* in your config/routes.rb.
     For example:

       root to: "home#index"

  3. Ensure you have flash messages in app/views/layouts/application.html.erb.
     For example:

       <p class="notice"><%= notice %></p>
       <p class="alert"><%= alert %></p>

  4. If you are deploying on Heroku with Rails 3.2 only, you may want to set:

       config.assets.initialize_on_precompile = false

     On config/application.rb forcing your application to not access the DB
     or load models when precompiling your assets.

  5. You can copy Devise views (for customization) to your app by running:

       rails g devise:views

===============================================================================
deviseのユーザモデルを作成
$ rails g devise User
      invoke  active_record
      create    db/migrate/20150103071332_devise_create_users.rb
      create    app/models/user.rb
      invoke    test_unit
      create      test/models/user_test.rb
      create      test/fixtures/users.yml
      insert    app/models/user.rb
       route  devise_for :users
deviseのユーザモデルにOmniAuth用のカラムを追加
$ rails generate migration AddOmniauthColumnsToUsers uid provider name
      invoke  active_record
      create    db/migrate/20150103071704_add_omniauth_columns_to_users.rb
migrationファイルを修正
class AddOmniauthColumnsToUsers < ActiveRecord::Migration
  def change
    add_column :users, :uid, :string,      :string, null: false, default: ""
    add_column :users, :provider, :string, :string, null: false, default: ""
    add_column :users, :name, :string
    
    add_index :users, [:uid, :provider], unique: true
  end
end
migrate実行
$ rake db:migrate
== 20150103071332 DeviseCreateUsers: migrating ================================
-- create_table(:users)
   -> 0.0150s
-- add_index(:users, :email, {:unique=>true})
   -> 0.0017s
-- add_index(:users, :reset_password_token, {:unique=>true})
   -> 0.0008s
== 20150103071332 DeviseCreateUsers: migrated (0.0178s) =======================

== 20150103071704 AddOmniauthColumnsToUsers: migrating ========================
-- add_column(:users, :uid, :string)
   -> 0.0015s
-- add_column(:users, :provider, :string)
   -> 0.0011s
-- add_column(:users, :name, :string)
   -> 0.0014s
== 20150103071704 AddOmniauthColumnsToUsers: migrated (0.0043s) ===============
bootstrapのファイルコピー&定義

bootstrap-3.3.1-dist.zipのファイルを以下にコピー

devise_test/vendor/assets/javascripts/bootstrap.min.js
devise_test/vendor/assets/stylesheets/bootstrap.min.css

bootstrapの定義を追加

devise_test/app/assets/javascripts/application.js

//= require jquery
//= require jquery_ujs
//= require turbolinks
//= require bootstrap.min
//= require_tree .

devise_test/app/assets/stylesheets/application.css

 *= require_tree .
 *= require_self
 *= require bootstrap.min
 */
user.rbの編集
class User < ActiveRecord::Base
  # Include default devise modules. Others available are:
  # :confirmable, :lockable, :timeoutable and :omniauthable
  devise :database_authenticatable, :omniauthable, :registerable,
         :recoverable, :rememberable, :trackable, :validatable

  def self.find_for_facebook_oauth(auth, signed_in_resource=nil)
    user = User.where(:provider => auth.provider, :uid => auth.uid).first
    unless user
      user = User.create(name:     auth.extra.raw_info.name,
                         provider: auth.provider,
                         uid:      auth.uid,
                         email:    auth.info.email,
                         password: Devise.friendly_token[0,20]
                        )
    end
    user
  end
 
  def self.find_for_twitter_oauth(auth, signed_in_resource=nil)
    user = User.where(:provider => auth.provider, :uid => auth.uid).first
    unless user
      user = User.create(name:     auth.info.nickname,
                         provider: auth.provider,
                         uid:      auth.uid,
                         email:    User.create_unique_email,
                         password: Devise.friendly_token[0,20]
                        )
    end
    user
  end
 
  # 通常サインアップ時のuid用、Twitter OAuth認証時のemail用にuuidな文字列を生成
  def self.create_unique_string
    SecureRandom.uuid
  end
 
  # twitterではemailを取得できないので、適当に一意のemailを生成
  def self.create_unique_email
    User.create_unique_string + "@example.com"
  end
 
end
devise定義ファイルにFacebookTwitterのアプリキーを登録
Devise.setup do |config|

...

  # When using omniauth, Devise cannot automatically set Omniauth path,
  # so you need to do it manually. For the users scope, it would be:
  # config.omniauth_path_prefix = '/my_engine/users/auth'
  # API key
  config.omniauth :facebook, "App ID", "App Secret"
  config.omniauth :twitter,  "Consumer Key", "Consumer Secret"
end
route.rbの設定
Rails.application.routes.draw do
  devise_for :users, :controllers => {
    :sessions      => "users/sessions",
    :registrations => "users/registrations",
    :passwords     => "users/passwords",
    :omniauth_callbacks => "users/omniauth_callbacks" 
  }

  root to: 'welcome#index'
end
トップ画面作成
<!DOCTYPE html>
<html>
<head>
  <title>deviseテスト</title>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <%= stylesheet_link_tag    'application', media: 'all', 'data-turbolinks-track' => true %>
  <%= javascript_include_tag 'application', 'data-turbolinks-track' => true %>
  <%= csrf_meta_tags %>
</head>
<body>

  <header class="navbar navbar-default" role="navigation">
    <div class="container">
      <div class="navbar-header">
        <%= link_to 'deviseテスト', root_path, class: 'navbar-brand' %>
      </div>
      <div class="navbar-text pull-right">
        <% if user_signed_in? %>
          Logged in as <strong><%= current_user.name %></strong>.
          <%= link_to 'Edit profile', edit_user_registration_path, :class => 'navbar-link' %> |
          <%= link_to 'Sign out', '/users/sign_out', :method => :delete, :class => 'navbar-link'  %>
        <% else %>
          <%= link_to "Sign up", new_user_registration_path, :class => 'navbar-link'  %> |
          <%= link_to "Login", new_user_session_path, :class => 'navbar-link'  %> |
          <%= link_to "Sign in with Facebook", user_omniauth_authorize_path(:facebook) , :class => 'navbar-link' %> |
          <%= link_to "Sign in with Twitter", user_omniauth_authorize_path(:twitter) , :class => 'navbar-link' %>
        <% end %>
      </div>
    </div>
  </div>
</header>

<div class="container">
  <% if notice %>
    <p class="alert alert-success"><%= notice %></p>
  <% end %>
  <% if alert %>
    <p class="alert alert-success"><%= alert %></p>
  <% end %>
  <%= yield %>
</div>
</body>
</html>
OmniauthCallbacksControllerコントローラーを作成

以下のファイルを作成
devise_test/app/controllers/users/omniauth_callbacks_controller.rb

class Users::OmniauthCallbacksController < Devise::OmniauthCallbacksController
  def facebook
    # You need to implement the method below in your model (e.g. app/models/user.rb)
    @user = User.find_for_facebook_oauth(request.env["omniauth.auth"], current_user)
 
    if @user.persisted?
      set_flash_message(:notice, :success, :kind => "Facebook") if is_navigational_format?
      sign_in_and_redirect @user, :event => :authentication
    else
      session["devise.facebook_data"] = request.env["omniauth.auth"]
      redirect_to new_user_registration_url
    end
  end
 
  def twitter
    # You need to implement the method below in your model
    @user = User.find_for_twitter_oauth(request.env["omniauth.auth"], current_user)
 
    if @user.persisted?
      set_flash_message(:notice, :success, :kind => "Twitter") if is_navigational_format?
      sign_in_and_redirect @user, :event => :authentication
    else
      session["devise.twitter_data"] = request.env["omniauth.auth"].except("extra")
      redirect_to new_user_registration_url
    end
  end
end

このままだとログアウト時にエラーが発生する

ログインはうまくいくが、ログアウトすると以下のエラーが発生する。

Routing Error
uninitialized constant Users::SessionsController
SessionsControllerクラスを作成

エラー対応のため、以下のファイルを作成

devise_test/app/controllers/users/sessions_controller.rb

class Users::SessionsController < Devise::SessionsController

end

今回作成したプロジェクトは以下
yuriken27/rails_devise_test · GitHub

IIJmioで留守番電話を使う方法

IIJmioでは留守番電話サービスがないが、転送サービス&FusionのIP Phoneセットで対応可能。

FusionのIP Phoneは基本料金がかからず使った分だけの支払いなので、
留守番電話を使わなければ料金がかかる事がないのでオススメ。

※3/3追記 IIJmioでも留守番電話サービス(300円/月)が始まったようです

基本料金が安いので、月300円が割高に感じる(^_^;)


留守番電話の動作はこんな感じ

IIJmioに電話がかかってくる
 → 呼び出しのまま設定時間が経過
  → IIJmioからFusion IP Phone SMARTに転送
   → Fusion IP Phone SMARTの留守番電話機能で録音

まずFusion IP Phone SMARTサービスに登録

まずはFusion IP Phone SMARTの登録を行い、IP Phoneの電話番号を取得。
スマホの通話料をトコトン安くする | FUSION IP-Phone SMART

登録完了後、マイページから【各種設定】-【「着信転送/留守番電話設定画面へ」】を選択し、
留守番電話の設定を行う。

「留守番電話設定」を選択して、呼び出し時間を「即時」にしておくと、
電話転送後すぐに留守番電話に切り替わる。

また、「着信メール通知 + 録音データファイルの添付」にしておくと、
留守番電話に登録されたときに録音データがユーザ登録したメールに届くので便利☆

ここでの設定は以上。

IIJmioで転送電話設定

次に、IIJmioの転送電話設定を行う。

転送方法はこちらから
IIJmio:音声オプション

●転送先の電話番号を設定

電話番号「1429」に電話をかけ、音声ガイダンス中に3を押して転送電話設定を選択。

音声ガイダンスに従って転送先の電話番号にIP Phoneの電話番号を設定する。

●転送時間を設定

次に同じく「1429」に電話をかけ音声ガイダンス中に1を押し、
呼び出し時間の設定をしておく。

これで、転送電話に切り替わる秒数、すなわち留守番電話に切り替わる秒数を指定できる。

このように、留守番電話は結構簡単に設定可能。

これはIIJmioでなくても同じように使えるように思います。
録音データがメールで送られてくるから各キャリアの留守番電話よりも少し便利なのでは。

DoCoMoのiPhone5Sを使ってDoCoMoからIIJmio にMNPしてみた

ドコモ&iPhone構成では、月々の携帯料金は節約しても7000円。

毎月の内訳としては、月々のデータ使用量は2GB〜3GBで通話料金も月々1000円行かないくらい。

パケホーダイだけで5200円になりこれ以上料金を節約することができないので、
最近一般的になってきたMVNO(仮想移動体通信事業者)へ乗り換えることにした。


今使っているスマホはSIMフリーではなくドコモで契約したiPhone5Sだけど、
実はドコモの回線を使っているMVNOであればそのまま使える。

ドコモの回線を使っているMVNOの中で、データ通信料や料金などを検討し、IIJmioを選択。

iPhoneへの最新対応状況は公式ブログで確認★
てくろぐ: IIJmio高速モバイル/D iOS別 iPhone・iPad動作状況

今回契約したのは音声通話付きでデータが4GBまで使えるライトスタートプラン
2,220円(税抜)(月額料金:1,520円(税抜)+音声通話機能付帯料:700円(税抜))


メリットは月々の料金がざっくり4000円くらい削減されること。

予想されるデメリットは以下があり。
IIJmioでは留守番電話サービスが使えないのでいろいろ設定が必要

※3/3追記 IIJmioでも留守番電話サービス(300円/月)が始まったようです

IIJmioを使っている人が多いところに行くと、通信速度が遅くなる恐れあり

※3/3追記 ここにも書きましたが、池袋と東新宿周辺では、大体15Mbps以上でます(^^)
IIJmioおすすめポイント - yuriken27's blog

それから、使っているとLINEの年齢認証がMy docomo経由になるが、
IIJmioでは認証できないことが発覚(´・ω・`)
また、電話をかけてからスマホが鳴るまでが遅い気がする・・・要検証。

ドコモからIIJmioに切り替える

IIJmioIIJからの契約以外にもいろいろあるが、
「公衆無線LANサービス Wi2 300」が使えるビックカメラBIC SIMに決定。

ドコモでMNP予約

今回、電話番号を変えたくなかったので、MNPするためにMy docomoからMNP予約番号を取得。

これは、auSoftBankへのMNPと同じ手順。

BIC SIMと契約する

BIC SIMの入手はAmazonなどでもできるが、電話が使えない期間が1〜2日できるようなので、
ビックカメラのカウンターに行って申し込むことにした。

土曜日の開店前5分にビックカメラ 池袋本店に到着。
待っている人は少なく、開店と同時にカウンターを探して整理券を入手。

10時10分頃に受け付け開始。iPadを使って申し込みを行い、10時40分頃に申し込み終了。
1時間ほどでSIMの焼き付けが終わると言うことなので、いったん帰宅。

11時40分ごろにiPhoneが圏外になり、電話が使えない状態に。

その後、ビックカメラでSIMを受け取りiPhone5SのSIMを交換し、
APN構成プロファイルをダウンロードして電波復活♪
※ちなみにwifiなどでネットがつながっているか、PCにつないで設定する必要あり

結局、圏外だった時間は30分ほど。

androidで手動設定する場合

androidでは、[その他の設定]-[モバイルネットワーク設定]-[アクセスポイント名]などから
プロファイルを追加し、以下の項目を入力すればOK。

APN :iijmio.jp
ユーザ名 :mio@iij
パスワード:iij
認証タイプ:CHAPまたはPAP

Dropboxへアクセスするiphoneアプリを作成する手順

dropboxのWeb上でアプリケーションを登録

以下にアクセスしてアプリ登録を行う

https://www.dropbox.com/developers/apps


「create an app」ボタンをクリックし、「core API」を選択し、
「App name」に任意の名前を入力して「Full Dropbox」を選択。

※Platformは必要な項目を選択すること

登録後に以下の画面で「App key」と「App secret」を確認。

f:id:yuriken27:20130609232643p:plain:w400

■DropboxSDKをダウンロード

以下のページからiOS用のSDKをダウンロードする。

https://www.dropbox.com/developers/core/sdk

xcodeでアプリケーションを作成

xcodeプロジェクト作成とDropboxFrameworkを追加

Single View Applicationで新規プロジェクトを作成。

アプリの対象バージョンを「5.0」に変更。

作成したxcodeプロジェクトにDropboxFrameworkを追加。

FinderでSDKに入っている「DropboxSDK.framework」ディレクトリを
xcodeに移動する。

f:id:yuriken27:20130609235106p:plain

移動後、以下の画面のように設定してOKを押す。
f:id:yuriken27:20130609235457p:plain

このほか、以下の2つを追加
・QuartzCore.framework
・Security.framework

f:id:yuriken27:20130610001037p:plain

AppDelegate.m

インポート文を追加

#import <DropboxSDK/DropboxSDK.h>

「application:didFinishLaunchingWithOptions」に以下のコードを追加

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
    // Override point for customization after application launch.
    
    // ここから追加
    DBSession* dbSession =
    [[DBSession alloc]
     initWithAppKey:@"xxxxxxxxxxxxxxx"
     appSecret:@"xxxxxxxxxxxxxxx"
     root:kDBRootDropbox]; // either kDBRootAppFolder or kDBRootDropbox
    [DBSession setSharedSession:dbSession];
    // ここまで

    return YES;
}
// 以下の関数も追加
- (BOOL)application:(UIApplication *)application handleOpenURL:(NSURL *)url {
    if ([[DBSession sharedSession] handleOpenURL:url]) {
        if ([[DBSession sharedSession] isLinked]) {
            NSLog(@"App linked successfully!");
            // At this point you can start making API calls
        }
        return YES;
    }
    // Add whatever other url handling code your app requires here
    return NO;
}

「xxxxxxxxxxxxxxx」には、DropboxのWebで登録したアプリの「App key」と「App secret」を登録

ViewController.h

DropboxSDK.hのインポート追加と「DBRestClientDelegate」デリゲートを追加し、
DBRestClientのプロパティをセット。

#import <UIKit/UIKit.h>
#import <DropboxSDK/DropboxSDK.h>

@interface ViewController : UIViewController <DBRestClientDelegate>

@property (nonatomic, readonly) DBRestClient *restClient;

@end

ViewController.m

まずは、先頭付近にrestClientのsynthesizeを追加。

@implementation ViewController
@synthesize restClient = _restClient;


以下のコードを追加。

- (DBRestClient *)restClient {
    if (!_restClient) {
        _restClient =
        [[DBRestClient alloc] initWithSession:[DBSession sharedSession]];
        _restClient.delegate = self;
    }
    return _restClient;
}

// ビュー表示後に、ログイン済みかチェックし、未ログインならばログイン画面を表示
-(void) viewDidAppear:(BOOL)animated
{
    [super viewDidAppear:animated];
    
    if (![[DBSession sharedSession] isLinked]) {
        [[DBSession sharedSession] linkFromController:self];
    }
    // Dropbox読み込み
    [[self restClient] loadMetadata:@"/"];   
}

Dropbox読み込みのコールバック関数を追加

- (BOOL)application:(UIApplication *)application handleOpenURL:(NSURL *)url {
    if ([[DBSession sharedSession] handleOpenURL:url]) {
        if ([[DBSession sharedSession] isLinked]) {
            NSLog(@"App linked successfully!");
            // At this point you can start making API calls
        }
        return YES;
    }
    // Add whatever other url handling code your app requires here
    return NO;
}

- (void)restClient:(DBRestClient *)client loadedMetadata:(DBMetadata *)metadata {
    if (metadata.isDirectory) {
        NSLog(@"Folder '%@' contains:", metadata.path);
        for (DBMetadata *file in metadata.contents) {
            NSLog(@"\t%@", file.filename);
        }
    }
}

DropboxTest-Info.plist

ファイルを右クリックし、「Open As」ー「Source Code」で開き、
ファイルの最後のとの間に以下のコードを挿入。

    <key>CFBundleURLTypes</key>
    <array>
        <dict>
            <key>CFBundleURLSchemes</key>
            <array>
                <string>db-APP_KEY</string>
            </array>
        </dict>
    </array>

「db-APP_KEY」のAPP_KEYにDropboxのWebで登録したアプリの「App key」をセット。

例:db-xxxxxxxxxxxxxxx

起動テスト

アプリを起動して以下の画面が表示されたれ
自分のID、パスワードを指定してOKを押す。

f:id:yuriken27:20130610005206p:plain

コンソールにDropboxのトップディレクトリのファイル、ディレクトリ内容が表示されたら
ログインに成功!

タブコントローラーアプリにナビゲーションバーを追加する

タブコントローラー(UITabBarController)に
ナビゲーションバー(UINavigationController)を追加してみた。



まずは新規プロジェクトで「Tabbed Application」を選択してプロジェクトを作成。

作成したプロジェクトのストーリーボードを開く。

f:id:yuriken27:20130606220130p:plain:w600

FirstViewをざっくり削除
f:id:yuriken27:20130606220129p:plain:w600

代わりにNavigationControllerを配置して
f:id:yuriken27:20130606220128p:plain:w600

タブビュー上で右クリックして、クリックしたままNavigationControllerまでドラッグして放し、
「view controllers」を選択
f:id:yuriken27:20130606220125p:plain:w600

これでつながって、

f:id:yuriken27:20130606220126p:plain:w600

実行したらこんな感じ。
f:id:yuriken27:20130606220124p:plain


かんたん!

iPhoneアプリ「もうすぐアラーム」を作成しました(^o^)

iPhoneアプリ「もうすぐアラーム」を作成しました。

iTunes App Storeで見つかる iPhone 3GS、iPhone 4、iPhone 4S、iPhone 5、iPod touch(第3世代)、iPod touch (第4世代)、iPod touch (第5世代)、およびiPad 対応のもうすぐアラーム

あらかじめ指定していた場所に着くと、アラームで知らせるアプリです。

電車などで目的地の駅を設定しておけば目的地日が付くとアラームが鳴り、乗り過ごし防止に使えます。

しかし、大きな弱点が・・・

それは、「アプリがバックグラウンドの時、アラームが鳴らない!」

なんだか、アプリの機能が80%カットされた気分です(´・ω・`)

もともとバックグラウンドでも音が鳴るようにしていたのですが、
アップルによるアプリのレビューで
「バックグラウンドで音をならしていいのは、音楽アプリやストリーミングアプリに限る」
と、指摘されたため。

なんどか交渉したのですが、認められませんでした・・・

そして、泣く泣くバックグラウンドでの再生設定を削除してアプリを申請し、
無事、リリースまでこぎ着けました。

アプリ画面紹介

まずは初期画面から。

右上の「新規追加」ボタンを押すと、目的地の登録画面が開きます。

f:id:yuriken27:20130526223116p:plain:w350


登録画面で目的地を指定し、

f:id:yuriken27:20130526223223p:plain:w350


登録した目的地を探索し、現在位置が目的地の周りの円に入ったら知らせます。
f:id:yuriken27:20130526222731p:plain:w350

無料で公開しているので、試してみてください!