ごらくらいふ

プログラミングしたりゲームしたり

ヤフオク!にて、ライブチケットなどに対する違反商品通報の対策

シンデレラガールズ4th live、楽しみですね。

http://idolmaster.jp/event/cinderella4th.php

チケットは無事入手できましたでしょうか。 私は無事会場チケット戦線に敗れ、いまライブビューイングチケットの抽選に祈りを捧げています。 (2016/08/22追記:ライブビューイングのチケット取れました( `ω')q)

もうひとつライブチケットに対して行っていることがありました。 オークションにおける転売チケットの違反通報です。

作業中、工夫して転売努力を注ぐ例に遭遇しました。

新着アラートに抗う

チケットが取れなかったプロデューサー(以下、P)の気持ちになれば、 買うPも通報するPも転売チケットを探すためにほぼ同じキーワードを指定します。

また、熱心に探すPはアラートを即通知するよう設定していますので、出品したらあまり間を置かずに発見されます。

通報されたら取り消し

出品者は、違反商品の申告通知を受けることができます。

ヤフオク!ヘルプ - 違反商品として申告があった場合

通知を受けたらオークションを取り消し、一旦静観したあと再度オープンします。 再オープンは新着アラートのように通知されないため、通知ベースで動く通報側から逃れることができます。

対策

オークションを取り消した段階で、通報側に通知メールが届きます。

私はGmailを使っていますので、このメールにスターを付け、定期的に再確認をしています。 再オープンされていたら再度通報し、メールからスターを外します。

出品したら即取り消し

出品したら即座にオークションを取り消し、しばらく寝かせたあと再度オープンします。 「もう通報されたかな?」という勘違いを狙う感じでしょうか。

対策

新着通知メールにスターをつけます。 通報後の再出品と方法は変わらないので、定期的に確認します。

宣伝

ヤフオク!での通報もなんだかんだ面倒なところがあります。 理由に「その他」を選んで、その他の中から適切なものを選んで……

ひとつふたつならまだ我慢できても、数が多ければ嫌気がさします。

なのでセミオートに通報できるChrome拡張を作りました。

github.com

個人の通報では限界があるので、ひとりでも違反商品の通報人が増えるといいんじゃないかな。

CocoaPods Linking error 「ld: symbol(s) not found for architecture i386」

環境

現象

CocoaPodsを導入して、いざdebug-buildしたら記事タイトルのエラーが発生した。

以下はそのログである。

Undefined symbols for architecture i386:
  "_FBSDKAppEventParameterNameContentType", referenced from:
      -[MyViewController viewDidLoad] in MyViewController.o
  "_FBSDKAppEventParameterNameCurrency", referenced from:
      -[MyViewController viewDidLoad] in MyViewController.o
  "_OBJC_CLASS_$_FBSDKAppEvents", referenced from:
      objc-class-ref in MyAppDelegate.o
      objc-class-ref in MyViewController.o
  "_OBJC_CLASS_$_FBSDKApplicationDelegate", referenced from:
      objc-class-ref in MyAppDelegate.o
  "_OBJC_CLASS_$_FBSDKGraphRequest", referenced from:
      objc-class-ref in MyClass.o
  "_OBJC_CLASS_$_FBSDKLoginButton", referenced from:
      objc-class-ref in MyViewController.o
ld: symbol(s) not found for architecture i386

結論

プロジェクト設定にて「Build Active Architecture Only」の項目が、Podsプロジェクトの設定と一致していなかったことが原因だった。

before

MyProject
  • Build Settings
    • Architectures
      • Build Active Architecture Only
        • Debug
          • NO
        • Release
          • NO
Pods
  • Build Settings
    • Architectures
      • Build Active Architecture Only
        • Debug
          • YES
        • Release
          • NO

after

MyProject
  • Build Settings
    • Architectures
      • Build Active Architecture Only
        • Debug
          • YES
        • Release
          • NO
Pods
  • Build Settings
    • Architectures
      • Build Active Architecture Only
        • Debug
          • YES
        • Release
          • NO

解決

Architecturesが「Standard architecures(armv7, arm64)」の状態で「Build Active Architecture Only」がYESの場合、 armv7, arm64だけを対象にビルドするっぽい。

Product>ArchiveではRelease設定を使うようにしているので、こちらでは「Build Active Architecture Only」をNOにしておこうと思う。

参考リンク

FacebookSDK 3.x -> 4.x : FBRequestConnection startWithGraphPath:completionHandler:が無くなったので FBSDKGraphRequest startWithCompletionHandler:を使う

記事タイトルキャメルケースでキッツキツだな。

結論

3.xにてGraphAPIを手軽に叩くため、FBRequestConnection startWithGraphPath:completionHandler:を使っていた。

4.xでは失くなってしまったのでFBSDKGraphRequest startWithCompletionHandler:を使った。

コードで見る違い

3.x

- (void) callGraphApi:(NSString*)graphPath {
    [FBRequestConnection startWithGraphPath:graphPath completionHandler:^(FBRequestConnection *connection, id result, NSError *error) {
    }];
}

4.x

- (void) callGraphApi:(NSString*)graphPath {
    // 一個一個変数化するとデバッグしやすくて好き
    FBSDKGraphRequest* fbRequest = [[FBSDKGraphRequest alloc] initWithGraphPath:graphPath parameters:nil];
    [fbRequest startWithCompletionHandler:^(FBSDKGraphRequestConnection *connection, id result, NSError *error) {
    }];
}

「なんでじゃ」と思ったこと集

  • FBRequestConnectionでやってたことがFBSDKGraphRequestConnectionではなくFBSDKGraphRequestに納まっていたこと
  • FBSDKGraphRequest startWithCompletionHandler:のコールバック、FBSDKGraphRequestHandlerの定義がFBSDKGraphRequestConnectionにあったこと
  • よくみるとFBSDKGraphRequestConnectionFBSDKGraphRequestをimportしておらず、その逆だったこと
    • 依存の仕方が直感に沿わない…内部クラスかしら?って思った

FacebookSDK 3.x -> 4.x : FBLoginView無くなったのでFBSDKLoginButtonを使った

Facebook APIバージョン v2.0 が非推奨間近*1のため尻に火が点いている。 消火活動で代替処理がわかったっぽいので記録。

(追記:2016/07/21 22:13) 3.x のログイン(ログアウト)時の処理の認識が間違っていたので修正。 仮にログイン時にNavigationControllerにPushするような実装をしていたら「画面を戻ろうとしているのに戻れない」現象が発生するはず。

改修内容

3.xでの擬似コード

// TheViewController.h

#import <FacebookSDK/FacebookSDK.h>
@interface TheViewController : UIViewController<FBLoginViewDelegate>
@end
// TheViewController.m

@interface TheViewController()
@property (nonatomic) FBLoginView* loginView;

@end

@implementation TheViewController
- (void)viewDidLoad{
    self.loginView = [[FBLoginView alloc] init];
}
- (void)viewDidAppear:(BOOL)animated{
    // viewの位置を真ん中にちょちょいとする
    CGRect bounds = [UIScreen mainScreen].bounds;
    CGRect rect = self.loginView.frame;
    rect.origin.x = (bounds.size.width - rect.size.width) / 2.0;
    rect.origin.y = (bounds.size.height - rect.size.height) / 2.0;
    self.loginView.frame = rect;

    // delegateの指定
    self.loginView.delegate = self;

    // 読み込み権限の指定
    self.loginView.readPermissions = @[@"public_profile", @"read_stream"];

    // 表示
    [self.view addSubView:self.loginView];
}

// FBLoginViewDelegate
-(void)loginViewFetchedUserInfo:(FBLoginView *)loginView user:(id<FBGraphUser>)user{
    // (とくになにもしていなかった……)
}
-(void)loginViewShowingLoggedInUser:(FBLoginView *)loginView{
    // ログインしている状態でLoginViewを表示したときの処理
}
-(void)loginViewShowingLoggedOutUser:(FBLoginView *)loginView{
    // ログアウトしている状態でLoginViewを表示したときの処理
}
@end

4.xでの擬似コード

// TheViewController.h

#import <FBSDKCoreKit/FBSDKCoreKit.h>
#import <FBSDKLoginKit/FBSDKLoginKit.h>
@interface TheViewController : UIViewController<FBSDKLoginButtonDelegate>
@end
// TheViewController.m

@interface TheViewController()
@property (nonatomic) FBLoginView* loginView;
@property (nonatomic) BOOL isLoggedIN;

@end

@implementation TheViewController
- (void)viewDidLoad{
    self.loginView = [[FBLoginView alloc] init];
}
- (void)viewDidAppear:(BOOL)animated{
    // viewの位置を真ん中にちょちょいとする
    self.fbLoginButton.center = self.view.center;

    // delegateの指定
    self.fbLoginButton.delegate = self;

    // 読み込み権限の指定
    self.fbLoginButton.readPermissions = @[@"public_profile", @"read_stream"];

    // 表示
    [self.view addSubView:self.fbLoginButton];

    // ログイン状態による処理分けはここに移植する
    if([FBSDKAccessToken currentAccessToken]) {
    } else {
    }
}

// FBSDKLoginButtonDelegate

-(BOOL)loginButtonWillLogin:(FBSDKLoginButton *)loginButton{
    // ログイン前処理
    // NOを返すと処理を中止するらしい。APIリファレンスに書いておいてほしい。
    return YES;
}
-(void)loginButton:(FBSDKLoginButton *)loginButton didCompleteWithResult:(FBSDKLoginManagerLoginResult *)result error:(NSError *)error {
    // ログイン処理を完了した時
    if (error) {
        return;
    }    
    if (result.isCancelled) {
        return;
    }
    if ([result.declinedPermissions containsObject:@"required permission"]) {
        return;
    }
    
    // ログイン完了
    // ログイン時の処理
}
-(void)loginButtonDidLogOut:(FBSDKLoginButton *)loginButton{
    // ログアウト完了
    // ログアウト時の処理
}
@end

*1:v2.1が公開されてから2年になるため

既存のXcodeプロジェクトにCocoaPodsを入れたらビルドエラー ld: library not found for -lPods

既存のプロジェクトにCocoaPodsを入れて、早速buildしたら次のようなエラーが出た。

ld: library not found for -lPods-ProjectName

対処方法をggrといくつかあって悩んだので、*1*2公式を確認した。

guides.cocoapods.org

Using the CocoaPods Project項目4 に答えがあった。

If Xcode complains when linking, e.g. Library not found for -lPods, it doesn't detect the implicit dependencies:
  • Go to Product > Edit Scheme
  • Click on Build
  • Add the Pods static library, and make sure it's at the top of the list
  • Clean and build again

以下にも続きがあるが、自分はこの時点で解決した。

他プロジェクトの生成物を使うので、先にbuildしましょう。ということかと。

Manage schemeで別途buildすると、「ライブラリのアップデートが反映されねぇ!」ってなりそうだからこっちの方法が良さそう。

*1:Manage schemeからPodsプロジェクトをshowするとか

*2:Edit schemeで対処するとか

続・リリースするファイルに対応したバックアップを作る

↓この処理をシェルスクリプトにした。 yajamon.hatenablog.com

#!/bin/bash

src=$1
dest=$2
backup=$3

# backupのパスがファイルなら終了
if [ -f $backup ] ; then
    echo "\$backup is file"
    exit 1
fi

# srcと同じディレクトリ構造のbackupディレクトリを作る
if [ ! -e $backup ] ; then
    echo "make directory: $backup"
    mkdir $backup
    echo "create: "$(cd $backup; pwd)
fi

# 続行するか念のために確認
echo "   src: $src"
echo "  dest: $dest"
echo "backup: $backup"
while [ "$goSign" = "" ]
do
    echo "execute ok? (yes/no)"
    read goSign
done

if [ $goSign != "yes" ] ; then
    echo "abort"
    exit 1
fi

cp -rv $src/* $backup/
echo "clean to $backup"
find $backup -type f -exec rm -v {} \;

# src内のファイルパスをもとに、destからbackupへコピーする
for item in $(find ${src} -type f | sed -e "s/^${src}//g")
do
    cp -v $dest$item $backup$item
done

feedlyでニコニコ動画のマイリストRSSを監視して新着を逃さないようにした

おれ しった かく。

マイリストの新着管理

  • プレイ動画とかシリーズ物の追跡をしたい。
  • RSS配信が生きてるらしいのでfeedlyに登録する。

chrome拡張入れると画面右下にボタン追加されて登録が楽。 chrome.google.com

手順

  1. 追跡したいマイリストを開く
    • f:id:yajamon:20160610190328p:plain
  2. feedly拡張をポチッとして登録する
    • f:id:yajamon:20160610190415p:plain
  3. 新着を待つ

手軽。

手軽だわ。どれブラウザから試しにひとつ…

f:id:yajamon:20160610191236p:plain

f:id:yajamon:20160610191553g:plain

ワンクッションおいて解決

IFTTTでSlackに流し込んで解決した。