개요
문서의 범위
이 문서는 Android와 iOS에서 MOMLView를 사용하기 위해 OS별로 각각 구현한 Native API를 중심으로 다룹니다.
OS 종류와 상관없는 XML UI element나 Script Object등과 같은 공통 MOML API의 사용법은 MOML API Reference 문서를 참고하십시오.
MOML Native 연동 예
일반적으로 MOML Native 연동이 필요한 상황들은 아래와 같이 분류할 수 있습니다.
Native -> MOML call
Native에서는 MOMLView.root.runScript를 통해 MOML 내부 객체의 값을 얻어오거나 함수를 실행할 수 있습니다.
일반적인 스크립트문 실행은 MOMLUIObject.runScript를 참고하십시오.
MOML UI XML 파일에 정의된 function 을 실행하는 경우는 MOMLHelper.runFunction을 참고하십시오.
UI element나 Script Object의 값을 설정하는 경우는 MOMLHelper.setAttribute를 참고하십시오.MOML -> Native call
MOML에서는 MOMLView.addUIObjectHandler를 통해 추가된 UIObjectHandler의 onEvent함수를 구현하여 Native 함수를 호출하거나 결과 값을 리턴 받을 수 있습니다.
예를 들면 BUTTON의 onClick 이벤트와 같은 기본 이벤트를 후킹하면 버튼이 눌렸을 때 Native 기능을 호출할 수 있습니다.
WINDOW.fireEvent(v)
를 사용하면 원하는 시점에 사용자 정의 이벤트를 발생시켜 Native 기능을 호출할 수 있습니다.Script Object 추가
math, date, sound 등과 같은 스크립트 객체를 사용자가 직접 추가하기 위해서는 DefaultObjectComponent를 상속 받아 구현하여MOMLView.registerObjectComponent
로 등록해야 합니다.
• UI element 추가
BUTTON, LABEL, IMAGE 등과 같은 UI element를 사용자가 직접 추가하기 위해서는 DefaultUIComponent를 상속 받아 구현하여 MOMLView.registerUIComponent
로 등록해야 합니다.
MOML Native Classes
▹ MOMLViewController
[declaration]
package org.mospi.moml.framework.pub.core;
class MOMLActivity extends Activity implements IMOMLBaseActiviyProxy
class MOMLFragmentActivity extends FragmentActivity implements IMOMLBaseActiviyProxy
class MOMLMapActivity extends MapActivity implements IMOMLBaseActiviyProxy
[declaration]
MOMLUIViewController.h
@interface MOMLUIViewController : UIViewController
[declaration]
class MOMLUIViewController : UIViewController
MOMLView 하나를 관리하고 있으며 MOMLView에서 자주 사용되는 API를 바로 사용할 수 있도록 제공합니다.
[attr] MOMLView momlView
[declaration]
MOMLView getMOMLView()
void setMOMLView(MOMLView momlView)
[declaration]
@property (nonatomic, strong) IBOutlet MOMLView* momlView
[declaration]
@IBOutlet var momlView: MOMLView!
관리하고 있는 MOMLView를 설정하거나 현재 설정된 MOMLView를 리턴합니다.
- MOMLView는 필요할 때 자동으로 생성되므로 getMOMLView함수 등으로 momlView의 값을 확인했을 경우 항상 null이 아닌 값을 리턴합니다.
- MOMLView가 자동으로 생성되기 전에 setMomlView 함수 등을 사용해 직접 MOMLView를 설정하면 자동으로 생성하지 않고 지정된 MOMLView를 사용합니다.
- iOS의 경우 Interface Builder에서 바로 momlView를 Outlet으로 연결할 수 있습니다.
- Android의 경우 Android Layout XML에 정의된 MOMLView는 MOMLViewController의 다른 함수를 호출하기 전에 가장 먼저 연결되어야 합니다.
- iOS Interface Builder나 Android Layout XML에 대한 더 자세한 내용은 MOML Native Layout XML을 참고하십시오.
[func] void loadApplication(url)
[declaration]
void loadApplication(String url)
[example]
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
loadApplication("embed:/moml/applicationInfo.xml");
}
[declaration]
- (void)loadApplication:(NSString *)url
[example]
- (void)viewDidLoad
{
[super viewDidLoad];
[self loadApplication:@"embed:/moml/applicationInfo.xml"];
}
[declaration]
func loadApplication(url: String!)
[example]
override func viewDidLoad() {
super.viewDidLoad()
loadApplication("embed:/moml/applicationInfo.xml");
}
MOML Application Info XML file을 읽어서 화면에 MOML 앱을 실행합니다.
- url은 http, https와 embed 프로토콜을 지원합니다.
- 프로토콜을 사용하지 않은 상대경로나 절대 경로는
embed:/
로 간주합니다.
Parameter | Type | 설명 |
---|---|---|
url | "[url path]" |
[func] void loadUrl(url)
[declaration]
void loadUrl(String url)
[example]
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
loadUrl("embed:/moml/ui/start.xml");
}
[declaration]
- (void)loadUrl:(NSString *)url
[example]
- (void)viewDidLoad
{
[super viewDidLoad];
[self loadUrl:@"embed:/moml/ui/start.xml"];
}
[declaration]
func loadUrl(url: String!)
[example]
override func viewDidLoad() {
super.viewDidLoad()
loadUrl("embed:/moml/ui/start.xml");
}
MOML UI XML file을 읽어서 화면에 MOML 앱을 실행합니다.
- url은 http, https와 embed 프로토콜을 지원합니다.
- 프로토콜을 사용하지 않은 상대경로나 절대 경로는 embed:/로 간주합니다.
- loadUrl은 현재 로딩한 MOML Application Info를 그대로 사용합니다. 만약 MOML Application Info를 아직 로딩한 적이 없다면 기본값들을 사용합니다.
Parameter | Type | 설명 |
---|---|---|
url | "[url path]" |
▹ MOMLView
[declaration]
package org.mospi.moml.framework.pub.core;
class MOMLView extends FrameLayout
[declaration]
MOMLView.h
@interface MOMLView : UIView
[declaration]
class MOMLView : UIView
MOML 페이지를 화면에 보여주며 내부 개체를 관리하고 제어할 수 있는 인터페이스를 제공합니다.
[func] void addUIObjectHandler(uiId, handler)
[declaration]
public void addUIObjectHandler(String uiId, MOMLUIObjectHandler handler)
[example]
getMomlView.addUIObjectHandler("root.coverflow1", new DefaultUIObjectHandler() {
public boolean onClick(MOMLUIObject uiObject) {
textView1.setText("MOMLView CoverFlow Index :" + uiObject.getAttribute("index"));
return true;
}
});
[declaration]
- (void)addUIObjectHandler:(NSString *)uiId handler:(id<MOMLUIObjectDelegate>)handler
[example]
[self.momlView addUIObjectHandler: @"root.coverflow1" handler:[DefaultUIObjectHandler handlerWithOnClickBlock:^BOOL(MOMLUIObject *uiObject) {
[textView1 setText:[NSString stringWithFormat:@"MOMLView CoverFlow Index : %@", [uiObject getAttribute:@"index"]];
return true;
}]];
[declaration]
func addUIObjectHandler(uiId: String!, handler: MOMLUIObjectDelegate!)
[example]
momlView.addUIObjectHandler("root.nativeTestBtn", handler: DefaultUIObjectHandler(onClick:{ (uiObject) -> Bool in
textView1.text = "MOMLView CoverFlow Index : \(uiObject.getAttribute("index"))"
return false;
}))
UI Object를 제어할 수 있는 UIObjectHandler를 추가합니다.
- UI Object Handler는 UI Object의 생성 여부와 상관없이 미리 추가해놓을 수 있습니다.
- MOMLUIObjectHandler 인터페이스를 직접 구현하여 사용하는 것보다는 DefaultUIObjectHandler를 사용하는 것이 편리합니다.
Parameter | Type | 설명 |
---|---|---|
uiId | "[ui object full id]" | |
handler | "[IMOMLUIObjectHandler]" | 핸들러 객체 |
[attr] MOMLUIObject root
[declaration]
MOMLUIObject getRoot()
[example]
MOMLUIObject root = getMomlView().getRoot();
[declaration]
@property (nonatomic, readonly) MOMLUIObject *root
[example]
MOMLUIObject *root = self.momlView.root;
[declaration]
var root: MOMLUIObject! { get }
[example]
var root = momlView.root
MOMLView에서 root CONTAINER element를 제어할 수 있는 MOMLUIObject를 리턴합니다.
[func] void loadApplication(url)
[declaration]
void loadApplication(String url)
[example]
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
getMomlView().loadApplication("embed:/moml/applicationInfo.xml");
}
[declaration]
- (void)loadApplication:(NSString *)url
[example]
- (void)viewDidLoad
{
[super viewDidLoad];
[self.momlView loadApplication:@"embed:/moml/applicationInfo.xml"];
}
[declaration]
func loadApplication(url: String!)
[example]
override func viewDidLoad() {
super.viewDidLoad()
momlView.loadApplication("embed:/moml/applicationInfo.xml");
}
MOML Application Info XML file을 읽어서 화면에 MOML 앱을 실행합니다.
- url은 http, https와 embed 프로토콜을 지원합니다.
- 프로토콜을 사용하지 않은 상대경로나 절대 경로는
embed:/
로 간주합니다.
Parameter | Type | 설명 |
---|---|---|
url | "[url path]" |
[func] void loadUrl(url)
[declaration]
void loadUrl(String url)
[example]
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
getMOMLView().loadUrl("embed:/moml/ui/start.xml");
}
[declaration]
- (void)loadUrl:(NSString *)url
[example]
- (void)viewDidLoad
{
[super viewDidLoad];
[self.momlView loadUrl:@"embed:/moml/ui/start.xml"];
}
[declaration]
func loadURL(url: String!)
[example]
override func viewDidLoad() {
super.viewDidLoad()
momlView.loadUrl("embed:/moml/ui/start.xml");
}
MOML Application Info XML file을 읽어서 화면에 MOML 앱을 실행합니다.
- url은 http, https와 embed 프로토콜을 지원합니다.
- 프로토콜을 사용하지 않은 상대경로나 절대 경로는 embed:/로 간주합니다.
- loadUrl은 현재 로딩한 MOML Application Info를 그대로 사용합니다. 만약 MOML Application Info를 아직 로딩한 적이 없다면 기본값들을 사용합니다.
Parameter | Type | 설명 |
---|---|---|
url | "[url path]" |
[func] bool registerObjectComponent(className, objectName, baseObjectName, userObject)
[declaration]
boolean registerObjectComponent(String className, String objectName, String baseObjectName, Object userObj)
[example]
getMomlView().registerObjectComponent(NativeComponent.class.getName(), "native", "object", this);
getMomlView().registerObjectComponent("com.mycompany.moml.NativeComponent", "native", "object", this);
[declaration]
- (BOOL)registerObjectComponent:(NSString *)className name:(NSString *)objectName base:(NSString *)baseObjectName userObject:(NSObject *)userObj
[example]
[self.momlView registerObjectComponent:NSStringFromClass(NativeObjectComponent.class) name:@"native" base:@"object" userObject:self];
[self.momlView registerObjectComponent:@"NativeObjectComponent" name:@"native" base:@"object" userObject:self];
[declaration]
func registerObjectComponent(className: String!, name: String!, base: String!, userObject userObj: NSObject!) -> Bool
[example]
momlView.registerObjectComponent(NSStringFromClass(NativeObjectComponent.self), name: "native", base: "object", userObject: self)
momlView.registerObjectComponent("MyProjectName.NativeObjectComponent", name: "native", base: "object", userObject: self)
사용자 Script Object를 등록합니다.
- Android Java의 경우className은 package 이름을 포함한 전체 이름을 사용해야 합니다.
- iOS Swift의 경우 className 은 "MyPrjoject.MyComponent"처럼 현재 프로젝트 이름이 앞에 붙습니다.
- userObj는 매번 object가 생성될 때마다 MOMLComponent의 initBase 함수로 전달됩니다. 보통 MOMLView나 MOMLView를 포함하고 있는 MOMLViewController를 전달하지만, 다른 개체를 사용할 수도 있습니다.
- 현재는 baseObjectName으로 object만 지원합니다.
Parameter | Type | 설명 |
---|---|---|
className | "[full class name]" | class 전체 이름 (android의 경우 package 이름을 포함해야 합니다.) |
objectName | "[identifier]" | Script Object의 이름 |
baseObjectName | "[identifier]" | 기본이 되는 Script Object의 이름 |
userObj | "[object]" | 개체 생성시 파라미터로 전달될 객체 |
[func] bool registerUIComponent(className, elementName, baseElementName, userObject)
[declaration]
boolean registerUIComponent(String className, String elementName, String baseElementName, Object userObj)
[example]
getMomlView().registerUIComponent(MyButtonUIComponent.class.getName(), "MYBUTTON", "WINDOW", this);
getMomlView().registerUIComponent("com.mycompany.moml.MyButtonUIComponent", "MYBUTTON", "WINDOW", this);
[declaration]
- (BOOL)registerUIComponent:(NSString *)className name:(NSString *)elementName base:(NSString *)baseElementName userObject:(NSObject *)userObj
[example]
[self.momlView registerUIComponent:NSStringFromClass(MyButtonUIComponent.class) name:@"MYBUTTON" base:@"WINDOW" userObject:self];
[self.momlView registerUIComponent@"MyButtonUIComponent" name:@"MYBUTTON" base:@"WINDOW" userObject:self];
[declaration]
func registerUIComponent(className: String!, name: String!, base: String!, userObject userObj: NSObject!) -> Bool
[example]
momlView.registerUIComponent(NSStringFromClass(MyButtonUIComponent.self), name: "MYBUTTON", base: "WINDOW", userObject: self)
momlView.registerUIComponent("MyProjectName.MyButtonUIComponent", name: "MYBUTTON", base: "WINDOW", userObject: self)
사용자 UI element를 등록합니다.
- Android Java의 경우className은 package 이름을 포함한 전체 이름을 사용해야 합니다.
- iOS Swift의 경우 className 은 "MyPrjoject.MyComponent"처럼 현재 프로젝트 이름이 앞에 붙습니다.
- userObj는 매번 UI element가 생성될 때마다 MOMLUIComponent의 initBase 함수로 전달됩니다. 보통 MOMLView나 MOMLView를 포함하고 있는 MOMLViewController를 전달하지만, 다른 개체를 사용할 수도 있습니다.
- 현재는 baseElementName으로 WINDOW만 지원합니다.
Parameter | Type | 설명 |
---|---|---|
className | "[full class name]" | class 전체 이름 (android의 경우 package 이름을 포함해야 합니다.) |
objectName | "[identifier]" | Script Object의 이름 |
baseObjectName | "[identifier]" | 기본이 되는 Script Object의 이름 |
userObj | "[object]" | 개체 생성시 파라미터로 전달될 객체 |
bool unregisterObjectComponent(className)
[declaration]
boolean unregisterObjectComponent(String className)
[example]
getMomlView().unregisterObjectComponent(NativeComponent.class.getName());
getMomlView().unregisterObjectComponent("com.mycompany.moml.NativeComponent");
[declaration]
- (BOOL)unregisterObjectComponent:(NSString *)className
[example]
[self.momlView unregisterObjectComponent:NSStringFromClass(NativeObjectComponent.class)];
[self.momlView unregisterObjectComponent:@"NativeObjectComponent"];
[declaration]
func unregisterObjectComponent(className: String!) -> Bool
[example]
momlView.unregisterObjectComponen(NSStringFromClass(NativeObjectComponent.self))
momlView.unregisterObjectComponen("MyProjectName.NativeObjectComponent")
등록한 사용자 Script Object를 등록 해제합니다.
- Android Java의 경우 className은 package 이름을 포함한 전체 이름을 사용해야 합니다.
- iOS Swift의 경우 className 은 "MyPrjoject.MyComponent"처럼 현재 프로젝트 이름이 앞에 붙습니다.
Parameter | Type | 설명 |
---|---|---|
className | "[full class name]" | class 전체 이름 (android의 경우 package 이름을 포함해야 합니다.) |
bool unregisterUIComponent(className)
[declaration]
boolean unregisterUIComponent(String className)
[example]
getMomlView().unregisterUIComponent(MyButtonUIComponent.class.getName());
getMomlView().unregisterUIComponent("com.mycompany.moml.MyButtonUIComponent");
[declaration]
- (BOOL)unregisterUIComponent:(NSString *)className
[example]
[self.momlView unregisterObjectComponent:NSStringFromClass(MyButtonUIComponent.class)];
[self.momlView unregisterObjectComponent:@"MyButtonUIComponent.class"];
[declaration]
func unregisterUIComponent(className: String!) -> Bool
[example]
momlView.unregisterObjectComponent(NSStringFromClass(MyButtonUIComponent.self))
momlView.unregisterObjectComponent("MyProjectName.MyButtonUIComponent")
등록한 사용자 UI element를 등록 해제합니다.
- Android Java의 경우 className은 package 이름을 포함한 전체 이름을 사용해야 합니다.
- iOS Swift의 경우 className 은 "MyPrjoject.MyComponent"처럼 현재 프로젝트 이름이 앞에 붙습니다.
Parameter | Type | 설명 |
---|---|---|
className | "[full class name]" | class 전체 이름 (android의 경우 package 이름을 포함해야 합니다.) |
▹ MOMLUIObject
[declaration]
package org.mospi.moml.framework.pub.core;
class MOMLUIObject extends MOMLObject
[declaration]
MOMLUIObject.h
@interface MOMLUIObject : MOMLObject
[declaration]
class MOMLUIObject : MOMLObject
UI element를 외부에서 제어할 수 있도록 해줍니다.
Inherited from MOMLObject
[attr] string elementName
[declaration]
String getElementName();
[declaration]
@property (nonatomic, readonly) NSString *elementName;
[declaration]
var elementName: String! { get }
UI element의 XML Tag 이름을 리턴합니다.
[attr] string idName
[declaration]
String getIdName()
[declaration]
@property (nonatomic, readonly) NSString *idName
[declaration]
var idName: String! { get }
UI element의 id 속성 값을 리턴합니다.
- 사용자가 id를 할당하지 않은 경우는 자동으로 할당된 id 값을 리턴합니다.
[func] string getAttribute(name)
[declaration]
String getAttribute(String name)
[declaration]
- (NSString *)getAttribute:(NSString*)name
[declaration]
func getAttribute(name: String!) -> String!
Script Object의 속성을 리턴합니다.
- 이 함수는 UI element의 내부 속성값을 직접 리턴하므로 의도하지 않는 동작을 할 수 있습니다.
- Script에서 값을 리턴한한 것과 동일한 동작을 하기 위해서는 runScript("caller.name")를 사용하여 값을 얻어오십시오.
Parameter | Type | 설명 |
---|---|---|
name | "[identifier]" | 속성의 이름 |
[func] MOMLUIObject findWindow(name)
[declaration]
MOMLUIObject findWindow(String name)
[declaration]
- (MOMLUIObject*)findWindow:(NSString*)name
[declaration]
func findWindow(name: String!) -> MOMLUIObject!
UI element를 찾습니다.
- name은 자식의 id가 아님에 주의하십시오. id를 찾는 방법은 MOML UI XML의 UI element 속성에서 검색하는 것과 동일한 규칙을 사용합니다. 예를 들어 "[id]"는 현재 자신이 속한 CONTAINER 내에서 id가 일치하는 UI element를 리턴하고, "caller"는 자신을 리턴하며, 현재 자신이 CONTAINER인 경우 "caller.[id]"는 CONTAINER내의 id를 검색합니다.
Parameter | Type | 설명 |
---|---|---|
name | "[identifier]" | 찾을 UI element의 id path |
[func] IMOMLUIObjectHandler getHandler()
[declaration]
MOMLUIObjectHandler getHandler()
[declaration]
- (id<MOMLUIObjectDelegate>) delegate
[declaration]
func findWindow(name: String!) -> MOMLUIObject!
UI element에 설정된 이벤트를 핸들러를 리턴합니다.
MOMLView.addUIObjectHandler(2) 함수나 MOMLUIObject.setHandler(1)
함수로 설정한 이벤트 핸들러를 리턴합니다.
Parameter | Type | 설명 |
---|---|---|
name | "[identifier]" | 찾을 UI element의 id path |
[func] View getView()
[declaration]
FrameLayout getFrameLayout()
[declaration]
@property (nonatomic, readonly) UIView *view
[declaration]
var view: UIView! { get }
UI element의 Native View를 리턴합니다.
- 리턴된 뷰는 Button이나 WebView등과 같은 실제로 동작을 하는 뷰나 배경을 설정하기 위한 뷰등 여러 개체를 자식으로 가지고 있습니다.
- element 종류나 속성값, 버전에 따라 내부 구현은 달라질 수 있으므로 주의해야 합니다.
- 원하는 View class를 얻기 위해서는
MOMLHelper.findViewByClass
를 사용하는 것이 편리합니다.
Parameter | Type | 설명 |
---|---|---|
name | "[identifier]" | 찾을 UI element의 id path |
[func] void setAttribute(name, value)
[declaration]
void setAttribute(String name, String value)
[declaration]
- (void)setAttribute:(NSString*)name value:(NSString*)value
[declaration]
- (void)setAttribute:(NSString*)name value:(NSString*)value
Script Object의 속성을 설정합니다.
- 이 함수는 UI element의 내부 속성 값을 직접 변경하므로 의도하지 않는 동작을 할 수 있습니다.
- Script에서 값을 설정한 것과 동일한 동작을 하기 위해서는 runScript("caller.setName('name')")을 사용하거나 MOMLHelper.setAttribute(uiObject, "caller", "name")을 사용하여 값을 변경하십시오.
Parameter | Type | 설명 |
---|---|---|
name | "[identifier]" | 속성의 이름 |
value | "[string]" |
[func] void setHandler(handler)
[declaration]
void setHandler(MOMLUIObjectHandler handler)
[declaration]
- (void)setDelegate:(id<MOMLUIObjectDelegate> )handler
[declaration]
var delegate: MOMLUIObjectDelegate!
UI element의 이벤트를 핸들링할 수 있는 인터페이스를 설정합니다.
- setHandler 함수는 객체가 생성된 이후 직접 handler를 설정할 수 있도록 해줍니다.
- 객체 생성 전에 자동으로 handler가 설정되도록 하려면 MOMLView.addUIObjectHandler(2) 함수를 사용하십시오.
Parameter | Type | 설명 |
---|---|---|
handler | "[IMOMLUIObjectHandler]" | 핸들러 객체 |
[func] string runScript(script, targetId)
[declaration]
String runScript(String script)
[example]
MOMLUIObject root = getMomlView().getRoot ();
String userId = root.runScript("userVariable.userId";
if (userId != null && userId.equals("guest")) {
root.runScript("function.root.login('" + userId + "')");
}
[declaration]
- (NSString *)runScript:(NSString *)script
[example]
MOMLUIObject *root = self.momlView.root
NSString *userId = [root runScript:@"userVariable.userId"];
if (userId != nil && [userId isEqualToString:@"guest"]) {
[root runScript:[NSString stringWithFormat:@"function.root.login('%@')", userId]];
}
[declaration]
func runScript(script: String!) -> String!
[exmaple]
var root = momlView.root
var userId = root.runScript("userVariable.userId")
if userId != nil && userId == "guest" {
root.runScript("function.root.login('\(userId)')")
}
현재 UI element를 caller로 스크립트를 실행하고 결과를 리턴합니다.
- script 구문을 만들 때 문자열로 parameter에 주의하십시오. \', \, \r, \n, 과 같이 MOML Function Script에서 문자열로 바로 사용할 수 없는 문자가 포함된 경우 \ 를 붙여야 합니다.
- 어느 한 개체의 함수를 호출하거나 속성을 설정하는 경우 MOMLHelper.runFunction, setAttribute를 사용하면 편리합니다.
Parameter | Type | 설명 |
---|---|---|
script | "[script]" | 실행할 스크립트 구문 |
▹ MOMLObjectApiInfo
[declaration]
package org.mospi.moml.framework.pub.objectapi;
class ObjectApiInfo
[declaration]
MOMLObjectApiInfo.h
@interface MOMLObjectApiInfo : NSObject
[declaration]
class MOMLObjectApiInfo : NSObject
사용자 Script Object나 UI element의 API 정보를 정의합니다.
[func] MOMLObjectApiInfo createObjectApiInfo(name, modVer, addVer, delVer, parent)
[declaration]
static ObjectApiInfo createObjectApiInfo(String name, String modVer, String addVer, String delVer, Object parent)
[example]
public ObjectApiInfo getObjectApiInfo() {
ObjectApiInfo apiInfo = ObjectApiInfo.createObjectApiInfo("QRCODE", "1.0.0", "1.0.0", "", getBase());
apiInfo.registerProperty("data", null, "1.0.0", "1.0.0", "");
apiInfo.registerMethod("share", null, 0, "1.0.0", "1.0.0", "");
return apiInfo;
}
[declaration]
+ (MOMLObjectApiInfo *)createObjectApiInfoWithName:(NSString *)name modifiedVersion:(NSString *)modVer addedVersion:(NSString *)addVer deletedVersion:(NSString *)delVer parent:(MOMLObjectApiInfo *)parent
[example]
- (MOMLObjectApiInfo *)getObjectApiInfo
{
MOMLObjectApiInfo *objApiInfo = [MOMLObjectApiInfo createObjectApiInfoWithName:@"QRCODE" modifiedVersion:@"1.0.0" addedVersion:@"1.0.0" deletedVersion:@"" parent:[super getObjectApiInfo]];
REGISTER_PROPERTY(data, 1.0.0, 1.0.0, )
REGISTER_METHOD(share, 0, 1.0.0, 1.0.0, )
return objApiInfo;
}
[declaration]
class func createObjectApiInfoWithName(name: String!, modifiedVersion: String!, addedVersion: String!, deletedVersion: String!, parent: MOMLObjectApiInfo!) -> MOMLObjectApiInfo!
[example]
override func getObjectApiInfo() -> MOMLObjectApiInfo! {
var objApiInfo = MOMLObjectApiInfo.createObjectApiInfoWithName("QRCODE", modifiedVersion: "1.0.0", addedVersion: "1.0.0", deletedVersion: "", parent: getBase().getObjectApiInfo())
objApiInfo.registerPropertyName("data", internalName: nil, modifiedVersion: "1.0.0", addedVersion: "1.0.0", deletedVersion: "")
objApiInfo.registerMethodName("share", internalName: nil, parameterCount: 0, modifiedVersion: "1.0.0", addedVersion: "1.0.0", deletedVersion: "")
return objApiInfo
Script Object가 지원하는 함수 정보 테이블을 생성합니다.
- 이 함수는 사용자 Script Object나 UI element를 구현한 클래스의 getObjectApiInfo 함수를 구현할 때 사용합니다.
Parameter | Type | 설명 |
---|---|---|
name | "[identifier]" | 클래스의 이름 |
modVer | "[number].[ number].[ number]" | 클래스의 API가 마지막으로 수정된 라이브러리 버전 |
addVer | "[number].[ number].[ number]" | 클래스의 API가 최초로 추가된 라이브러리 버전 |
delVer | "[number].[ number].[ number]" | 클래스의 API가 삭제된 라이브러리 버전 |
parent | "[ObjectApiInfo]" | 부모 클래스의 ObjectApiInfo |
[func] void registerMethod(name, internalName, parameterCount, modVer, addVer, delVer)
[declaration]
void registerMethod(String name, String internalName, int parameterCount, String modVer, String addVer, String delVer)
[declaration]
- (void)registerMethodName:(NSString *)name internalName:(NSString *)internalName parameterCount:(int)parameterCount modifiedVersion:(NSString *)modVer addedVersion:(NSString *)addVer deletedVersion:(NSString *)delVer
[declaration]
func registerMethodName(name: String!, internalName: String!, parameterCount: Int32, modifiedVersion: String!, addedVersion: String!, deletedVersion: String!)
Script Object가 지원하는 함수를 선언합니다.
- 외부 이름과 내부 이름이 동일한 경우 내부 이름은 null을 사용할 수 있습니다.
- 가변 인자를 갖는 함수인 경우 parameterCount로 -1을 사용합니다.
- 일반적으로 외부 이름과 내부 이름은 동일하게 선언하는 것이 좋습니다. 그러나 만약 외부 이름이 id, return, for 등과 같은 Java나 Objective-C 에서 사용하는 키워드나 다른 함수명과 겹치는 경우 내부 이름을 다르게 하여 컴파일 오류를 피해갈 수 있습니다.
- iOS에서 실제 구현된 함수를 찾을 때는 함수의 이름과 함수 인자의 개수만 확인을 합니다. Objective-C 나 Swift에사 사용하는 함수 인자 이름은 무시합니다. 함수 인자의 개수는 같고 함수 인자 이름은 다른 여러 함수를 오버로딩하여 정의하는 일이 없도록 주의해야 합니다.
- 선언한 함수를 구현할 때는 IMOMLComponent.callFunction으로 전달된 내부 이름과 함수 인자 확인하여 직접 구현할 수도 있지만, DefaultObjectComponent.callFunction의 reflection기능을 사용하는 것이 편리합니다.
Parameter | Type | 설명 |
---|---|---|
name | "[identifier]" | 외부로 노출할 함수 이름 |
internalName | "[identifier]" | 실제로 구현한 함수 이름 |
parameterCount | "[number]" | 함수 인자 개수 |
modVer | "[number].[ number].[ number]" | 함수의 API가 마지막으로 수정된 라이브러리 버전 |
addVer | "[number].[ number].[ number]" | 함수의 API가 최초로 추가된 라이브러리 버전 |
delVer | "[number].[ number].[ number]" | 함수의 API가 삭제된 라이브러리 버전 |
[func] void registerProperty(name, internalName, modVer, addVer, delVer)
[declaration]
void registerProperty(String name, String internalName, String modVer, String addVer, String delVer)
[declaration]
- (void)registerPropertyName:(NSString *)name internalName:(NSString *)internalName modifiedVersion:(NSString *)modVer addedVersion:(NSString *)addVer deletedVersion:(NSString *)delVer
[declaration]
func registerPropertyName(name: String!, internalName: String!, modifiedVersion: String!, addedVersion: String!, deletedVersion: String!)
Script Object가 지원하는 속성을 선언합니다.
- 외부 이름과 내부 이름이 같은 경우 내부 이름은 null을 사용할 수 있습니다.
- 외부 이름과 내부 이름은 보통 동일한 이름을 사용합니다. 만약 외부 이름이 id, return, for 등과 같은 Java나 Objective-C 에서 사용하는 키워드나 다른 함수명과 겹치는 경우 내부 이름을 다르게 하여 컴파일 오류를 피해갈 수 있습니다.
- 속성을 하나 정의하는 것은 내부적으로는 get함수와 set함수 두 개를 정의하는 것과 유사합니다.
Parameter | Type | 설명 |
---|---|---|
name | "[identifier]" | 외부로 노출할 속성 이름 |
internalName | "[identifier]" | 실제로 구현한 속성 이름 |
modVer | "[number].[ number].[ number]" | 속성의 수PI가 마지막으로 수정된 라이브러리 버전 |
addVer | "[number].[ number].[ number]" | 속성의 API가 최초로 추가된 라이브러리 버전 |
delVer | "[number].[ number].[ number]" | 속성의 API가 삭제된 라이브러리 버전 |
MOML Helper Classes
MOML Helper class들은 MOML Native Interface들을 편하게 사용하기 위해 라이브러리 외부에서 별도로 구현한 클래스입니다.
- MOML Helper classes를 Component개발자가 library에 포함하여 개발하는 경우 다른 Component끼리 class가 중복되는 것을 피하기 위해 Android는 package 명을 다르게 하고, iOS는 각 class명을 다르게 하여 개발하기를 권장합니다.
- Android의 경우 Helper class가 정의된 java 파일들을 프로젝트에 복사한 후 package를 적절하게 수정하십시오.
- iOS의 경우 Helper class를 사용하기 전에 MOML_DEFAULT_COMPONENT_NAMESPACE 매크로를 적절한 이름으로 정의하십시오.
ex) DefaultUIComponent class를 MyCompanyUIComponent 로 선언하길 원하는 경우 아래와 같이 사용합니다.
DefaultComponentDefine.h
#define MOML_DEFAULT_COMPONENT_NAMESPACE MyCompany
▹ MOMLHelper
[declaration]
MOMLHelper.java
class MOMLHelper
[declaration]
MOMLHelper.h
@interface MOMLHelper : NSObject
[declaration]
MOMLHelper.swift
class MOMLHelper
MOML Native 연동을 위한 여러 함수들을 제공합니다.
[func] string runFunction(caller, function, args...)
[declaration]
static String runFunction(MOMLUIObject caller, String function, Object... args)
[example]
int count = 6;
String result = MOMLHelper.runFunction(getMomlView().getRoot(), "function.root.log", "count : ", count);
[declaration]
+ (NSString *)runFunction:(MOMLUIObject *)caller function:(NSString *)function, ...
[example]
int count = 6;
NSString *result = [MOMLHelper runFunction:self.momlView.root function:@"function.root.log", @"count", [NSNumber numberWithInt:count], nil];
[declaration]
func runFunction(caller: MOMLUIObject!, function: NSString!, args: AnyObject...) -> String!
[example]
var count = 6
var result = MOMLHelper.runFunction(momlView.root, function: "function.root.log", args: "count", count)
함수 호출 스크립트를 만들어서 시행하고 결과를 리턴합니다.
- caller의 함수를 호출하는 것이 아님에 주의하십시오. caller는 function 이름을 해석할 때 기준 위치를 판단하는 용도로 사용됩니다.
- function 이름은 함수를 호출하려는 Script Object나 UI element의 id를 포함하며 "function."으로도 시작할 수 있습니다.
ex) "root.navigation", "math.add", "function.root.log" - iOS의 경우 args의 마지막은 nil로 끝나야 합니다.
- iOS의 경우 args의 자료형은 NSString 또는 NSNumber만 사용 가능합니다.
Parameter | Type | 설명 |
---|---|---|
caller | "[MOMLUIObject]" | 함수 호출 시 caller로 지정할 UI element |
name | "[identifier][. [identifier]]..." ⎮ "function.[identifier][. [identifier]]..." | 함수를 실행할 개체.함수이름 |
args | "[[string] ⎮ [number]], ... " | 함수 파라미터 |
[func] View findViewByClass(view, class)
[declaration]
static View findViewByClass(View view, Class<?> cls)
[example]
Button button = (Button)MOMLHelper.findViewByClass(uiObject.getFrameLayout(), Button.class);
if (button != null)
button.setTextColor(Color.GREEN);
[declaration]
+ (UIView *)findView:(UIView *)view withClass:(Class)cls
[example]
UIButton *button = (UIButton*)[MOMLHelper findView:uiObject.view withClass:UIButton.class];
if (button != nil)
[button setTitleColor:[UIColor greenColor] forState:UIControlStateNormal];
[declaration]
class func findView(view: UIView!, cls: AnyClass!) -> UIView!
[example]
if let button = MOMLHelper.findView(uiObject.view, cls: UIButton.self) as? UIButton {
button.setTitleColor(UIColor.greenColor(), forState: UIControlState.Normal)
}
view와 view 자식들 중에서 class 타입과 일치하는 view를 찾습니다.
- 이 함수는 MOMLUIObject.getView() 에서 리턴된 뷰에서 실제 원하는 class 형식의 뷰를 찾을 때 유용합니다.
Parameter | Type | 설명 |
---|---|---|
view | "[View]" | 찾을 뷰, 자기 자신도 검색에 포함합니다. |
cls | "[Class]" | class 타입 |
[func] string setAttribute(caller, attribute, value)
[declaration]
static String setAttribute(MOMLUIObject caller, String attribute, Object value)
[example]
MOMLHelper.setAttribute(getMomlView().getRoot(), "userVariable.nativeValue", text);
[declaration]
+ (NSString *)setAttribute:(MOMLUIObject *)caller attribute:(NSString *)attribute value:(NSObject *)value
[example]
[MOMLHelper setAttribute:self.momlView.root attribute:@"userVariable.nativeValue" value:text];
[declaration]
class func setAttribute(caller: MOMLUIObject!, attribute: NSString!, value: AnyObject!) -> String!
[example]
MOMLHelper.setAttribute(momlView.root, attribute: "userVariable.nativeValue" value: text)
함수 호출 스크립트를 만들어서 실행하고 결과를 리턴합니다.
- caller의 속성을 설정하는 것이 아님에 주의하십시오. caller는 attribute 이름을 해석할 때 기준 위치를 판단하는 용도로 사용됩니다.
- attribute 이름은 속성을 설정하려는 Script Object나 UI element의 id를 포함합니다.
ex) "root.navigation", "date.date", - iOS의 경우 value의 자료형은 NSString 또는 NSNumber만 사용 가능합니다.
Parameter | Type | 설명 |
---|---|---|
caller | "[MOMLUIObject]" | 함수 호출 시 caller로 지정할 UI element |
attribute | "[identifier][. [identifier]]..." ⎮ "function.[identifier][. [identifier]]..." | 속성을 설정할 개체.속성이름 |
value | "[string]" ⎮ "[number]" ⎮ "function.[identifier][. [identifier]]..." | 속성 값 |
▹ DefaultUIObjectHandler
[declaration]
DefaultUIObjectHandler.java
class DefaultUIObjectHandler implements MOMLUIObjectHandler
[example]
getMomlView.addUIObjectHandler("root.coverflow1", new DefaultUIObjectHandler() {
public boolean onClick(MOMLUIObject uiObject) {
textView1.setText("MOMLView CoverFlow Index :" + uiObject.getAttribute("index"));
return true;
}
});
[declaration]
DefaultUIObjectHandler.h
@interface DefaultUIObjectHandler : NSObject <MOMLUIObjectDelegate>
[example]
[self.momlView addUIObjectHandler: [DefaultUIObjectHandler handlerWithOnClickBlock:^BOOL(MOMLUIObject *uiObject) {
[textView1 setText:[NSString stringWithFormat:@"MOMLView CoverFlow Index : %@", [uiObject getAttribute:@"index"]]];
}] forUiId:@"root.coverflow1"];
[declaration]
DefaultUIObjectHandler.swift
class DefaultUIObjectHandler : NSObject, MOMLUIObjectDelegate
[example]
momlView.addUIObjectHandler("root.nativeTestBtn", handler: DefaultUIObjectHandler(onClick:{ (uiObject) -> Bool in
textView1.text = "MOMLView CoverFlow Index : \(uiObject.getAttribute("index"))"
return false;
}))
UI element에서 발생한 이벤트를 핸들링할 수 있도록 합니다.
- UI element의 이벤트를 핸들링하기 위해서는 DefaultUIObjectObjectHandler를 상속받아 구현한 개체를 MOMLView.addUIObjectHandler(2) 함수를 사용하여 등록해야 합니다.
▹ DefaultObjectComponent
DefaultObjectComponent.java
class DefaultObjectComponent implements MOMLComponent
[example]
TestObjectComponent.java
package com.mycompany.componentdemo;
import com.mycompany.componentdemo.DefaultObjectComponent;
import org.mospi.moml.framework.pub.objectapi.ObjectApiInfo;
public class TestObjectComponent extends DefaultObjectComponent {
@Override
public ObjectApiInfo createObjectApiInfo() {
ObjectApiInfo apiInfo = ObjectApiInfo.createObjectApiInfo("test", "1.0.0", "1.0.0", "", getBase().getObjectApiInfo());
apiInfo.registerProperty("name", null, "1.0.0", "1.0.0", "");
apiInfo.registerMethod("hello", null, 0, "1.0.0", "1.0.0", "");
apiInfo.registerMethod("average", null, -1, "1.0.0", "1.0.0", "");
return apiInfo;
}
private String mName;
public TestObjectComponent() {
}
public String getName() {
return mName;
}
public void setName(String value) {
mName = value;
}
public String hello() {
return "hello";
}
public double average(Object...args) {
double sum = 0;
for (Object arg : args) {
if (arg instanceof Double) {
sum += (Double)arg;
} else {
sum += Double.parseDouble(arg.toString());
}
}
double avg = sum / args.length;
return avg;
}
}
[declaration]
DefaultObjectComponent.h
@interface MOMLNAME(ObjectComponent) : NSObject <IMOMLComponent>
[example]
DefaultComponentDefine.h
#define MOML_DEFAULT_COMPONENT_NAMESPACE MyCompanyTest
TestObjectComponent.h
#pragma push_macro("MOML_DEFAULT_COMPONENT_NAMESPACE")
#ifdef MOML_DEFAULT_COMPONENT_NAMESPACE
#undef MOML_DEFAULT_COMPONENT_NAMESPACE
#endif
#import "DefaultObjectComponent.h"
@interface TestObjectComponent : MOMLNAME(ObjectComponent)
@end
#pragma pop_macro("MOML_DEFAULT_COMPONENT_NAMESPACE")
TestObjectComponent.m
#import "TestObjectComponent.h"
#import "MOMLObjectApiInfo.h"
@interface TestObjectComponent()
{
NSString *_name;
}
@end
@implementation TestObjectComponent
- (MOMLObjectApiInfo *)createObjectApiInfo
{
MOMLObjectApiInfo *objApiInfo = [MOMLObjectApiInfo createObjectApiInfoWithName:@"test" modifiedVersion:@"1.0.0" addedVersion:@"1.0.0" deletedVersion:@"" parent:[[self getBase] getObjectApiInfo]];
REGISTER_PROPERTY(name, 1.0.0, 1.0.0, 1.0.0)
REGISTER_METHOD(hello, 0, 1.0.0, 1.0.0, 1.0.0)
REGISTER_METHOD(average, -1, 1.0.0, 1.0.0, 1.0.0)
return objApiInfo;
}
- (id) init
{
self = [super init];
return self;
}
- (NSString *)hello
{
return @"hello";
}
- (NSString *)name
{
return _name;
}
-(void)setName:(NSString *)name
{
_name = name;
}
-(double)average:(NSArray *)args
{
double sum = 0;
for (NSObject *arg in args) {
if ([arg isKindOfClass:NSNumber.class]) {
sum += [(NSNumber *)arg doubleValue];
} else if ([arg isKindOfClass:NSString.class]) {
sum += [(NSString *)arg doubleValue];
}
}
return sum / args.count;
}
@end
[declaration]
DefaultObjectComponent.swift
class DefaultObjectComponent : NSObject, IMOMLComponent
[example]
TestObjectComponent.swift
import Agate
class TestObjectComponent: DefaultObjectComponent {
var name: String?
override func createObjectApiInfo() -> MOMLObjectApiInfo! {
var objApiInfo = MOMLObjectApiInfo.createObjectApiInfo(self, "test")
objApiInfo.registerProperty("name")
objApiInfo.registerMethod("hello", 0)
objApiInfo.registerMethod("average", -1)
return objApiInfo
}
func hello() -> String {
return "hello"
}
func average(args:[AnyObject]) -> Double {
var sum: Double = 0
for arg in args {
if arg is NSNumber {
sum += (arg as NSNumber).doubleValue
} else if arg is NSString {
sum += (arg as NSString).doubleValue
}
}
return sum / Double(args.count)
}
}
이 클래스를 상속받아 사용자 Script Object를 구현할 수 있습니다.
- 사용자 Script Object를 사용하기 위해서는 DefaultObjectComponent를 상속받아 구현한 개체를 MOMLView.registerObjectComponent함수를 사용하여 등록해야 합니다.
[func] MOMLObjectApiInfo createObjectApiInfo()
[declaration]
ObjectApiInfo createObjectApiInfo()
[declaration]
- (MOMLObjectApiInfo *)createObjectApiInfo
[declaration]
func createObjectApiInfo() -> MOMLObjectApiInfo!
Script Object가 지원하는 함수에 대한 정보들을 생성하여 리턴합니다.
- DefaultObjectComponent.getObjectApiInfo() 함수는 ObjectApiInfo가 없는 경우 최초 한번만 createObjectApiInfo()를 호출합니다.
[func] string callFunction(name, args)
[declaration]
String callFunction(String name, ArrayList<Object>args)
[example]
public ObjectApiInfo createObjectApiInfo() {
...
apiInfo.registerMethod("sum", null, -1, "1.0.0", "1.0.0", "");
return apiInfo;
}
public double sum(Object...args) {
double sum = 0;
for (Object arg : args) {
if (arg instanceof Double) {
sum += (Double)arg;
} else {
sum += Double.parseDouble(arg.toString());
}
}
return sum;
}
[declaration]
- (NSString*) callFunction:(NSString *)name args:(NSArray *)args
[example]
- (MOMLObjectApiInfo *)createObjectApiInfo
{
...
REGISTER_METHOD(sum, -1, 1.0.0, 1.0.0, 1.0.0)
return objApiInfo;
}
- (double)sum:(NSArray *)args
{
double sum = 0;
for (NSObject *arg in args) {
if ([arg isKindOfClass:NSNumber.class]) {
sum += [(NSNumber *)arg doubleValue];
} else if ([arg isKindOfClass:NSString.class]) {
sum += [(NSString *)arg doubleValue];
}
}
return sum
}
[declaration]
func callFunction(name: String!, args: [AnyObject]!) -> String!
[example]
override func createObjectApiInfo() -> MOMLObjectApiInfo! {
...
objApiInfo.registerMethodName("sum", internalName: nil, parameterCount: -1, modifiedVersion: "1.0.0", addedVersion: "1.0.0", deletedVersion: "")
return objApiInfo;
}
func sum(args:[AnyObject]) -> Double {
{
double sum = 0;
for arg in args {
if arg is NSNumber {
sum += (arg as NSNumber).doubleValue
} else if arg is NSString {
sum += (arg as NSString).doubleValue
}
}
return sum
}
각 OS언어의 reflection 기능을 사용하여 class에 정의된 내부 구현 함수를 매핑하여 호출합니다.
- DefaultObjectComponent나 DefaultUIComponent를 상속받아 구현한 경우 보통 이 함수는 정의하지 않고 기본 구현을 그대로 사용하는 것이 일반적입니다.
- DefaultObjectComponent.callFunction(2)은 class에 정의된 내부 구현 함수를 찾아서 함수인자와 리턴 값을 적절하게 변환합니다.
- 속성의 실제 get/set 동작이 일어났을 때는 각 OS 언어의 관례에 따라 아래와 같이 함수로 매핑됩니다.
ex) 속성 이름이 name 인 경우
OS 언어 | get 동작 | set 동작 |
---|---|---|
Android Java | String getName() | void setName(String name) |
iOS Objective-C | - (NSString *)name | - (void) setName:(NSString *)name |
iOS Swift | String name() | void setName(name: String!) |
- iOS Objective-C 의 경우 속성 이름 변환 규칙이 @property의 함수 이름 변환 규칙과 동일하므로 함수를 만드는 대신 @property 선언을 사용할 수도 있습니다.
- class에 선언한 함수의 함수인자와 리턴값의 자료형으로 사용가능한 형식은 아래와 같습니다.
Android Java | iOS Objective-C | iOS Swift | |
---|---|---|---|
data types | boolean int long float double java.lang.String |
bool BOOL (unsigned) int (unsigned) short (unsigned) long (unsigned) long long float double const char* NSString* |
Bool Int UInt Double Float String |
- ObjectApiInfo에 함수 인자 개수를 -1로 설정하여 가변 인자를 받도록 한 함수의 경우는 전달되는 함수 인자의 자료형과 각 가변 인자들의 타입은 아래와 같습니다.
Android Java | iOS Objective-C | iOS Swift | |
---|---|---|---|
parameter type | Object... | NSArray* | [AnyObject] |
variant argument types | java.lang.String java.lang.Double |
NSString* NSNumber* |
String NSNumber |
- 가변 인자로 선언한 경우 각 가변인자들의 실제 자료형을 확인하고 원하는 자료형과 다를 경우 변환하여 사용해야 합니다.
Parameter | Type | 설명 |
---|---|---|
name | "[identifier]" | 내부 구현 함수 이름 |
args | "[array]" | 함수 파라미터 |
▹ DefaultUIComponent
[declaration]
DefaultUIComponent.java
class DefaultUIComponent extends DefaultObjectComponent implements MOMLUIComponent
[example]
TestUIComponentView.java
package com.mycompany.componentdemo;
import com.mycompany.componentdemo.DefaultObjectComponent;
import org.mospi.moml.framework.pub.objectapi.ObjectApiInfo;
import android.content.Context;
import android.view.View;
import android.webkit.WebView;
import android.webkit.WebViewClient;
public class TestUIComponentView extends DefaultUIComponent {
@Override
public ObjectApiInfo createObjectApiInfo() {
ObjectApiInfo apiInfo = ObjectApiInfo.createObjectApiInfo("TESTUI", "1.0.0", "1.0.0", "", getBase().getObjectApiInfo());
apiInfo.registerProperty("webSource", null, "1.0.0", "1.0.0", "");
apiInfo.registerMethod("back", "back", 0, "1.0.0", "1.0.0", "");
apiInfo.registerMethod("forward", "forward", 0, "1.0.0", "1.0.0", "");
return apiInfo;
}
private WebView mWebView;
private String mWebSource;
public TestUIComponentView() {
}
@Override
public void onInitialUpdate() {
// TODO Auto-generated method stub
super.onInitialUpdate();
setWebSource((String) uiObj.getProperty("webSource"));
}
@Override
public View createView(Context context) {
mWebView = new WebView(context);
mWebView.setWebViewClient(new WebViewClient() {});
return mWebView;
}
public void setWebSource(String url) {
if (url == null || url.length() == 0)
return;
mWebSource = url;
mWebView.loadUrl(url);
}
public String getWebSource() {
return mWebSource;
}
public void back() {
mWebView.goBack();
}
public void forward() {
mWebView.goForward();
}
}
[declaration]
DefaultUIComponent.h
@interface MOMLNAME(UIComponent) : MOMLNAME(ObjectComponent) <IMOMLUIComponent>
[example]
DefaultComponentDefine.h
#define MOML_DEFAULT_COMPONENT_NAMESPACE MyCompanyTest
TestUIComponentView.h
#pragma push_macro("MOML_DEFAULT_COMPONENT_NAMESPACE")
#ifdef MOML_DEFAULT_COMPONENT_NAMESPACE
#undef MOML_DEFAULT_COMPONENT_NAMESPACE
#endif
#import "DefaultUIComponent.h"
@interface TestUIComponentView : MOMLNAME(UIComponent)
@end
#pragma push_macro("MOML_DEFAULT_COMPONENT_NAMESPACE")
#ifdef MOML_DEFAULT_COMPONENT_NAMESPACE
#undef MOML_DEFAULT_COMPONENT_NAMESPACE
#endif
TestObjectComponentView.m
#import "TestUIComponentView.h"
#import "MOMLObjectApiInfo.h"
@interface TestUIComponentView ()
{
UIWebView *_webView;
NSString *_webSource;
}
@end
@implementation TestUIComponentView
- (MOMLObjectApiInfo *)createObjectApiInfo
{
MOMLObjectApiInfo *objApiInfo = [MOMLObjectApiInfo createObjectApiInfoWithName:@"TESTUI" modifiedVersion:@"1.0.0" addedVersion:@"1.0.0" deletedVersion:@"" parent:[[self getBase] getObjectApiInfo]];
REGISTER_PROPERTY(webSource, 1.0.0, 1.0.0, )
REGISTER_METHOD(back, 0, 1.0.0, 1.0.0, 1.0.0)
REGISTER_METHOD(forward, 0, 1.0.0, 1.0.0, 1.0.0)
return objApiInfo;
}
- (id) init
{
self = [super init];
return self;
}
- (UIView *) createView;
{
_webView = [[UIWebView alloc] init];
return _webView;
}
- (void) onInitialUpdate
{
[super onInitialUpdate];
[self setWebSource:[self.uiObject getAttribute:@"webSource"]];
}
- (NSString *) webSource
{
return _webSource;
}
- (void) setWebSource:(NSString *) src
{
if (src == nil || src.length == 0)
return;
_webSource = src;
NSURL *url = [NSURL URLWithString:src];
NSURLRequest *request = [NSURLRequest requestWithURL:url];
[_webView loadRequest:request];
}
- (void) back
{
[_webView goBack];
}
- (void) forward
{
[_webView goForward];
}
@end
[declaration]
DefaultUIComponent.swift
class DefaultUIComponent: DefaultObjectComponent, IMOMLUIComponent
[example]
TestUIComponentView.swift
import Agate
class TestUIComponentView: DefaultUIComponent {
private var _webView: UIWebView?
private var _webSource: String?
override func createObjectApiInfo() -> MOMLObjectApiInfo! {
var objApiInfo = MOMLObjectApiInfo.createObjectApiInfo(self, "TESTUI")
objApiInfo.registerProperty("webSource")
objApiInfo.registerMethod("back", 0)
objApiInfo.registerMethod("forward", 0)
return objApiInfo
}
override init() {
super.init()
}
override func createView() -> UIView! {
_webView = UIWebView()
return _webView;
}
override func onInitialUpdate() {
super.onInitialUpdate()
setWebSource(uiObject?.getAttribute("webSource"))
}
func webSource() -> String! {
return _webSource;
}
func setWebSource(src: String!) {
if src == nil || countElements(src) == 0 {
return
}
_webSource = src
var url : NSURL = NSURL(string: src)!
var request = NSURLRequest(URL: url)
_webView?.loadRequest(request)
}
func back() {
_webView?.goBack()
}
func forward() {
_webView?.goForward()
}
}
<?xml version="1.0" encoding="UTF-8"?>
<MOML version="1.1.7">
<THEMES>
<THEME element="BUTTON" defaultImg="#0080ff" textColor="#ffffff" margin="2,2,2,2"/>
</THEMES>
<UILAYOUT portrait="320,480" landscape="320,480">
<WINDOW layout="0,0,320,480" defaultImg="#ffffff">
<WINDOW layout="0,0,320,auto" align="linear:vertical">
<LABEL text="UI handler: " />
<WINDOW layout="320,auto" align="linear" >
<BUTTON id="nativeTestBtn" text="native onClick" onClick="'native'" />
<BUTTON text="get native value by fireEvent" onClick="device.toastPopup(root.fireEvent('onGetNativeValue', 'apple', 'orange'))" />
</WINDOW>
<LABEL text="test object: " />
<WINDOW layout="320,auto" align="linear" >
<BUTTON text="test.hello" onClick="device.toastPopup(test.hello)" />
<BUTTON text="test.average(1, 2.5, '3', 4)" onClick="device.toastPopup(test.average(1, 2.5, '3', 4))" />
</WINDOW>
<LABEL text="TESTUI element: " />
<WINDOW layout="320,auto" align="linear" >
<BUTTON text="set webSource" onClick="custom1.webSource = 'http://mospi.org'" />
<BUTTON text="get webSource" onClick="device.toastPopup(custom1.webSource)" />
</WINDOW>
<WINDOW layout="320,auto" align="linear">
<BUTTON text="back" onClick="custom1.back" />
<BUTTON text="forward" onClick="custom1.forward" />
</WINDOW>
</WINDOW>
<TESTUI id="custom1" layout="0,prev.bottom,320,parent.height-prev.bottom" webSource="http://google.com" onTest="function.onTestEvent" defaultImg="#ff0000"/>
</WINDOW>
</UILAYOUT>
<FUNCTION id="onNativeCall(arg1)" >
<RETURN condition="arg1 == userVariable.nativeValue" cmd="'received arg1:\n' + arg1" elseCmd="'arg1 is not equal to userVariable.nativeValue'"/>
</FUNCTION>
</MOML>
이 클래스를 상속받아 사용자 UI element를 구현할 수 있습니다.
- 사용자 UI element를 사용하기 위해서는 DefaultUIComponent를 상속받아 구현한 개체를 MOMLView.registerObjectComponent함수를 사용하여 등록해야 합니다.
MOML Native Interfaces
MOML Native Interface들은 라이브러리 외부에서 개발자가 구현해야 하는 인터페이스들입니다.
이 인터페이스를 바로 직접 구현하는 것보다는 Helper class들을 사용하는 것이 편리합니다.
▹ IMOMLUIObjectHandler
[declaration]
package org.mospi.moml.framework.pub.core;
interface MOMLUIObjectHandler
[declaration]
MOMLUIObject.h
@protocol MOMLUIObjectDelegate<NSObject>
[declaration]
protocol MOMLUIObjectDelegate : NSObjectProtocol
UI element에서 발생한 이벤트를 핸들링할 수 있도록 합니다.
- UI element의 이벤트를 핸들링하기 위해서는 IMOMLUIObjectHandler를 구현한 개체를 MOMLView.addUIObjectHandler(2) 함수를 사용하여 등록해야 합니다.
- 실제 개발할 때는 이 인터페이스를 직접 구현하는 것보다 DefaultUIObjectHandler를 사용하는 것이 편리합니다.
[func] string onEvent(uiObject, eventName, args...)
[declaration]
String onEvent(MOMLUIObject uiObject, String eventName, String... args);
[declaration]
- (NSString *)momlUIObject:(MOMLUIObject *)momlUIObject onEvent:(NSString *)eventName args:(NSArray *)args;
[declaration]
optional func momlUIObject(momlUIObject: MOMLUIObject!, onEvent eventName: String!, args: [AnyObject]!) -> String!
UI element의 이벤트가 발생되면 호출됩니다.
- 모든 UI element는 기본적으로 onCreate, onDestroy, onShow, onHide, onClick 이벤트를 발생합니다.
- 사용자 정의 이벤트를 발생시키기 위해서는 WINDOW.fireEvent(v) 함수를 사용하십시오.
- onClick 이벤트는 UI element의 onClick 속성 값이 존재해야 합니다. 따라서 MOML XML에서는 onClick이 필요 없더라도 Native에서 onClick 이벤트를 핸들링 하기 위에서는 임의의 값이 존재해야 합니다.
ex) onClick에서 문자열을 리턴하는 것은 아무 의미가 없지만 Native의 event 에서 처리할 수 있도록 한다.
<BUTTON onClick="'native'" />
Parameter | Type | 설명 |
---|---|---|
uiObject | "[MOMLUIObject]" | 이벤트가 발생한 UI element를 제어할 수 있는 MOMLUIObject 인터페이스 |
▹ IMOMLComponent
[declaration]
package org.mospi.moml.framework.pub.object;
interface MOMLComponent
[declaration]
IMOMLComponent.h
@protocol IMOMLComponent <NSObject>
[declaration]
protocol IMOMLComponent : NSObjectProtocol
사용자 Script Object는 이 인터페이스를 상속받아 구현해야 합니다.
- 사용자 Script Object를 사용하기 위해서는 IMOMLComponent를 구현한 개체를 MOMLView.registerObjectComponent함수를 사용하여 등록해야 합니다.
- 실제 개발할 때는 이 인터페이스를 직접 구현하는 것보다 DefaultObjectComponent를 사용하는 것이 편리합니다.
[func] string callFunction(name, args)
[declaration]
String callFunction(String name, ArrayList<Object>args)
[example]
public String callFunction(String name, ArrayList<Object> args) {
if (name.equals("text") && args.size() == 0)
return getText();
if (name.equals("setText") && args.size() == 1) {
setText(args.get(0));
return null;
}
return baseComponent.callFunction(name, args);
}
[declaration]
- (NSString*) callFunction:(NSString *)name args:(NSArray *)args
[example]
- (NSString*) callFunction:(NSString *)name args:(NSArray *)args
{
if ([name isEqualToString:@"text"] && args.count == 0)
return self.text;
if ([name isEqualToString:@"setText"] && args.count == 1) {
[self setText:[args objectAtIndex:0]];
return nil;
}
return [_baseComponent callFunction:name args:args];
}
[declaration]
func callFunction(name: String!, args: [AnyObject]!) -> String!
[example]
func callFunction(name: String!, args: [AnyObject]!) -> String!
{
if name == "text" && args.count == 0 {
return self.text
}
if name == "setText" && args.count == 1 {
self.text = args[0]
}
return baseComponent?.callFunction(name args: args)
}
함수 호출이나 속성의 get/set을 구현합니다.
- 함수의 외부 이름과 내부 이름이 다른 경우 name은 내부 이름으로 호출됩니다.
- 속성은 "MOML Attribute의 Function 변환" 규칙에 따라 함수로 변경되어 호출됩니다.
ex) 속성 이름이 text인경우 name과 args는 상황에 따라 아래의 값을 갖습니다.
사용예 | name | args |
---|---|---|
str = obj.text | "text" | [] (길이가 0인 배열) |
obj.text = "TEST" | "setText" | ["TEST"] (value 1개를 포함한 배열) |
- 직접 구현하지 않은 경우 base component의 callFunction을 호출해야 합니다.
- 이 함수를 구현하여 이름과 함수를 매핑하는 작업은 상당히 번거롭기 때문에 DefaultObjectComponent를 사용하는 것이 편리합니다.
Parameter | Type | 설명 |
---|---|---|
name | "[identifier]" | 내부 구현 함수 이름 |
args | "[array]" | 함수 파라미터 |
[func] IMOMLComponent getBase()
[declaration]
MOMLComponent getBase()
[declaration]
- (id<IMOMLComponent>) getBase
[declaration]
func getBase() -> IMOMLComponent!
base component를 리턴합니다.
- 보통 initBase(3)함수에서 넘겨준 baseComponent를 리턴합니다.
[func] MOMLObjectApiInfo getObjectApiInfo()
[declaration]
ObjectApiInfo getObjectApiInfo()
[example]
public ObjectApiInfo getObjectApiInfo() {
ObjectApiInfo apiInfo = ObjectApiInfo.createObjectApiInfo("QRCODE", "1.0.0", "1.0.0", "", getBase().getObjectApiInfo());
apiInfo.registerProperty("data", null, "1.0.0", "1.0.0", "");
apiInfo.registerMethod("share", null, 0, "1.0.0", "1.0.0", "");
return apiInfo;
}
[declaration]
- (MOMLObjectApiInfo *)getObjectApiInfo
[example]
- (MOMLObjectApiInfo *)getObjectApiInfo
{
MOMLObjectApiInfo *objApiInfo = [MOMLObjectApiInfo createObjectApiInfoWithName:@"QRCODE" modifiedVersion:@"1.0.0" addedVersion:@"1.0.0" deletedVersion:@"" parent:[[self getBase] getObjectApiInfo]];
REGISTER_PROPERTY(data, 1.0.0, 1.0.0, )
REGISTER_METHOD(share, 0, 1.0.0, 1.0.0, )
return objApiInfo;
}
[declaration]
func getObjectApiInfo() -> MOMLObjectApiInfo!
[example]
override func getObjectApiInfo() -> MOMLObjectApiInfo! {
var objApiInfo = MOMLObjectApiInfo.createObjectApiInfoWithName("QRCODE", modifiedVersion: "1.0.0", addedVersion: "1.0.0", deletedVersion: "", parent: getBase().getObjectApiInfo())
objApiInfo.registerPropertyName("data", internalName: nil, modifiedVersion: "1.0.0", addedVersion: "1.0.0", deletedVersion: "")
objApiInfo.registerMethodName("share", internalName: nil, parameterCount: 0, modifiedVersion: "1.0.0", addedVersion: "1.0.0", deletedVersion: "")
return objApiInfo
}
Script Object가 지원하는 함수에 대한 정보들을 리턴합니다.
- MOMLObjectApiInfo는 MOMLObjectApiInfo.createObjectApiInfo(5) 함수로 생성할 수 있습니다.
[func] void initBase(baseComponent, userObj, momlObj)
[declaration]
void initBase(Context context, MOMLComponent base, Object userObj, MOMLObject momlObj)
[example]
public void initBase(final Context context, MOMLComponent base, Object userObj, MOMLObject obj) {
this.context = context;
this.baseComponent = base;
this.obj = obj;
this.userObj = userObj;
}
[declaration]
void initBase(Context context, MOMLComponent base, Object userObj, MOMLObject momlObj)
[example]
- (void) initBase:(id<IMOMLComponent>)base userObject:(NSObject *)userObj object:(MOMLObject *)object
{
_baseComponent = base;
_userObject = userObj;
_object = object;
}
[declaration]
func initBase(base: IMOMLComponent!, userObject userObj: NSObject!, object: MOMLObject!)
[example]
func initBase(base: IMOMLComponent!, userObject userObj: NSObject!, object: MOMLObject!) {
self.baseComponent = base
self.userObject = userObj
self.object = object
}
Script Object가 생성될 때 호출됩니다.
- initBase함수는 개체 생성시 호출되므로 초기화 작업을 할 수 있습니다.
- initBase함수의 파라미터로 넘겨온 값들은 추후 사용을 위해 저장해 두는 것이 좋습니다.
Parameter | Type | 설명 |
---|---|---|
base | "[IMOMLComponent]" | base component 인터페이스 |
userObj | "[object]" | component 등록 시 전달한 사용자 정의 object |
momlObj | "[object]" | 현재 component의 MOMLObject 인터페이스 |
▹ IMOMLUIComponent
[declaration]
package org.mospi.moml.framework.pub.ui;
interface MOMLUIComponent
[declaration]
IMOMLComponent.h
@protocol IMOMLUIComponent <NSObject>
[declaration]
protocol IMOMLUIComponent : IMOMLComponent, NSObjectProtocol
사용자 UI element는 이 인터페이스를 상속받아 구현해야 합니다.
- 사용자 UI element를 사용하기 위해서는 IMOMLUIComponent를 구현한 개체를 MOMLView.registerUIComponent함수를 사용하여 등록해야 합니다.
- 실제 개발할 때는 이 인터페이스를 직접 구현하는 것보다 DefaultUIComponent를 사용하는 것이 편리합니다.
[func] View createView()
[declaration]
View createView(Context context)
[example]
public View createView(Context context) {
mView = new TextView(context);
mView.setText("CustomUIComponent");
return mView;
}
[declaration]
- (UIView *) createView
[example]
- (UIView *) createView;
{
_view = [[UITextView alloc] init];
return _view;
}
[declaration]
func createView() -> UIView!
[example]
func createView() -> UIView! {
view = UITextView();
return view
}
UI element의 native view를 생성하여 리턴합니다.
[func] void layout(rect)
[declaration]
void layout(int l, int t, int r, int b)
[declaration]
- (void) layout:(CGRect) rect
[declaration]
func layout(rect: CGRect)
UI element의 크기를 조절하고 내부 뷰들을 크기에 맞추어 재배치 합니다.
- 단순한 UI인 경우 이 함수에서 직접 위치를 수정하는 것보다는 Android의 LayoutParam.MATCH_PARENT나 iOS의 UIView.autoResizingMask 등처럼 각각의 OS SDK가 제공하는 레이아웃을 자동으로 맞출 수 있는 API들을 사용하길 권장합니다.
[func] void onInitialUpdate()
[declaration]
void onInitialUpdate()
[declaration]
- (void) onInitialUpdate
[declaration]
func onInitialUpdate()
UI element의 화면 배치가 끝난 후 최초 한 번 호출됩니다.
- onInitialUpdate함수는 화면 배치가 끝난 다음 호출됩니다. 주로 화면 배치 이후 필요한 초기화 작업을 수행하기에 적절합니다. 그러나 createView나 layout함수보다도 나중에 호출되므로 일반적인 초기화 작업은 적절하지 않을 수 있습니다. 변수 초기화 같은 기본적인 초기화 작업은 생성자 함수에서 수행하고, element attribute와 관련된 초기화 작업은 initBase 함수에서 수행하도록 하십시오.
[func] string onEvent(eventName, args...)
[declaration]
String onEvent(String eventName, String... args)
[example]
public String onEvent(String eventName, String... args) {
return ((MOMLUIComponent)baseComponent).onEvent(eventName, args);
}
[declaration]
- (NSString *)onEvent:(NSString *)eventName args:(NSArray *)args
[example]
- (NSString *)onEvent:(NSString *)eventName args:(NSArray *)args
{
return [_uiBaseComponent onEvent:eventName args:args];
}
[declaration]
func onEvent(eventName: String!, args: [AnyObject]!) -> String!
[example]
func onEvent(eventName: String!, args: [AnyObject]!) -> String!
{
return uiBaseComponent?.onEvent(eventName, args: args)
}
이벤트를 전달합니다.
- onCreate, onDestroy, onClick, onShow, onHide 등의 WINDOW 이벤트에 따라 필요한 동작을 추가할 수 있습니다.
- 최상위 baseComponent (WINDOW)의 onEvent 함수의 구현은 IMOMLUIObjectHandler로 이벤트를 전달한 후 지정한 이벤트 이름을 가진 속성을 스크립트로 실행하도록 되어 있습니다.
Parameter | Type | 설명 |
---|---|---|
eventName | "[identifier]" | onClick, onChange와 같은 이벤트 이름 |
MOML Native Layout XML
▹ MOMLView
[declaration]
package org.mospi.moml.framework.pub.core;
org.mospi.moml.framework.pub.core.MOMLView
[example]
/res/values/org_mospi_moml_framework_attrs.xml
<?xml version="1.0" encoding="utf-8"?>
<resources>
<declare-styleable name="MOMLView">
<attr name="applicationInfo" format="string" />
<attr name="startUrl" format="string" />
</declare-styleable>
</resources>
/res/layout/activity_main.xml
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
xmlns:moml="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity" >
<TextView
android:id="@+id/labelNativeArea"
android:layout_width="wrap_content"
android:layout_height="40dp"
android:layout_gravity="top|left"
android:gravity="center_vertical"
android:text="native button : " />
<Button
android:id="@+id/button1"
android:layout_width="wrap_content"
android:layout_height="40dp"
android:layout_gravity="top|right"
android:layout_toRightOf="@id/labelNativeArea"
android:text="function.root.onNativeCall"
android:onClick="onButton1Click"/>
<org.mospi.moml.framework.pub.core.MOMLView
android:id="@+id/momlView1"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_gravity="top|left"
android:layout_marginTop="40dp"
moml:applicationInfo="embed:/moml/applicationInfo.xml" />
</RelativeLayout>
MainActivity.java
@Override
public class MainActivity extends MOMLActivity {
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// uses momlView from layout resource
MOMLView momlView1 = (MOMLView) findViewById(R.id.momlView1);
setMomlView(momlView1);
}
}
[declaration]
MOMLView.h
@interface MOMLView : UIView
[example]
MOMLViewIB.m
#import "MOMLView.h"
#ifdef TARGET_INTERFACE_BUILDER
@implementation MOMLView(InterfaceBuilder)
- (void)drawRect:(CGRect)rect {
CGRect frame = self.bounds;
// background
[[UIColor colorWithRed:0.8 green:0.9 blue:1 alpha:1] set];
UIRectFill(frame);
// background text
[[UIColor colorWithRed:1 green:1 blue:1 alpha:0.5] set];
CGFloat fontSize = MIN(self.bounds.size.width / 4, self.bounds.size.height / 2);
[@"MOML" drawInRect:CGRectMake(0, (frame.size.height - fontSize) / 2, frame.size.width, fontSize) withFont:[UIFont systemFontOfSize:fontSize] lineBreakMode:NSLineBreakByClipping alignment:NSTextAlignmentCenter];
// msg text
[[UIColor colorWithRed:0 green:0 blue:0 alpha:1] set];
UIFont *font = [UIFont systemFontOfSize:10];
CGRect msgRect = CGRectInset(frame, 5, 2);
NSString *msg = @"applicationInfo or startUrl is not specified.";
if (self.applicationInfo)
msg = [NSString stringWithFormat:@"Application Info :\n\t%@", self.applicationInfo];
else if (self.startUrl)
msg = [NSString stringWithFormat:@"Start Url :\n\t%@", self.startUrl];
[msg drawInRect:msgRect withFont:font];
}
@end
#endif // TARGET_INTERFACE_BUILDER
[declaration]
MOMLView.h
@interface MOMLView : UIView
화면의 일부 영역만 MOMLView를 사용하는 경우 Android Layout Editor나 Xcode의 Interface Builder를 통하여 MOMLView를 생성하도록 할 수도 있습니다.
- MOMLViewController 없이 MOMLView만 사용하는 경우 MOMLViewController를 사용하는 일부 기능들은 오동작하거나 동작하지 않을 수 있습니다. (ex : Android의 back 키 동작)
- Native Layout에서 생성된 MOMLView를 MOMLViewController에 연결할 때는 MOMLView를 사용하는 다른 작업들보다 먼저 수행되어야 합니다. MOMLViewController는 필요에 따라 MOMLView를 자동으로 생성하므로 다른 작업이 먼저 수행될 경우 두 개의 MOMLView가 생성되게 됩니다.
Android
- Android Layout Editor에서 MOMLView의 applicationInfo나 startUrl 속성을 사용하기 위해서는 resources/declare-styleable element를 정의해야 합니다.
iOS
- Interface Builder의 Attributes Inspector에서 MOMLView의 applicationInfo나 startUrl 속성을 사용하기 위해서는 MOMLView.h 가 프로젝트에 포함되어 있어야 합니다.
- ViewController 소스에서 MOMLView에 대해 추가적인 다른 작업을 하기 위해서는 다른 View들과 마찬가지로 ViewController에 MOMLView에 대한 Referencing Outlet을 설정해야 합니다.
- MOMLUIViewController를 사용하는 경우 MOMLView의 Referencing Outlet으로 MOMLUIViewController의 momlView Outlet을 연결하십시오.
- MOMLView의 – (void)drawRect:(CGRect)rect 함수를 재정의하여 Interface Builder에서 MOMLView영역이 그려지도록 할 수 있습니다.
[attr] string applicationInfo
[declaration]
<attr name="applicationInfo" format="string" />
[declaration]
@property (nonatomic) IBInspectable NSString *applicationInfo
[declaration]
@property (nonatomic) IBInspectable NSString *applicationInfo
뷰가 로딩될 때 자동으로 MOMLView.loadApplication(1)함수를 사용하여 로딩할 MOML Application Info XML 파일을 지정합니다.
- applicationInfo와 startUrl을 둘 다 지정한 경우 applicationInfo만 동작합니다.
[attr] string startUrl
[declaration]
<attr name="startUrl" format="string" />
[declaration]
@property (nonatomic) IBInspectable NSString *startUrl
[declaration]
@property (nonatomic) IBInspectable NSString *startUrl
뷰가 로딩될 때 자동으로 MOMLView.loadUrl(1)함수를 사용하여 로딩할 MOML UI XML 파일을 지정합니다.
- applicationInfo와 startUrl을 둘 다 지정한 경우 startUrl은 무시됩니다.