iOSでは、パッチポリシーJSPatchの運用基本を動的に更新します.


iOSでは、パッチポリシーJSPatchの運用基本を動的に更新します.
        JSPatchはGitHubの前のオープンソースのフレームワークで、Objective-Cのrun-timeメカニズムを通じて動的にJavaScriptを使って代替プロジェクトのObjective-C属性と方法を呼び出すことができます.そのフレームはコンパクトで、コードは簡潔で、そしてシステムのJavaScript Coreフレームワークを通じてObjective-Cとインタラクションしています.これは安全性と審査リスクにおいても優れています.Gitソースの住所:https://github.com/bang590/JSPatch.
一、公式のデモちゃんから見て
        cocoppappodsを通じてJSPathを一つのXcodeプロジェクトに統合し、AppDelegate類の中で次のコードを作成します.
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
    //       
    [JPEngine startEngine];
    //  js  
    NSString *sourcePath = [[NSBundle mainBundle] pathForResource:@"demo" ofType:@"js"];
    NSString *script = [NSString stringWithContentsOfFile:sourcePath encoding:NSUTF8StringEncoding error:nil];
    //  js  
    [JPEngine evaluateScript:script];
    self.window = [[UIWindow alloc]initWithFrame:[UIScreen mainScreen].bounds];
    self.window.rootViewController = [[ViewController alloc]init];
    [self.window addSubview:[self genView]];
    [self.window makeKeyAndVisible];
    return YES;
}

- (UIView *)genView
{
    UIView * view= [[UIView alloc] initWithFrame:CGRectMake(0, 0, 320, 320)];
    view.backgroundColor = [UIColor redColor];
    return view;
}
プロジェクトにjsファイルを追加して、下記のように作成します.
    require('UIView, UIColor, UILabel')
    //       
    defineClass('AppDelegate', {
            //    
                //        
                genView: function() {
                    var view = self.ORIGgenView();
                    view.setBackgroundColor(UIColor.greenColor())
                    var label = UILabel.alloc().initWithFrame(view.frame());
                    label.setText("JSPatch");
                    label.setTextAlignment(1);
                    view.addSubview(label);
                    return view;
            }
    });
プロジェクトを実行すると、Jsファイルに置き換えられたgenViewメソッドが見られます.元々は赤いビューが緑色に修正されました.
二、JavaScriptコードを使ってObjective-Cに修正または追加する方法
        JSPatchエンジンでは、JavaScriptコードの呼び出しは、JavaScript文字列を使用して実行され、ローカルJavaScriptファイルを読み込み、コード実行とネットワークを取得するJavaScriptファイルを実行します.例えば、JavaScriptコードを通じてプロジェクトに警告枠をイジェクトする場合、Objective-Cコードに次のコードを挿入します.
- (void)viewDidLoad {
    [super viewDidLoad];
    // ‘\’       
    [JPEngine evaluateScript:@"\
     var alertView = require('UIAlertView').alloc().init();\
     alertView.setTitle('Alert');\
     alertView.setMessage('AlertView from js'); \
     alertView.addButtonWithTitle('OK');\
     alertView.show(); \
     "];
}
        開発者は、Objective-Cファイルに動的に方法を追加することもできます.例えば、View Controllerクラスでは、次のように作成します.
- (void)viewDidLoad {
    [super viewDidLoad];
    self.view.backgroundColor = [UIColor whiteColor];
    [JPEngine startEngine];
    NSString *sourcePath = [[NSBundle mainBundle] pathForResource:@"demo" ofType:@"js"];
    NSString *script = [NSString stringWithContentsOfFile:sourcePath encoding:NSUTF8StringEncoding error:nil];
    [JPEngine evaluateScript:script];
    [self performSelectorOnMainThread:@selector(creatView) withObject:nil waitUntilDone:nil];
}
JavaScriptファイルコードは以下の通りです.
 require('UIView, UIColor, UILabel')
    defineClass('ViewController', {
            // replace the -genView method
                creatView: function() {
                    var view = UIView.alloc().initWithFrame({x:20, y:20, width:100, height:100});
                    view.setBackgroundColor(UIColor.greenColor());
                    var label = UILabel.alloc().initWithFrame({x:0, y:0, width:100, height:100});
                    label.setText("JSPatch");
                    label.setTextAlignment(1);
                    view.addSubview(label);
                self.view().addSubview(view)
            }
    });
上記のコードを除いて、ViewController.mファイルには他の方法がありません.プロジェクトを実行すると、プログラムは崩壊していません.View Controllerがcreat View方法を実行しています.
        上記の例を通して、JSPatchを使って非常に面白いことができることを発見しました.iOSアプリケーションにとっては、公式チャネルAppStoreを通じたアプリケーションのリリースは、人工的な審査によって行われます.この審査期間は非常に長い場合があります.開発者がコードを作成する時に、小さな穴を残していたら、アプリケーションがオンラインに出たら、このバグを修正するのは十分に困難です.JSPatchがあったら、問題のある方法をオンラインに位置付けて、JSファイルを使ってこの方法を修正することができます.これはどんなにcoolなことでしょうか?実は、JSPatchの主な用途もオンライン応用の極小問題のhotfixを実現することができます.
