【C#】【iOS】In-AppPurchaseレシートの検証-Consumableバージョン

あけおめにゃん。

iOS側は省略。ググればあるにゃん。
サーバーサイドはPHPだといっぱいあるんだけど、C#はあんまないから書いとくにゃん。

とりあえずデシリアライズ用のクラスさんたち。


    [DataContract]
    public class VerifyReceiptResult
    {
        [DataMember]
        public int status { get; set; }

        [DataMember]
        public string environment { get; set; }

        [DataMember]
        public virtual Receipt receipt { get; set; }
    }

    [DataContract]
    public class Receipt
    {
        [DataMember]
        public string receipt_type { get; set; }

        [DataMember]
        public int adam_id { get; set; }

        [DataMember]
        public int app_item_id { get; set; }

        [DataMember]
        public string bundle_id { get; set; }

        [DataMember]
        public string application_version { get; set; }

        [DataMember]
        public int download_id { get; set; }

        [DataMember]
        public int version_external_identifier { get; set; }

        [DataMember]
        public string request_date { get; set; }

        [DataMember]
        public long request_date_ms { get; set; }

        [DataMember]
        public string request_date_pst { get; set; }

        [DataMember]
        public string original_purchase_date { get; set; }

        [DataMember]
        public long original_purchase_date_ms { get; set; }

        [DataMember]
        public string original_purchase_date_pst { get; set; }

        [DataMember]
        public string original_application_version { get; set; }

        [DataMember]
        public virtual ICollection<Purchase> in_app { get; set; }
    }

    [DataContract]
    public class Purchase
    {
        [DataMember]
        public int quantity { get; set; }

        [DataMember]
        public string product_id { get; set; }

        [DataMember]
        public long transaction_id { get; set; }

        [DataMember]
        public long original_transaction_id { get; set; }

        [DataMember]
        public string purchase_date { get; set; }

        [DataMember]
        public long purchase_date_ms { get; set; }

        [DataMember]
        public string purchase_date_pst { get; set; }

        [DataMember]
        public string original_purchase_date { get; set; }

        [DataMember]
        public long original_purchase_date_ms { get; set; }

        [DataMember]
        public string original_purchase_date_pst { get; set; }

        [DataMember]
        public bool is_trial_period { get; set; }
    }


