2016年11月18日金曜日

【UIデザイン】Scketchを使ってみた

どーもこんにちは。ありかわです。

ちょっと前からUIデザイナー界隈でSketchが流行ってるみたいなんで、遅ればせながらSketchつこてみました。

最初は使い方おぼえるの大変そうとか色々ネガティブな感じで見てたのですが、、
使ってみたらこれめちゃくちゃ便利です!しかもちょーわかり易い!

いつもはPhotoshopとか使ってUIデザインしてたのですが、SketchがあればPhotoshopいりまへん。
Photoshopはやっぱりすごいんですけど、機能がありすぎて僕みたにちょっとUIデザインする
程度だと手にあまる感じなんですよね。
SketchはほんとにUIデザインに特化した感じで直感的にデザインできちゃいます。

触り始めたばかりの僕がわーわー言ってもあれなんで、興味ありましたら↓からDLできますので是非。
30日間無料トライアルあります。

https://www.sketchapp.com



画面はこんな感じ。ボタン等のUI部品はあらかじめ用意されてます。


あとiOSアプリのUIデザインする時は「Sketch Mirro」ってアプリをiPhoneに入れてると
iPhoneをMacにつなげるだけで、Sketch上で作ったUIデザインをiPhoneで確認することができるんですよ。

Sketchでデザインした画面が実機上に!


すごく便利!


それじゃまた。



おすすめアプリ 暇つぶしに最適!無料で遊べるひっぱりシューティング - HIPPARI Bang Bee

2016年11月11日金曜日

【iOS10】UnityのAdMobプラグインを使う時の対応




こんにちは。ありかわです。

先日弊社のゲームアプリ「HIPPARI Bang Bee」をリリースしようとした際、Appleから
↓のメールが来てすんなりリリースさせてくれませんでした。


Dear developer,
We have discovered one or more issues with your recent delivery for "HIPPARI Bang Bee". To process your delivery, the following issues must be corrected:
This app attempts to access privacy-sensitive data without a usage description. The app's Info.plist must contain an NSCameraUsageDescription key with a string value explaining to the user how the app uses this data.
Once these issues have been corrected, you can then redeliver the corrected binary.
Regards,
The App Store team


何やらよくわからなかったのですが、調べてみるとiOS10からカメラやらカレンダーやら
デリケートな情報にアクセスする場合はinfo.plistファイルにパーミッションを追加する必要があるとのことでした。

「HIPPARI Bang Bee」でそんな情報にアクセスするようなことしてないのになぁ。。
何言っちゃってんの?と思ってさらに調べてみるとUnityのAdMobプラグインがその辺の情報にアクセスしてるみたいです。

「HIPPARI Bang Bee」はUnityで作っててAdMobのプラグインも使ってました。。

んでinfo.plistに以下のパーミッションを追加してやると通してくれました。


<key>NSCameraUsageDescription</key>
<string> Description </string>
<key>NSLocationWhenInUseUsageDescription</key>
<string> Description </string>



それじゃまた。


おすすめアプリ 暇つぶしに最適!無料で遊べるひっぱりシューティング - HIPPARI Bang Bee

2016年11月1日火曜日

HIPPARI Bang Bee リリースしました!




こんにちは。新事業部のありかわです。

先日、弊社アプリ第2弾「HIPPARI Bang Bee」のiOS版をリリースいたしました!
本アプリはいわゆるひっぱりシューティングです。
ボールを飛ばして画面上のまっくろ●●すけ的なやつを全てやつけるとステージクリアです。
ぜひ全ステージ星3つ目指して遊んでみてください。
もちろん無料ですよ!


それじゃまた。

2016年10月27日木曜日

Unityで作ったアプリがメモリリーク!




どーもお久しぶりです。新事業部のありかわです。

最近Unityでゲームアプリを作っているのですが
久々にメモリリークではまってしまいました。

Unityに限らずオブジェクト指向言語ならGCが組み込まれていても、
オブジェクトへの参照が残りっぱなしになる状態が続くと
参照されてるオブジェクトは破棄されず、メモリリークになります。
当たり前ですけど。

そういった観点で色々調べて、Webでも

【Unity】DestroyしたオブジェクトのMaterialがリークする問題への対応
とか

DestroyしてUnloadUnusedAssetsしてもアセットがアンロードされない場合がある話
とか