三、JavaScriptとObjective-Cの相互作用の基礎方法
        JSPatchを使ってObjective-Cスタイルの方法を編纂するには、JavaScriptとObjective-Cの相互作用の規則を守る必要があります.
1.JavaScriptファイルにObjective-C類を使用する
   JavaScriptコードを作成する際にObjective-Cを使用する必要がある場合は、まずこのクラスをrequire引用しなければなりません.例えば、UID Viewというクラスを使う必要がある場合は、使用前に以下のように参照してください.
require('UIView')
複数のObjective-C類を一度に参照することもできます.
require('UIView, UIColor, UILabel')
もっと簡単な書き方もあります.直接使う時に引用します.
require('UIView').alloc().init()
2.JavaScriptファイルでObjective-Cメソッドの呼び出しを行います.
    Objective-Cメソッドの呼び出しを行う場合、2つに分けられます.一つは呼び出しクラスの方法で、一つは呼び出しクラスのオブジェクト方法です.
クラスの呼び出し方法:クラス名の打点でクラスメソッドを呼び出すと、フォーマットは以下のようになります.
UIColor.redColor()
コールの例の方法:オブジェクトの打点によってクラスの実例的な方法を呼び出すと、以下のようになります.括弧内はパラメータの伝達になります.
view.addSubview(label)
Objective-Cにおけるマルチパラメータ方法については、JavaScriptに変換してパラメータを分割する位置を_分割を行います.パラメータは全部後の括弧に入れて、カンマで分割します.例は以下の通りです.
view.setBackgroundColor(UIColor.colorWithRed_green_blue_alpha(0,0.5,0.5,1))
Objective-Cクラスの属性変数については、JavaScriptではgetterとsetterの方法しか使用できません.例は以下の通りです.
label.setText("JSPatch")
ヒント:元Objective-Cの方法に既に含まれている場合記号は、JavaScriptで使用されます.代わりに
3.JavaScriptでObjective-C類の操作と修正
    JSPatchの最大応用は、アプリケーション運転時のダイナミックな操作と修正類です.
クラスを書き換えたり追加する方法:
JavaScriptでdefineClassを使用してクラス中の方法を定義し、修正します.そのフォーマットは以下の通りです.
/*
classDeclaration:                                 
instanceMethods:             {}
classMethods:            {}
*/
defineClass(classDeclaration, instanceMethods, classMethods)
例は以下の通りです
defineClass('ViewController', {
            // replace the -genView method
                newFunc: function() {
                    //      
                    self.view().setBackgroundColor(UIColor.redColor())
                }
    
            },{

                myLoad:function(){
                    //     
                }

            }
            )
クラス内の方法を書き換えた後に元の方法を呼び出す場合、ORIGプレフィックスを使用する必要がある.例は以下の通りである.
defineClass('ViewController', {
            // replace the -genView method
                viewDidLoad: function() {
                    //      
                    self.ORIGviewDidLoad()
                }
    
            }
            )
Objective-Cにおけるsuperキーの呼び出しの方法については、JavaScriptにおいて、self.super()を使用して呼び出すことができる.
defineClass('ViewController', {
            // replace the -genView method
                viewDidLoad: function() {
                    //      
                    self.super().viewDidLoad()
                }
    
            }
            )
同様にJSPatchは、クラスに対して一時的な属性を追加して、方法間でパラメータを伝達するために、set_を使用してもよい.Prop.forKey()に属性を追加し、getProp()を使用して属性を取得します.JSPatchの属性はObjective-Cのsetterとgetterの方法でアクセスできません.
defineClass('ViewController', {
            // replace the -genView method
                viewDidLoad: function() {
                    //      
                    self.super().viewDidLoad()
                    self.setProp_forKey("JSPatch", "data")
                },
                touchesBegan_withEvent(id,touch){
                    self.getProp("data")
                    self.view().setBackgroundColor(UIColor.redColor())
                }
    
            }
            )
クラス追加契約の遵守については、Objective-Cで合意に従う方式と一致しています.
defineClass("ViewController2: UIViewController <UIAlertViewDelegate>", {
            viewDidAppear: function(animated) {
            var alertView = require('UIAlertView')
            .alloc()
            .initWithTitle_message_delegate_cancelButtonTitle_otherButtonTitles(
                                                                                "Alert",
                                                                                "content",
                                                                                self,
                                                                                "OK",
                                                                                null
                                                                                )
            alertView.show()
            },
            alertView_clickedButtonAtIndex:function(alertView, buttonIndex) {
            console.log('clicked index ' + buttonIndex)
            }
            })