んで、Appleからレシート情報取得

            var serializer = new DataContractJsonSerializer(typeof(VerifyReceiptResult));
            VerifyReceiptResult verifyReceiptResult;

            using (var client = new HttpClient())
            using (var content = new StringContent(@"{""receipt-data"":""" + "クライアントから受け取ったレシートデータ" + @"""}"))
            {
                content.Headers.ContentType = new MediaTypeHeaderValue("application/json");

                var response = client.PostAsync(@"https://buy.itunes.apple.com/verifyReceipt", content).Result;
                var resultByteArray = response.Content.ReadAsByteArrayAsync().Result;
                var resultStream = new MemoryStream(resultByteArray);
                verifyReceiptResult = (VerifyReceiptResult)serializer.ReadObject(resultStream);
            }

            if (verifyReceiptResult.status == 21007)
            {
                using (var client = new HttpClient())
                using (var content = new StringContent(@"{""receipt-data"":""" + "クライアントから受け取ったレシートデータ" + @"""}"))
                {
                    content.Headers.ContentType = new MediaTypeHeaderValue("application/json");

                    var response = client.PostAsync(@"https://sandbox.itunes.apple.com/verifyReceipt", content).Result;
                    var resultByteArray = response.Content.ReadAsByteArrayAsync().Result;
                    var resultStream = new MemoryStream(resultByteArray);
                    verifyReceiptResult = (VerifyReceiptResult)serializer.ReadObject(resultStream);
                }
            }

            if (verifyReceiptResult.status == 0)
            {
                // コイン付与とか
            }



verifyReceiptResultにデシリアライズされて値が入ってるので、あとはよしなに。
transaction-idは未使用かどうか自前で管理する必要があるぉ。
StringContentはPostAsyncが終わると破棄されるらしーぉ。




【その他】2014年振り返りと2015年目標

気付けばこんな時間っすね。つーか今日大晦日っすね。
もう仕事納めよう。納まってないけど納まったことにしよう。
あんまり仕事、仕事になるのもよくない、うん。
自分で言うのもなんだけど頑張ったから、許して下さいw
前職は運用で土日、深夜関係なく突然仕事が発生。独立してからは仕事、仕事、仕事だったのでたまにはちゃんと休もうと思います。来年は3日まで仕事しません。



とゆーわけで2014年振り返り。
仕事もプライベートも色々ありました。はい。
とりあえず会社員辞めました。
会社員辞めて、独立して、ある日なぜかベンチャー執行役員 CTOに就任して会社員に舞い戻り。
収入きつくなったので、自営業再開し、今に至る。



2014年よかった点

・引っ越した
新築マンションっていいですね。いい加減養生外れてほしいですが。

・ネットがWiMAX2→光になった
全く何も困ってなかったんだけど、マンションに無料でついてたので。
S3にアップロードするのに6時間掛ってた処理が30分になった。

・PC用品買いまくり
節税という大義名分の元に欲しいものは大体買いつくしました。

・人脈広がった
あんま人脈、人脈言うやつ好きじゃないんだけどね。他に適当な言葉が見つからないので。人脈っていうか仲良くしてくれる人?仲良くしてくれる人大事。
会社員時代じゃ考えられないくらい多くの人と出会った年でした。

・新しい技術にチャレンジした
ってゆーか絶賛チャレンジ中。フリーランスってほんと技術が選べていい。
もちろん結果がついてこないとだめなんですが。結果出せるように頑張ります。

なんか独立してよかったことみたいになっちゃった。仕事しかしてないからしゃーない。

2015年目標

・サービスリリース
うん、CTOの会社のサービスね。
予定より遅れましたが、そろそろ出します。

・貯金
2014年現在まさかの貯金ほぼ0。何に使ったんだろう。

・契約してる仕事を無事終わらせる
がんばるよ。いや、がんばってるよ。

・事業拡大
うん。お陰様で色々お話を頂いているので、今契約してる仕事終わったら真面目に動こうと思っております。

とゆーわけで今年一年お世話になった方々、大変ありがとうございました。
相変わらず適当な感じで過ごしていきますが、来年もどうぞよろしくお願い致しますw




【iOS/Objective-c】Method Swizzling 修正版

ちょっと前にこんなん書きましたシリーズ第二弾

【iOS/Objective-c】Method Swizzling - ふるすたっくえんじにあっぽい人の日記

いや、動くんだけどさ。
[[Hoge sharedInstance] applicationWillResignActive:application];
って呼ぶと、AppDelegate内で定義されているapplicationWillResignActive内の処理が実行されるんすけどね。こんなかでselfは当然AppDelegateのインスタンスは参照してないんすよね。Hogeインスタンス参照してるわ。そらそうだ。

で、以下のように修正


#pragma mark - swizzled AppDelegate Methods
- (void)applicationWillResignActive:(UIApplication *)application {
    [[Hoge sharedInstance] swizzleMethod:@selector(applicationWillResignActive:)];
    [self applicationWillResignActive:application];
    [[Hoge sharedInstance] swizzleMethod:@selector(applicationWillResignActive:)];
}

- (void)applicationDidEnterBackground:(UIApplication *)application {
    [[Hoge sharedInstance] swizzleMethod:@selector(applicationDidEnterBackground:)];
    [self applicationDidEnterBackground:application];
    [[Hoge sharedInstance] swizzleMethod:@selector(applicationDidEnterBackground:)];
}

- (void)applicationWillEnterForeground:(UIApplication *)application {
    [[Hoge sharedInstance] swizzleMethod:@selector(applicationWillEnterForeground:)];
    [self applicationWillEnterForeground:application];
    [[Hoge sharedInstance] swizzleMethod:@selector(applicationWillEnterForeground:)];
}

- (void)applicationDidBecomeActive:(UIApplication *)application {
    [[Hoge sharedInstance] swizzleMethod:@selector(applicationDidBecomeActive:)];
    [self applicationDidBecomeActive:application];
    [[Hoge sharedInstance] swizzleMethod:@selector(applicationDidBecomeActive:)];
}

- (void)applicationWillTerminate:(UIApplication *)application {
    [[Hoge sharedInstance] swizzleMethod:@selector(applicationWillTerminate:)];
    [self applicationWillTerminate:application];
    [[Hoge sharedInstance] swizzleMethod:@selector(applicationWillTerminate:)];
}

- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo {
    [[Hoge sharedInstance] swizzleMethod:@selector(application:didReceiveRemoteNotification:)];
    [self application:application didReceiveRemoteNotification:userInfo];
    [[Hoge sharedInstance] swizzleMethod:@selector(application:didReceiveRemoteNotification:)];
}




【iOS】UIWebViewで表示されている要素の高さを取得 バージョン2

ちょっと前にこんなん書きました。


【iOS】UIWebViewで表示されている要素の高さを取得 - ふるすたっくえんじにあっぽい人の日記

だがしかし。なんかびみょーにずれる。いや、divの高さは正しく取れてるんだけどさ。
WebViewの描画領域のサイズ取りたいだけなら、以下で十分w

webView.scrollView.contentSize




【Git】.gitignoreの書き方~Unity編

はい、ここを参考にしました。
オフィシャルなやつですからね。間違ってるはずがありませんね。

http://docs.unity3d.com/Manual/ExternalVersionControlSystemSupport.html
Unity - Manual: Using External Version Control Systems with Unity



こんな感じ

Temp
Obj
UnityGenerated
Library

次回.gitignoreの書き方にはいよいよCocos2d-xさんが登場する予定でございます。

なお、このエントリで記念すべき100エントリ目!
とりあえずfacebookに投稿しても、流入の98%は検索であんま意味ないからそろそろやめよう。




【その他】Duet Display買ったった

不具合多い
iOS側がiOS7だとあんまちゃんと動かなかった
まぁ今後に期待ですが、サブディスプレイとして映すだけならiOS8でリフレッシュレート落とせばそこそこ快適



ちっちゃいiPadに映せるって便利
ってゆかこのアプリが申請通ったのがすごい
なお、現在1500円になってました。


Duet Display - Ex-Apple Engineers Turn Your iPad Into An Extra Display



【iOS】UIWebViewで表示されている要素の高さを取得

2014/12/27
追記しました↓

【iOS】UIWebViewで表示されている要素の高さを取得 バージョン2 - ふるすたっくえんじにあっぽい人の日記



ひさびさiOS
うん、一応iOSもまだやってます。

動的に変えたいじゃん?webViewのサイズ。
とりあえずこんなhtml


<!DOCTYPE html>
<html>
<head>
<title>aaaaa</title>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=EmulateIE7" />
<meta name="viewport" content="user-scalable=no;">
<link rel="stylesheet" type="text/css" href="../css/hoge.css" media="all">
</head>
<body>
<div id="contents">
あーぁ、だりー
</div>
</body>
</html>



取得したい要素にid振っとくのがポイントですねー
んでもって、こう。

- (void)webViewDidFinishLoad:(UIWebView *)webView {
    NSString *heightStr = [webView stringByEvaluatingJavaScriptFromString:@"document.getElementById(\"contents\").clientHeight;"];
    if (![NSString isNilOrEmpty:heightStr])
        webView.height = [heightStr floatValue];
}

ただ単にObjective-cからJavascript使えるよーってだけですね。