diff --git a/gogio/androidbuild.go b/gogio/androidbuild.go
index f6dc924..03951a0 100644
--- a/gogio/androidbuild.go
+++ b/gogio/androidbuild.go
@@ -48,6 +48,7 @@ type manifestData struct {
Features []string
IconSnip string
AppName string
+ Schemes []string
}
const (
@@ -442,6 +443,7 @@ func exeAndroid(tmpDir string, tools *androidTools, bi *buildInfo, extraJars, pe
Features: features,
IconSnip: iconSnip,
AppName: appName,
+ Schemes: bi.schemes,
}
tmpl, err := template.New("test").Parse(
`
@@ -458,11 +460,20 @@ func exeAndroid(tmpDir string, tools *androidTools, bi *buildInfo, extraJars, pe
android:theme="@style/Theme.GioApp"
android:configChanges="screenSize|screenLayout|smallestScreenSize|orientation|keyboardHidden"
android:windowSoftInputMode="adjustResize"
+ android:launchMode="singleInstance"
android:exported="true">
+ {{range .Schemes}}
+
+
+
+
+
+
+ {{end}}
`)
diff --git a/gogio/build_info.go b/gogio/build_info.go
index f168330..5c17f41 100644
--- a/gogio/build_info.go
+++ b/gogio/build_info.go
@@ -31,6 +31,7 @@ type buildInfo struct {
notaryAppleID string
notaryPassword string
notaryTeamID string
+ schemes []string
}
type Semver struct {
@@ -78,6 +79,7 @@ func newBuildInfo(pkgPath string) (*buildInfo, error) {
notaryAppleID: *notaryID,
notaryPassword: *notaryPass,
notaryTeamID: *notaryTeamID,
+ schemes: getCommaList(*schemes),
}
return bi, nil
}
@@ -147,6 +149,15 @@ func getLdFlags(appID string) string {
return strings.Join(ldflags, " ")
}
+func getCommaList(s string) (list []string) {
+ for _, v := range strings.Split(s, ",") {
+ if v := strings.TrimSpace(v); v != "" {
+ list = append(list, v)
+ }
+ }
+ return list
+}
+
type packageMetadata struct {
PkgPath string
Dir string
diff --git a/gogio/help.go b/gogio/help.go
index d6f6554..0338344 100644
--- a/gogio/help.go
+++ b/gogio/help.go
@@ -82,4 +82,9 @@ for details. If not provided, the password will be prompted.
The -notaryteamid flag specifies the team ID to use for notarization of MacOS app, ignored if
-notaryid is not provided.
+
+The -schemes flag specifies a list of comma separated URI schemes that the program can
+handle. For example, use -schemes yourAppName to receive a app.URLEvent for URIs
+starting with yourAppName://. It is only supported on Android, iOS, macOS and Windows.
+On Windows, it will restrict the program to a single instance.
`
diff --git a/gogio/iosbuild.go b/gogio/iosbuild.go
index 00594f0..5d1db69 100644
--- a/gogio/iosbuild.go
+++ b/gogio/iosbuild.go
@@ -4,6 +4,7 @@ package main
import (
"archive/zip"
+ "bytes"
"crypto/sha1"
"encoding/hex"
"errors"
@@ -15,6 +16,7 @@ import (
"slices"
"strconv"
"strings"
+ "text/template"
"time"
"golang.org/x/sync/errgroup"
@@ -302,36 +304,57 @@ func buildInfoPlist(bi *buildInfo) string {
case "tvos":
supportPlatform = "AppleTVOS"
}
- return fmt.Sprintf(`
+
+ manifestSrc := struct {
+ AppName string
+ AppID string
+ Version string
+ VersionCode uint32
+ Platform string
+ MinVersion int
+ SupportPlatform string
+ Schemes []string
+ }{
+ AppName: appName,
+ AppID: bi.appID,
+ Version: bi.version.String(),
+ VersionCode: bi.version.VersionCode,
+ Platform: platform,
+ MinVersion: minIOSVersion,
+ SupportPlatform: supportPlatform,
+ Schemes: bi.schemes,
+ }
+
+ tmpl, err := template.New("manifest").Parse(`
CFBundleDevelopmentRegion
en
CFBundleExecutable
- %s
+ {{.AppName}}
CFBundleIdentifier
- %s
+ {{.AppID}}
CFBundleInfoDictionaryVersion
6.0
CFBundleName
- %s
+ {{.AppName}}
CFBundlePackageType
APPL
CFBundleShortVersionString
- %s
+ {{.Version}}
CFBundleVersion
- %d
+ {{.VersionCode}}
UILaunchStoryboardName
LaunchScreen
UIRequiredDeviceCapabilities
arm64
DTPlatformName
- %s
+ {{.Platform}}
DTPlatformVersion
12.4
MinimumOSVersion
- %d
+ {{.MinVersion}}
UIDeviceFamily
1
@@ -339,7 +362,7 @@ func buildInfoPlist(bi *buildInfo) string {
CFBundleSupportedPlatforms
- %s
+ {{.SupportPlatform}}
UISupportedInterfaceOrientations
@@ -354,13 +377,36 @@ func buildInfoPlist(bi *buildInfo) string {
DTSDKBuild
16G73
DTSDKName
- %s12.4
+ {{.Platform}}12.4
DTXcode
1030
DTXcodeBuild
10G8
+ {{if .Schemes}}
+ CFBundleURLTypes
+
+ {{range .Schemes}}
+
+ CFBundleURLSchemes
+
+ {{.}}
+
+
+ {{end}}
+
+ {{end}}
-`, appName, bi.appID, appName, bi.version, bi.version.VersionCode, platform, minIOSVersion, supportPlatform, platform)
+`)
+ if err != nil {
+ panic(err)
+ }
+
+ var manifestBuffer bytes.Buffer
+ if err := tmpl.Execute(&manifestBuffer, manifestSrc); err != nil {
+ panic(err)
+ }
+
+ return manifestBuffer.String()
}
func iosPlatformFor(target string) string {
diff --git a/gogio/macosbuild.go b/gogio/macosbuild.go
index c77f350..b9b79dd 100644
--- a/gogio/macosbuild.go
+++ b/gogio/macosbuild.go
@@ -1,6 +1,7 @@
package main
import (
+ "bytes"
"errors"
"fmt"
"os"
@@ -34,9 +35,7 @@ func buildMac(tmpDir string, bi *buildInfo) error {
return err
}
- if err := builder.setInfo(bi, name); err != nil {
- return fmt.Errorf("can't build the resources: %v", err)
- }
+ builder.setInfo(bi, name)
for _, arch := range bi.archs {
tmpDest := filepath.Join(builder.TempDir, filepath.Base(builder.DestDir))
@@ -122,7 +121,20 @@ func (b *macBuilder) setIcon(path string) (err error) {
return err
}
-func (b *macBuilder) setInfo(buildInfo *buildInfo, name string) error {
+func (b *macBuilder) setInfo(buildInfo *buildInfo, name string) {
+
+ manifestSrc := struct {
+ Name string
+ Bundle string
+ Version Semver
+ Schemes []string
+ }{
+ Name: name,
+ Bundle: buildInfo.appID,
+ Version: buildInfo.version,
+ Schemes: buildInfo.schemes,
+ }
+
t, err := template.New("manifest").Parse(`
@@ -137,20 +149,28 @@ func (b *macBuilder) setInfo(buildInfo *buildInfo, name string) error {
CFBundlePackageType
APPL
+ {{if .Schemes}}
+ CFBundleURLTypes
+
+ {{range .Schemes}}
+
+ CFBundleURLSchemes
+
+ {{.}}
+
+
+ {{end}}
+
+ {{end}}
`)
if err != nil {
- return err
+ panic(err)
}
- var manifest bufferCoff
- if err := t.Execute(&manifest, struct {
- Name, Bundle string
- }{
- Name: name,
- Bundle: buildInfo.appID,
- }); err != nil {
- return err
+ var manifest bytes.Buffer
+ if err := t.Execute(&manifest, manifestSrc); err != nil {
+ panic(err)
}
b.Manifest = manifest.Bytes()
@@ -164,8 +184,6 @@ func (b *macBuilder) setInfo(buildInfo *buildInfo, name string) error {
`)
-
- return nil
}
func (b *macBuilder) buildProgram(buildInfo *buildInfo, binDest string, name string, arch string) error {
diff --git a/gogio/main.go b/gogio/main.go
index 5945250..fb730f2 100644
--- a/gogio/main.go
+++ b/gogio/main.go
@@ -41,6 +41,7 @@ var (
notaryID = flag.String("notaryid", "", "specify the apple id to use for notarization.")
notaryPass = flag.String("notarypass", "", "specify app-specific password of the Apple ID to be used for notarization.")
notaryTeamID = flag.String("notaryteamid", "", "specify the team id to use for notarization.")
+ schemes = flag.String("schemes", "", "specify a list of comma separated URL schemes that the program accepts")
)
func main() {
diff --git a/gogio/windowsbuild.go b/gogio/windowsbuild.go
index af93bb2..40dd7aa 100644
--- a/gogio/windowsbuild.go
+++ b/gogio/windowsbuild.go
@@ -202,10 +202,18 @@ func (b *windowsBuilder) buildProgram(buildInfo *buildInfo, name string, arch st
dest = filepath.Join(filepath.Dir(b.DestDir), name+"_"+arch+".exe")
}
+ ldflags := buildInfo.ldflags
+ if buildInfo.schemes != nil {
+ ldflags += ` -X "gioui.org/app.schemesURI=` + strings.Join(buildInfo.schemes, ",") + `" `
+ }
+ if buildInfo.appID != "" {
+ ldflags += ` -X "gioui.org/app.ID=` + buildInfo.appID + `" `
+ }
+
cmd := exec.Command(
"go",
"build",
- "-ldflags=-H=windowsgui "+buildInfo.ldflags,
+ "-ldflags=-H=windowsgui "+ldflags,
"-tags="+buildInfo.tags,
"-o", dest,
buildInfo.pkgPath,