애플리케이션 개발
Wails로 애플리케이션을 개발하기 위한 엄격한 규칙은 없으나 몇 가지의 기본 가이드가 있습니다.
애플리케이션 셋업
기본 템플릿에서 사용되는 패턴은 main.go가 애플리케이션 구성 및 실행에 사용되는 반면 app.go는 애플리케이션 로직 정의에 사용된다는 것입니다.
app.go 파일은 기본 애플리케이션에 hook 역할을 하는 2개의 메소드가 있는 구조체를 정의합니다.
type App struct {
ctx context.Context
}
func NewApp() *App {
return &App{}
}
func (a *App) startup(ctx context.Context) {
a.ctx = ctx
}
func (a *App) shutdown(ctx context.Context) {
}
-
시작 메서드는 Wails가 필요한 리소스를 할당하는 즉시 호출되며 리소스 생성, 이벤트 리스너 설정 및 시작 시 응용 프로그램에 필요한 모든 것을 설정하기에 좋은 위치입니다. 일반적으로 구조체 필드에 저장되는
context.Context가 제공됩니다. 이 컨텍스트는 런타임을 호출하는 데 필요합니다. 이 메서드가 오류를 반환하면 응용 프로그램이 종료됩니다. 개발 모드에서는 오류가 콘솔에 출력됩니다. -
Shutdown 메소드는 shutdown 프로세스가 끝날 때 바로 Wails에 의해 호출됩니다. 이것은 메모리 할당을 해제하고 모든 shutodown 작업을 수행하기에 좋은 위치입니다.
main.go 파일은 일반적으로 애플리케이션 구성을 허용하는 wails.Run()에 대한 단일 호출로 구성됩니다. 템플릿에서 사용하는 패턴은 wails.Run()을 호출하기 전에 app.go에서 정의한 구조체의 인스턴스가 생성되어 변수에 저장된다는 것입니다. 이것은 app이라고 합니다. 이 configuration 은 콜백을 추가하는 위치입니다:
func main() {
app := NewApp()
err := wails.Run(&options.App{
Title: "My App",
Width: 800,
Height: 600,
OnStartup: app.startup,
OnShutdown: app.shutdown,
})
if err != nil {
log.Fatal(err)
}
}
애플리케이션 lifecycle hook에 대한 자세한 내용은 여기에서 확인할 수 있습니다.
바인딩 메소드
프론트엔드에서 Go 메서드를 호출할 가능성이 높습니다. 이는 일반적으로 app.go에서 이미 정의된 구조체에 public method를 추가하여 수행됩니다.
type App struct {
ctx context.Context
}
func NewApp() *App {
return &App{}
}
func (a *App) startup(ctx context.Context) {
a.ctx = ctx
}
func (a *App) shutdown(ctx context.Context) {
}
func (a *App) Greet(name string) string {
return fmt.Sprintf("Hello %s!", name)
}
메인 어플리케이션 구성에서, Bind 키는 Wails에 무엇을 바인딩할지 알릴 수 있는 부분입니다.
func main() {
app := NewApp()
err := wails.Run(&options.App{
Title: "My App",
Width: 800,
Height: 600,
OnStartup: app.startup,
OnShutdown: app.shutdown,
Bind: []interface{}{
app,
},
})
if err != nil {
log.Fatal(err)
}
}
이렇게 하면 App 구조체의 모든 공개 메서드가 바인딩됩니다(시작 및 종료 메서드는 바인딩되지 않음).
여러 구조체를 바인딩할 때의 컨텍스트 처리
여러 구조체에 대한 메서드를 바인딩하고 싶지만 런타임을 사용할 수 있도록 각 구조체가 컨텍스트에 대한 참조를 유지하기를 원하는 경우, 함수에서 좋은 패턴은 OnStartup 메서드에서 구조체 인스턴스로 컨텍스트를 전달하는 것입니다.
func main() {
app := NewApp()
otherStruct := NewOtherStruct()
err := wails.Run(&options.App{
Title: "My App",
Width: 800,
Height: 600,
OnStartup: func(ctx context.Context){
app.SetContext(ctx)
otherStruct.SetContext(ctx)
},
OnShutdown: app.shutdown,
Bind: []interface{}{
app,
otherStruct
},
})
if err != nil {
log.Fatal(err)
}
}
Also you might want to use Enums in your structs and have models for them on frontend. In that case you should create array that will contain all possible enum values, instrument enum type and bind it to the app:
type Weekday string
const (
Sunday Weekday = "Sunday"
Monday Weekday = "Monday"
Tuesday Weekday = "Tuesday"
Wednesday Weekday = "Wednesday"
Thursday Weekday = "Thursday"
Friday Weekday = "Friday"
Saturday Weekday = "Saturday"
)
var AllWeekdays = []struct {
Value Weekday
TSName string
}{
{Sunday, "SUNDAY"},
{Monday, "MONDAY"},
{Tuesday, "TUESDAY"},
{Wednesday, "WEDNESDAY"},
{Thursday, "THURSDAY"},
{Friday, "FRIDAY"},
{Saturday, "SATURDAY"},
}
In the main application configuration, the EnumBind key is where we can tell Wails what we want to bind enums as well:
func main() {
app := NewApp()
err := wails.Run(&options.App{
Title: "My App",
Width: 800,
Height: 600,
OnStartup: app.startup,
OnShutdown: app.shutdown,
Bind: []interface{}{
app,
},
EnumBind: []interface{}{
AllWeekdays,
},
})
if err != nil {
log.Fatal(err)
}
}
This will add missing enums to your model.ts file.
바인딩에 대한 더 많은 정보는 여기에서 확인할 수 있습니다.