参考にさせて頂いたのですが一向に原因がわからずめちゃくちゃ困ってました。

Unityファ○ク!!とか思ってたら、、AdMobのプラグインの使い方ミスってたのが原因でした。
Unityさんごめんなさい。

UnityでAdMobの広告を表示するのにBannerView、InterstitialAdといったクラスを使うんですが
使い終わったら各クラスのDestroy()メソッドを呼び出さないとリークの原因になるみたいです。

↓公式のサイトに書いてました。
ゲーム デベロッパー向け: 広告に関するおすすめの方法

ちゃんと読めや!って話ですよね。

それじゃまた。


2016年10月21日金曜日

ASP.NET Identityを利用して独自ユーザーを作る(後編)

今回はログインとパスワード変更です。

ログイン


前回登録したユーザーでログインしようとすると、またエラーが発生します。

Store does not implement IUserLockoutStore<TUser>.


var result = await SignInManager.PasswordSignInAsync(model.Email, model.Password, model.RememberMe, shouldLockout: false);
switch (result) {

どうしたものかとググってみると、このメソッドをオーバーライドしているサイトを見つけました。
同じようにオーバーライドします。

あとは、ストアクラスにパスワード取得メソッドを実装すればOKです。
public class ApplicationUserStore : IUserStore<ApplicationUser>, IUserPasswordStore<ApplicationUser>
{
    public Task<string> GetPasswordHashAsync(ApplicationUser user)
    {
        return Task.FromResult(user.PasswordHash);
    }
}

パスワード変更


パスワードの変更画面でパスワードを変更しようとすると、またまたエラーが発生します。

ストアは IUserEmailStore<TUser> を実装していません。


var result = await UserManager.ChangePasswordAsync(User.Identity.GetUserId(), model.OldPassword, model.NewPassword);
if (result.Succeeded) {

もうお分かりですよね?
ChangePasswordAsyncをオーバーライドします。
public override async Task<IdentityResult> ChangePasswordAsync(string userId, string currentPassword, string newPassword)
{
    var store = (ApplicationUserStore)this.Store;
    var user = await store.FindByIdAsync(userId);
    var result = await VerifyPasswordAsync(store, user, currentPassword);
    if (!result)
    {
        return IdentityResult.Failed("パスワードが正しくありません。");
    }
 
    var identifyResult = await UpdatePassword(store, user, newPassword);
    if (!identifyResult.Succeeded)
    {
        return identifyResult;
    }
 
    await store.UpdateAsync(user);
    return IdentityResult.Success;
}

必要なメソッドをストアクラスに実装します。
public class ApplicationUserStore : IUserStore<ApplicationUser>, IUserPasswordStore<ApplicationUser>
{
    public Task<ApplicationUser> FindByIdAsync(string userId)
    {
        return this._context.ApplicationUsers.SingleOrDefaultAsync(x => x.Id == userId);
    }
 
    public Task UpdateAsync(ApplicationUser user)
    {
        return this._context.SaveChangesAsync();
    }
}

これでパスワード変更ができました。

またいつか、どこかで。

2016年10月14日金曜日

ASP.NET Identityを利用して独自ユーザーを作る(前編)

ASP.NET Identityを初めて使っています。

非常に便利なのですが、VisualStudioでMVCテンプレートを選択して作成したプロジェクトでは、IdentityUserを継承しているためにメールアドレスや電話番号等が含まれており、シンプルに名前とパスワードだけを使いたいような場合にはオーバースペックですよね。
そこで、生成したプロジェクトをベースに、必要最小限のユーザー情報で登録・ログインなどができるように変更してみたいと思います。

ApplicationUserをIUserを実装するように変更し、パスワードを追加します。
public class ApplicationUser : IUser
{
    public string Id { get; set; }
 
    public string UserName { get; set; }
 
    public string PasswordHash { get; set; }
 
    public async Task<ClaimsIdentity> GenerateUserIdentityAsync(UserManager<ApplicationUser> manager)
    {
        var userIdentity = await manager.CreateIdentityAsync(this, DefaultAuthenticationTypes.ApplicationCookie);
        return userIdentity;
    }
}

コンテキストをDbContext派生にします。
public class ApplicationDbContext : DbContext
{
    public ApplicationDbContext()
        : base("DefaultConnection")
    {
    }
 
    public static ApplicationDbContext Create()
    {
        return new ApplicationDbContext();
    }
 
    public DbSet<ApplicationUser> ApplicationUsers { get; set; }
}

IUserStoreを実装するストアクラスを新しく作ります。
public class ApplicationUserStore : IUserStore<ApplicationUser>
{
    private ApplicationDbContext _context;
 
    public ApplicationUserStore(ApplicationDbContext context)
    {
        this._context = context;
    }
 
    // IUserStoreインターフェースの実装は省略
}

作成したストアをユーザーマネージャーのコンストラクタに渡します。
public class ApplicationUserManager : UserManager<ApplicationUser>
{
    public ApplicationUserManager(IUserStore<ApplicationUser> store)
        : base(store)
    {
    }
 
    public static ApplicationUserManager Create(IdentityFactoryOptions<ApplicationUserManager> options, IOwinContext context) 
    {
        var manager = new ApplicationUserManager(new ApplicationUserStore(context.Get<ApplicationDbContext>()));
 
        // 省略

        return manager;
    }
}

これでビルドが通るようになりました。
デバッグを開始し、登録しようとするとエラーが発生します。

ストアは IUserPasswordStore<TUser> を実装していません。


{
    var user = new ApplicationUser { UserName = model.Email, };
    var result = await UserManager.CreateAsync(user, model.Password);
    if (result.Succeeded)
    {

ということで、ストアクラスにIUserPasswordStoreも実装します。
public class ApplicationUserStore : IUserStore<ApplicationUser>, IUserPasswordStore<ApplicationUser>
{
    private ApplicationDbContext _context;
 
    public ApplicationUserStore(ApplicationDbContext context)
    {
        this._context = context;
    }
 
    public void Dispose()
    {
    }
 
    public Task<ApplicationUser> FindByNameAsync(string userName)
    {
        return this._context.ApplicationUsers.SingleOrDefaultAsync(x => x.UserName == userName);
    }
 
    public Task SetPasswordHashAsync(ApplicationUser user, string passwordHash)
    {
        return Task.Run(() => user.PasswordHash = passwordHash);
    }
 
    // その他のインターフェースの実装は省略
}

再度、登録しようとするとまたエラーが発生しました。

ストアは IUserEmailStore<TUser> を実装していません。


{
    var user = new ApplicationUser { UserName = model.Email, };
    var result = await UserManager.CreateAsync(user, model.Password);
    if (result.Succeeded)
    {

IUserPasswordStoreはまだしも、さすがにIUserEmailStoreを実装するわけにはいきません。
CreateAsyncメソッドをオーバーライドすることにしました。
public class ApplicationUserManager : UserManager<ApplicationUser>
{
    public override async Task<IdentityResult> CreateAsync(ApplicationUser user, string password)
    {
        var store = (ApplicationUserStore)this.Store;
        var identityResult = await UpdatePassword(store, user, password);
        if (!identityResult.Succeeded)
        {
            return identityResult;
        }
 
        await store.CreateAsync(user);
        return IdentityResult.Success;
    }
}

ストアクラスの作成処理はこんな感じです。
public class ApplicationUserStore : IUserStore<ApplicationUser>, IUserPasswordStore<ApplicationUser>
{
    public Task CreateAsync(ApplicationUser user)
    {
        user.Id = Guid.NewGuid().ToString();
        this._context.ApplicationUsers.Add(user);
        return this._context.SaveChangesAsync();
    }
}

これで登録ができるようになりました。
次回はログインです。

またいつか、どこかで。

2016年10月7日金曜日

AdMobのアカウント



新事業部のありかわです。

先日、アプリで広告収入を得るためにAdMobのアカウントを作ろうとしたら

「 申し訳ございませんが、現時点では、お客様は AdMob をご利用いただけません。」
とか言われて作ることができませんでした。

いろいろ調べてたら、AdMobのアカウントを作るために使用したGoogleアカウントの生年月日が
1999年になっていました。(会社用のアカウントなので弊社創業日になってました。)
今年は2016年だから17歳なんですよねー。
AdMobのアカウントは18歳からしか作れないのです。

会社用のGoogleアカウントでAdMobのアカウントを開設する方は気をつけて!


それじゃまた。