### Install APNS/2 Package Source: https://github.com/sideshow/apns2/blob/master/README.md Installs the APNS/2 Go package using the go get command. Also shows how to install the testify package for running the test suite. ```sh go get -u github.com/sideshow/apns2 go get -u github.com/stretchr/testify ``` -------------------------------- ### Go Curl Example Help Source: https://github.com/sideshow/apns2/blob/master/vendor/github.com/alecthomas/kingpin/README.md Displays the help information for the Go-based curl example. This includes usage instructions, available flags like timeout and headers, and commands such as 'get' and 'post' with their respective arguments. ```bash $ go run ./examples/curl/curl.go --help usage: curl [] [ ...] An example implementation of curl. Flags: --help Show help. -t, --timeout=5s Set connection timeout. -H, --headers=HEADER=VALUE Add HTTP headers to the request. Commands: help [...] get [] url file post [] ``` -------------------------------- ### Install Kingpin v2 Source: https://github.com/sideshow/apns2/blob/master/vendor/github.com/alecthomas/kingpin/README.md Installs the current stable version of the Kingpin library using the go get command. ```sh $ go get gopkg.in/alecthomas/kingpin.v2 ``` -------------------------------- ### Install Kingpin v1 Source: https://github.com/sideshow/apns2/blob/master/vendor/github.com/alecthomas/kingpin/README.md Installs the older, deprecated version of the Kingpin library using the go get command. ```sh $ go get gopkg.in/alecthomas/kingpin.v1 ``` -------------------------------- ### Default Help Output Example Source: https://github.com/sideshow/apns2/blob/master/vendor/github.com/alecthomas/kingpin/README.md An example of the default help message generated by Kingpin for a sample CLI application. ```bash $ go run ./examples/curl/curl.go --help usage: curl [] [ ...] An example implementation of curl. Flags: --help Show help. -t, --timeout=5s Set connection timeout. -H, --headers=HEADER=VALUE Add HTTP headers to the request. Commands: help [...] Show help. get url Retrieve a URL. get file Retrieve a file. post [] POST a resource. ``` -------------------------------- ### APNS/2 Command Line Tool Usage Source: https://github.com/sideshow/apns2/blob/master/README.md Provides instructions and examples for using the APNS/2 command-line interface to send notifications. It details the installation process, required flags like certificate path and topic, and the expected input format for device tokens and payloads. ```bash apns2 --help usage: apns2 --certificate-path=CERTIFICATE-PATH --topic=TOPIC [] Listens to STDIN to send notifications and writes APNS response code and reason to STDOUT. The expected format is: Example: aff0c63d9eaa63ad161bafee732d5bc2c31f66d552054718ff19ce314371e5d0 {"aps": {"alert": "hi"}} Flags: --help Show context-sensitive help (also try --help-long and --help-man). -c, --certificate-path=CERTIFICATE-PATH Path to certificate file. -t, --topic=TOPIC The topic of the remote notification, which is typically the bundle ID for your app -m, --mode="production" APNS server to send notifications to. `production` or `development`. Defaults to `production` --version Show application version. ``` -------------------------------- ### Install jwt-go Package Source: https://github.com/sideshow/apns2/blob/master/vendor/github.com/golang-jwt/jwt/v5/README.md Installs the latest version of the jwt-go package using the go get command. This is the first step to include the library in your Go project. ```sh go get -u github.com/golang-jwt/jwt/v5 ``` -------------------------------- ### APNS/2 High Throughput Example (Go) Source: https://github.com/sideshow/apns2/wiki/APNS-HTTP-2-Push-Speed Demonstrates how to achieve high throughput with APNS/2 by utilizing multiple client instances, one per CPU core, and a channel for managing notifications. This example highlights efficient client management and concurrent push operations. ```go cores := runtime.NumCPU() runtime.GOMAXPROCS(cores) clients = make(chan *apns2.Client, 50) cert, err := certificate.FromP12File("./Certificates.p12", "") if err != nil { log.Fatal("cert error:", err) } for i := 0; i < runtime.NumCPU(); i++ { // create an apns2 Client per CPU core clients <- apns2.NewClient(cert).Production() } var wg sync.WaitGroup for i := 0; i < int(100000); i++ { client := <-clients // grab a client from the pool clients <- client // add the client back to the pool wg.Add(1) go func() { // grab a notification from your channel filled with notifications notification := <-notifications res, err := client.Push(notification) // handle response or error wg.Done() }() } wg.Wait() ``` -------------------------------- ### Simple Kingpin Example Source: https://github.com/sideshow/apns2/blob/master/vendor/github.com/alecthomas/kingpin/README.md A basic example demonstrating how to define and parse a boolean flag and a required string argument using Kingpin. It shows the core `Flag`, `Arg`, and `Parse` functions. ```go var ( verbose = kingpin.Flag("verbose", "Verbose mode.").Short('v').Bool() name = kingpin.Arg("name", "Name of user.").Required().String() ) func main() { kingpin.Parse() fmt.Printf("%v, %s\n", *verbose, *name) } ``` -------------------------------- ### Installing Shell Completion via bash_profile Source: https://github.com/sideshow/apns2/blob/master/vendor/github.com/alecthomas/kingpin/README.md Instructions for users to enable shell completion by sourcing the generated script in their bash_profile or equivalent. ```bash # For Bash eval "$(your-cli-tool --completion-script-bash)" # For ZSH eval "$(your-cli-tool --completion-script-zsh)" ``` -------------------------------- ### JWT Library Migration Guide (v4.0.0) Source: https://github.com/sideshow/apns2/blob/master/vendor/github.com/golang-jwt/jwt/v5/MIGRATION_GUIDE.md Provides instructions for migrating to version 4.0.0 of the JWT library. It details the change in import path and suggests methods for updating existing code, including manual replacement and using tools like sed or gofmt. ```APIDOC Import Path Change: Starting from v4.0.0, the import path is: "github.com/golang-jwt/jwt/v4" Migration Steps: 1. Replace existing import paths: - "github.com/dgrijalva/jwt-go" - "github.com/golang-jwt/jwt" with "github.com/golang-jwt/jwt/v4". 2. Use tools like `sed` or `gofmt` for automated replacement. 3. Update dependencies: go get github.com/golang-jwt/jwt/v4 go mod tidy Compatibility: - v4.0.0 is backwards compatible with existing v3.x.y tags. - It is also compatible with "github.com/dgrijalva/jwt-go". ``` -------------------------------- ### Simple Kingpin Application Source: https://github.com/sideshow/apns2/blob/master/vendor/github.com/alecthomas/kingpin/README.md Demonstrates a basic Kingpin application for pinging an IP address. It includes flags for debug mode and timeout, and arguments for the IP address and count. The example shows how to define flags and arguments and parse them. ```go package main import ( "fmt" "gopkg.in/alecthomas/kingpin.v2" ) var ( debug = kingpin.Flag("debug", "Enable debug mode.").Bool() timeout = kingpin.Flag("timeout", "Timeout waiting for ping.").Default("5s").OverrideDefaultFromEnvar("PING_TIMEOUT").Short('t').Duration() ip = kingpin.Arg("ip", "IP address to ping.").Required().IP() count = kingpin.Arg("count", "Number of packets to send").Int() ) func main() { kingpin.Version("0.0.1") kingpin.Parse() fmt.Printf("Would ping: %s with timeout %s and count %d\n", *ip, *timeout, *count) } ``` ```bash $ ping --help usage: ping [] [] Flags: --debug Enable debug mode. --help Show help. -t, --timeout=5s Timeout waiting for ping. Args: IP address to ping. [] Number of packets to send $ ping 1.2.3.4 5 Would ping: 1.2.3.4 with timeout 5s and count 5 ``` -------------------------------- ### jwt-go v5 Import Path Source: https://github.com/sideshow/apns2/blob/master/vendor/github.com/golang-jwt/jwt/v5/MIGRATION_GUIDE.md Starting from v5.0.0, the import path for the jwt-go library has changed to include the version number. ```go import "github.com/golang-jwt/jwt/v5" ``` -------------------------------- ### JWT Building and Signing Example (HMAC) Source: https://github.com/sideshow/apns2/blob/master/vendor/github.com/golang-jwt/jwt/v5/README.md Illustrates how to build and sign a JWT using the HMAC method. This is useful for creating new tokens for authentication or data exchange. ```go // Example of building and signing a token // See: https://pkg.go.dev/github.com/golang-jwt/jwt/v5#example-New-Hmac ``` -------------------------------- ### JWT Parsing and Validation Example (HMAC) Source: https://github.com/sideshow/apns2/blob/master/vendor/github.com/golang-jwt/jwt/v5/README.md Provides a simple example of how to parse and validate a JWT using the HMAC signing method. This is a common use case for verifying token authenticity. ```go // Example of parsing and validating a token // See: https://pkg.go.dev/github.com/golang-jwt/jwt/v5#example-Parse-Hmac ``` -------------------------------- ### jwt-go v5 Parser Options Source: https://github.com/sideshow/apns2/blob/master/vendor/github.com/golang-jwt/jwt/v5/MIGRATION_GUIDE.md Details the new ParserOption functions available in jwt-go v5 for fine-tuning token validation, including leeway, audience, issuer, and strict decoding. ```APIDOC ParserOption Functions: - WithLeeway(leeway time.Duration) - Description: Specifies the leeway allowed when validating time-based claims (exp, nbf). - Parameters: - leeway: The duration of leeway to apply. - WithIssuedAt() - Description: Enables checking of the 'iat' claim. Disabled by default as per RFC. - WithAudience(audience string) - Description: Checks for the expected 'aud' claim. - Parameters: - audience: The expected audience string. - WithSubject(subject string) - Description: Checks for the expected 'sub' claim. - Parameters: - subject: The expected subject string. - WithIssuer(issuer string) - Description: Checks for the expected 'iss' claim. - Parameters: - issuer: The expected issuer string. - WithStrictDecoding() - Description: Enables strict base64 encoding checking. Disabled by default. - WithPaddingAllowed() - Description: Allows parsing of base64 strings with padding, even if not strictly compliant with the standard. Disabled by default. ``` -------------------------------- ### Import jwt-go in Go Code Source: https://github.com/sideshow/apns2/blob/master/vendor/github.com/golang-jwt/jwt/v5/README.md Demonstrates how to import the jwt-go package into your Go source files after installation. This allows you to use the library's functionalities. ```go import "github.com/golang-jwt/jwt/v5" ``` -------------------------------- ### Complex Kingpin Chat Application Source: https://github.com/sideshow/apns2/blob/master/vendor/github.com/alecthomas/kingpin/README.md Illustrates a more complex Kingpin application for a command-line chat client. It features global flags, sub-commands (register, post), and per-subcommand flags and arguments. This example showcases nested commands and argument parsing. ```go package main import ( "os" "strings" "gopkg.in/alecthomas/kingpin.v2" ) var ( app = kingpin.New("chat", "A command-line chat application.") debug = app.Flag("debug", "Enable debug mode.").Bool() serverIP = app.Flag("server", "Server address.").Default("127.0.0.1").IP() register = app.Command("register", "Register a new user.") registerNick = register.Arg("nick", "Nickname for user.").Required().String() registerName = register.Arg("name", "Name of user.").Required().String() post = app.Command("post", "Post a message to a channel.") postImage = post.Flag("image", "Image to post.").File() postChannel = post.Arg("channel", "Channel to post to.").Required().String() postText = post.Arg("text", "Text to post.").Strings() ) func main() { switch kingpin.MustParse(app.Parse(os.Args[1:])) { // Register user case register.FullCommand(): println(*registerNick) // Post message case post.FullCommand(): if *postImage != nil { } text := strings.Join(*postText, " ") println("Post:", text) } } ``` ```bash $ chat --help usage: chat [] [] [ ...] A command-line chat application. Flags: --help Show help. --debug Enable debug mode. --server=127.0.0.1 Server address. Commands: help [] Show help for a command. register Register a new user. post [] [] Post a message to a channel. $ chat help post usage: chat [] post [] [] Post a message to a channel. Flags: --image=IMAGE Image to post. Args: Channel to post to. [] Text to post. $ chat post --image=~/Downloads/owls.jpg pics ... ``` -------------------------------- ### Newline Elision Example Source: https://github.com/sideshow/apns2/blob/master/vendor/github.com/alecthomas/template/README.md Demonstrates the newline elision feature in the modified text/template package. A backslash following a closing delimiter removes subsequent newlines. ```go package main import ( "bytes" "log" "text/template" ) func main() { const tmplString = `{{if true}}\nhello\n{{end}}\n` ttmpl, err := template.New("elision").Parse(tmplString) if err != nil { log.Fatal(err) } var buf bytes.Buffer if err := tmpl.Execute(&buf, nil); err != nil { log.Fatal(err) } // The output will be "hello\n" due to newline elision. // fmt.Println(buf.String()) } ``` -------------------------------- ### Independent Validator Usage Source: https://github.com/sideshow/apns2/blob/master/vendor/github.com/golang-jwt/jwt/v5/MIGRATION_GUIDE.md Demonstrates how to use the jwt.NewValidator function to validate claims independently of the parsing process, with options like WithLeeway. ```go var v = jwt.NewValidator(jwt.WithLeeway(5*time.Second)) v.Validate(myClaims) ``` -------------------------------- ### Claims Interface Definition Source: https://github.com/sideshow/apns2/blob/master/vendor/github.com/golang-jwt/jwt/v5/MIGRATION_GUIDE.md The updated Claims interface in jwt-go v5 focuses on getter functions for specific claim types, decoupling validation logic from storage. ```go type Claims interface { GetExpirationTime() (*NumericDate, error) GetIssuedAt() (*NumericDate, error) GetNotBefore() (*NumericDate, error) GetIssuer() (string, error) GetSubject() (string, error) GetAudience() (ClaimStrings, error) } ``` -------------------------------- ### Token Struct Definition Source: https://github.com/sideshow/apns2/blob/master/vendor/github.com/golang-jwt/jwt/v5/MIGRATION_GUIDE.md Defines the structure of a JWT Token, including its raw string representation, signing method, decoded header and claims, decoded signature, and a validity flag. The Signature field is now a byte slice for consistency. ```go type Token struct { Raw string // Raw contains the raw token Method SigningMethod // Method is the signing method used or to be used Header map[string]interface{} // Header is the first segment of the token in decoded form Claims Claims // Claims is the second segment of the token in decoded form Signature []byte // Signature is the third segment of the token in decoded form Valid bool // Valid specifies if the token is valid } ``` -------------------------------- ### Bash/ZSH Shell Completion Generation Source: https://github.com/sideshow/apns2/blob/master/vendor/github.com/alecthomas/kingpin/README.md Generates shell completion scripts for Bash and ZSH. These scripts enable users to get command and flag suggestions directly in their terminal. ```bash # Generate bash completion script ./yourtool --completion-script-bash # Generate zsh completion script ./yourtool --completion-script-zsh ``` -------------------------------- ### Providing Static Hint Options for Flags Source: https://github.com/sideshow/apns2/blob/master/vendor/github.com/alecthomas/kingpin/README.md Demonstrates how to provide a predefined list of options for a flag, allowing users to choose from these suggestions while also permitting custom input. ```go app := kingpin.New("completion", "My application with bash completion.") app.Flag("port", "Provide a port to connect to"). Required(). HintOptions("80", "443", "8080"). IntVar(&c.port) ``` -------------------------------- ### Custom Help Templates Source: https://github.com/sideshow/apns2/blob/master/vendor/github.com/alecthomas/kingpin/README.md Explains how to use custom help templates with Kingpin, including built-in templates like Compact and ManPage. ```go # Set a custom usage template app.UsageTemplate(kingpin.CompactUsageTemplate) # Or use a ManPage template app.UsageTemplate(kingpin.ManPageTemplate) ``` -------------------------------- ### Providing Dynamic Hint Options for Flags Source: https://github.com/sideshow/apns2/blob/master/vendor/github.com/alecthomas/kingpin/README.md Shows how to dynamically generate completion options for a flag by reading from external sources like files or databases. ```go func listHosts() []string { // Provide a dynamic list of hosts from a hosts file or otherwise // for bash completion. In this example we simply return static slice. // You could use this functionality to reach into a hosts file to provide // completion for a list of known hosts. return []string{"sshhost.example", "webhost.example", "ftphost.example"} } app := kingpin.New("completion", "My application with bash completion.") app.Flag("flag-1", "").HintAction(listHosts).String() ``` -------------------------------- ### Kingpin v1.0.0 Streamlining Source: https://github.com/sideshow/apns2/blob/master/vendor/github.com/alecthomas/kingpin/README.md Details the streamlining changes in Kingpin v1.0.0, including renaming MetaVar to PlaceHolder and removing MetaVarFromDefault, with Kingpin now using heuristics for help text. ```APIDOC Renamed MetaVar to PlaceHolder. Removed MetaVarFromDefault. Kingpin uses heuristics for PlaceHolder in help text. ``` -------------------------------- ### APNS Payload Builder Source: https://github.com/sideshow/apns2/blob/master/README.md Demonstrates using the payload builder package to construct APNs payloads programmatically. Shows how to set alert messages, badges, and custom key-value pairs within the payload. ```go // {"aps":{"alert":"hello","badge":1},"key":"val"} payload := payload.NewPayload().Alert("hello").Badge(1).Custom("key", "val") notification.Payload = payload client.Push(notification) ``` -------------------------------- ### Kingpin v2.1.0 Features Source: https://github.com/sideshow/apns2/blob/master/vendor/github.com/alecthomas/kingpin/README.md Highlights new features introduced in Kingpin v2.1.0, including default commands, customizable help flags, enhanced action callbacks, and improved flag handling. ```APIDOC command.Default(): Specify a default command for unmatched inputs. Exposed HelpFlag and VersionFlag for customization. Action() and PreAction() support multiple callbacks. kingpin.SeparateOptionalFlagsUsageTemplate for usage formatting. --help-long and --help-man flags. app.Interspersed(false) to disable interspersed flags. Support for all simple builtin types and slice variants. app.Writer(os.Writer) to set default output writer. Dropped os.Writer prefix from printf-like functions. ``` -------------------------------- ### Using Context with Timeouts for Push Notifications Source: https://github.com/sideshow/apns2/blob/master/README.md Shows how to integrate Go's `context` package to manage timeouts and cancellations for push notification requests. This allows for finer control over individual push operations or cancellation when a parent process is terminated. ```go ctx, cancel = context.WithTimeout(context.Background(), 10 * time.Second) res, err := client.PushWithContext(ctx, notification) defer cancel() ``` -------------------------------- ### Support for Go 1.15 and 1.16 Source: https://github.com/sideshow/apns2/blob/master/vendor/github.com/golang-jwt/jwt/v5/VERSION_HISTORY.md Starting from version 3.2.2, the library adopts a policy to support the two most recent versions of Go. At the time of release, this includes Go 1.15 and Go 1.16. ```go package main import ( "fmt" "runtime" ) func main() { fmt.Printf("Running on Go version: %s\n", runtime.Version()) // The library is compatible with Go 1.15 and 1.16. } ``` -------------------------------- ### Kingpin v1.0.0 Features Source: https://github.com/sideshow/apns2/blob/master/vendor/github.com/alecthomas/kingpin/README.md Describes the core features of Kingpin v1.0.0, including support for cumulative positional arguments, error handling for invalid defaults, and use of gokpg.in for versioning. ```APIDOC Support cumulative positional arguments. Return error rather than panic for fatal errors not caught by type system (e.g., invalid default value). Use gokpg.in. ``` -------------------------------- ### API Documentation for gopkg.in/yaml.v3 Source: https://github.com/sideshow/apns2/blob/master/vendor/gopkg.in/yaml.v3/README.md Provides access to the official API documentation for the `gopkg.in/yaml.v3` package. The documentation covers the package's functionality for encoding and decoding YAML data in Go. ```APIDOC gopkg.in/yaml.v3: Import Path: gopkg.in/yaml.v3 Description: Enables Go programs to comfortably encode and decode YAML values. Compatibility: - Supports most of YAML 1.2. - Preserves some behavior from YAML 1.1 for backwards compatibility. - YAML 1.1 bools (_yes/no, on/off_) supported when decoding into typed bool; otherwise treated as strings. - Octals encode/decode as _0777_ (YAML 1.1 format) for compatibility, but _0o777_ (YAML 1.2) is also supported. - Does not support base-60 floats. Installation: go get gopkg.in/yaml.v3 API Stability: API for v3 remains stable as described in gopkg.in. License: MIT and Apache License 2.0. Key Functions: Unmarshal(in []byte, out interface{}) error: Description: Decodes YAML into the value pointed to by out. Parameters: in: The YAML data to decode. out: A pointer to the Go value to decode into. Returns: An error if decoding fails. Marshal(in interface{}) ([]byte, error): Description: Encodes the Go value into YAML. Parameters: in: The Go value to encode. Returns: A byte slice containing the YAML data. An error if encoding fails. ``` -------------------------------- ### Kingpin v1.1.0 Features Source: https://github.com/sideshow/apns2/blob/master/vendor/github.com/alecthomas/kingpin/README.md Lists improvements in Kingpin v1.1.0, including bug fixes, consistent error handling (avoiding panics), OpenFile value type for file control, and significantly improved usage formatting. ```APIDOC Bug fixes. Always return an error (rather than panicing) when misconfigured. OpenFile(flag, perm) value type for finer control over opening files. Significantly improved usage formatting. ``` -------------------------------- ### Custom Claims Validation with ClaimsValidator Interface Source: https://github.com/sideshow/apns2/blob/master/vendor/github.com/golang-jwt/jwt/v5/MIGRATION_GUIDE.md Demonstrates how to define custom claims that implement the ClaimsValidator interface for application-specific validation. This approach appends custom validation errors to standard validation, preventing accidental disabling of security checks. ```go import ( "errors" "github.com/golang-jwt/jwt/v4" ) // MyCustomClaims includes all registered claims, plus Foo. type MyCustomClaims struct { Foo string `json:"foo"` jwt.RegisteredClaims } // Validate can be used to execute additional application-specific claims // validation. func (m MyCustomClaims) Validate() error { if m.Foo != "bar" { return errors.New("must be foobar") } return nil } ``` -------------------------------- ### Send Push Notification with JWT Token Source: https://github.com/sideshow/apns2/blob/master/README.md Illustrates sending a push notification using JWT Provider Authentication Tokens. It shows how to load a .p8 signing key, configure the token with KeyID and TeamID, and create a client for sending notifications. ```go authKey, err := token.AuthKeyFromFile("../AuthKey_XXX.p8") if err != nil { log.Fatal("token error:", err) } token := &token.Token{ AuthKey: authKey, // KeyID from developer account (Certificates, Identifiers & Profiles -> Keys) KeyID: "ABC123DEFG", // TeamID from developer account (View Account -> Membership) TeamID: "DEF123GHIJ", } ... client := apns2.NewTokenClient(token) res, err := client.Push(notification) ``` -------------------------------- ### Kingpin API: Error and Usage Information Source: https://github.com/sideshow/apns2/blob/master/vendor/github.com/alecthomas/kingpin/README.md Details the Kingpin API functions for displaying errors and usage information. It covers functions like `Errorf`, `Fatalf`, `FatalUsage`, and `FatalIfError`, explaining their purpose and how they contribute to a consistent user experience. ```APIDOC Kingpin Error and Usage Functions: Error messages format: : error: Functions on `Application` (and equivalent global functions): Function | Purpose ---------|-------------- `Errorf(format, args)` | Display a printf formatted error to the user. `Fatalf(format, args)` | Display error and call termination handler. `FatalUsage(format, args)` | Display error and contextual usage information. `FatalUsageContext(context, format, args)` | Display error and contextual usage from a `ParseContext`. `FatalIfError(err, format, args)` | Conditionally display prefixed error and call termination handler. ``` -------------------------------- ### Kingpin v1.3.4 Features Source: https://github.com/sideshow/apns2/blob/master/vendor/github.com/alecthomas/kingpin/README.md Outlines enhancements in Kingpin v1.3.4, such as support for '--' to separate flags from arguments, loading flags from files, post-validation hooks, and improved help formatting. ```APIDOC Support "--" for separating flags from positional arguments. Support loading flags from files (ParseWithFileExpansion()). Use @FILE as an argument. Add post-app and post-cmd validation hooks. Improvements to help usage and formatting. Support arbitrarily nested sub-commands. ``` -------------------------------- ### Kingpin v2.0.0 Features Source: https://github.com/sideshow/apns2/blob/master/vendor/github.com/alecthomas/kingpin/README.md Details the major changes in Kingpin v2.0.0, including full support for interspersed flags and arguments, refactored parsing, customizable termination and output streams, and templated help messages. ```APIDOC Fully supports interspersed flags, commands, and arguments. Flags can appear anywhere after their definition. Application.Parse() terminates if commands are present but not parsed. Dispatch() renamed to Action(). Actions dispatched after all values are populated. Override termination function (defaults to os.Exit). Override output stream (defaults to os.Stderr). Templatised usage help with default and compact templates. Error/usage functions made more consistent. Support argument expansion from files (@) by default. Public data model available via .Model(). Parser refactored. Parsing and execution split into distinct stages. Use go generate for repeated flags. Support combined short-flag+argument: -fARG. ``` -------------------------------- ### Send Push Notification with Certificate Source: https://github.com/sideshow/apns2/blob/master/README.md Demonstrates how to send a push notification using a .p12 certificate. It covers loading the certificate, creating a notification object with device token, topic, and payload, and sending it via a production client. ```go package main import ( "log" "fmt" "github.com/sideshow/apns2" "github.com/sideshow/apns2/certificate" ) func main() { cert, err := certificate.FromP12File("../cert.p12", "") if err != nil { log.Fatal("Cert Error:", err) } notification := &apns2.Notification{} notification.DeviceToken = "11aa01229f15f0f0c52029d8cf8cd0aeaf2365fe4cebc4af26cd6d76b7919ef7" notification.Topic = "com.sideshow.Apns2" notification.Payload = []byte(`{"aps":{"alert":"Hello!"}}`) // If you want to test push notifications for builds running directly from XCode (Development), use // client := apns2.NewClient(cert).Development() // For apps published to the app store or installed as an ad-hoc distribution use Production() client := apns2.NewClient(cert).Production() res, err := client.Push(notification) if err != nil { log.Fatal("Error:", err) } fmt.Printf("%v %v %v\n", res.StatusCode, res.ApnsID, res.Reason) } ``` -------------------------------- ### SigningMethod Interface and Registration Source: https://github.com/sideshow/apns2/blob/master/vendor/github.com/golang-jwt/jwt/v5/README.md This snippet describes how to extend the library by implementing the `SigningMethod` interface and registering custom factory methods using `RegisterSigningMethod` or providing a `jwt.Keyfunc`. This is useful for integrating with third-party signature providers or custom standards. ```go package jwt // SigningMethod is the interface that must be implemented by all signing methods. type SigningMethod interface { // Alg returns the algorithm name. Alg() string // Verify verifies the signature. Verify(signingString, signature []byte, key interface{}) error } // RegisterSigningMethod registers a signing method. func RegisterSigningMethod(method SigningMethod) { // ... implementation details ... } // Keyfunc is a function that returns a key for the given token. type Keyfunc func(*Token) (interface{}, error) ``` -------------------------------- ### Golang Text Unicode Dependencies Source: https://github.com/sideshow/apns2/blob/master/vendor/modules.txt Imports packages for text processing and Unicode normalization from golang.org/x/text, compatible with Go 1.18. This includes bidirule, transform, bidi, and norm for text manipulation. ```go import ( "golang.org/x/text/secure/bidirule" "golang.org/x/text/transform" "golang.org/x/text/unicode/bidi" "golang.org/x/text/unicode/norm" ) ``` -------------------------------- ### Testify Assert Dependency Source: https://github.com/sideshow/apns2/blob/master/vendor/modules.txt Imports the 'assert' package from github.com/stretchr/testify, compatible with Go 1.17. This is a popular assertion library for Go testing. It also imports the 'yaml' subpackage. ```go import ( "github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert/yaml" ) ``` -------------------------------- ### Kingpin v1.2.0 Features Source: https://github.com/sideshow/apns2/blob/master/vendor/github.com/alecthomas/kingpin/README.md Details features added in Kingpin v1.2.0, including passing values to Strings() for final arguments, allowing '--help' with commands, supporting hidden flags, and introducing Enum() for restricted choices. ```APIDOC Pass any value through to Strings() when final argument. Allow --help to be used with commands. Support Hidden() flags. Parser for units.Base2Bytes type (e.g., --ram=512MB). Add Enum() value for restricted choices (e.g., Flag(...).Enum("debug", "info")). ``` -------------------------------- ### Customizing Help Flag Source: https://github.com/sideshow/apns2/blob/master/vendor/github.com/alecthomas/kingpin/README.md Configures the short alias for the help flag to 'h'. ```go kingpin.CommandLine.HelpFlag.Short('h') ``` -------------------------------- ### Kingpin API: Sub-commands Source: https://github.com/sideshow/apns2/blob/master/vendor/github.com/alecthomas/kingpin/README.md Explains how Kingpin supports nested sub-commands, allowing for separate flag and positional argument definitions for each sub-command. It highlights that positional arguments must follow sub-commands. ```APIDOC Kingpin Sub-commands: Supports nested sub-commands with distinct flags and arguments per sub-command. Positional arguments must appear after sub-commands. Example: ```go var ( deleteCommand = kingpin.Command("delete", "Delete an object.") deleteUserCommand = deleteCommand.Command("user", "Delete a user.") deleteUserUIDFlag = deleteUserCommand.Flag("uid", "Delete user by UID rather than username.") deleteUserUsername = deleteUserCommand.Arg("username", "Username to delete.") deletePostCommand = deleteCommand.Command("post", "Delete a post.") ) func main() { switch kingpin.Parse() { case "delete user": case "delete post": } } ``` ``` -------------------------------- ### Kingpin API Changes (v1 to v2) Source: https://github.com/sideshow/apns2/blob/master/vendor/github.com/alecthomas/kingpin/README.md Details significant API changes between Kingpin v1 and v2, including removed functions, renamed functions, and newly added functionalities for error handling and parsing context. ```APIDOC Kingpin API Changes (v1 to v2): - `ParseWithFileExpansion()`: Removed. New parser directly supports `@` expansion. - `FatalUsage()` and `FatalUsageContext()`: Added for displaying an error and usage, then terminating. - `Dispatch()`: Renamed to `Action()`. - `ParseContext()`: Added for parsing command line into intermediate context without execution. - `Terminate()`: Added to override the termination function. - `UsageForContextWithTemplate()`: Added for printing usage via a custom template. - `UsageTemplate()`: Added for overriding the default template. Includes `DefaultUsageTemplate` and `CompactUsageTemplate`. ``` -------------------------------- ### Golang Net HTTP Dependencies Source: https://github.com/sideshow/apns2/blob/master/vendor/modules.txt Imports packages related to HTTP from golang.org/x/net, compatible with Go 1.18. This includes httpguts, http2, hpack, and idna for network and HTTP protocol handling. ```go import ( "golang.org/x/net/http/httpguts" "golang.org/x/net/http2" "golang.org/x/net/http2/hpack" "golang.org/x/net/idna" ) ``` -------------------------------- ### Golang Crypto PKCS12 Dependency Source: https://github.com/sideshow/apns2/blob/master/vendor/modules.txt Imports the 'pkcs12' package from golang.org/x/crypto, compatible with Go 1.20. This package handles PKCS#12 encoded data, often used for certificates and private keys. ```go import ( "golang.org/x/crypto/pkcs12" "golang.org/x/crypto/pkcs12/internal/rc2" ) ``` -------------------------------- ### Template Package Dependency Source: https://github.com/sideshow/apns2/blob/master/vendor/modules.txt Imports the 'template' package from github.com/alecthomas/template, including its 'parse' subpackage. This suggests usage of a templating engine. ```go import ( "github.com/alecthomas/template" "github.com/alecthomas/template/parse" ) ``` -------------------------------- ### Units Package Dependency Source: https://github.com/sideshow/apns2/blob/master/vendor/modules.txt Imports the 'units' package from github.com/alecthomas/units, compatible with Go 1.15. This package likely handles unit conversions or definitions. ```go import "github.com/alecthomas/units" ``` -------------------------------- ### Go-Difflib Dependency Source: https://github.com/sideshow/apns2/blob/master/vendor/modules.txt Imports the 'difflib' package from github.com/pmezard/go-difflib. This package is used for computing differences between sequences, often for text comparison. ```go import "github.com/pmezard/go-difflib/difflib" ``` -------------------------------- ### APNS Notification Structure Source: https://github.com/sideshow/apns2/blob/master/README.md Defines the minimum requirements for an APNS notification, including DeviceToken, Topic, and Payload. Also shows how to set optional fields like ApnsID, Expiration, and Priority. ```go notification := &apns2.Notification{ DeviceToken: "11aa01229f15f0f0c52029d8cf8cd0aeaf2365fe4cebc4af26cd6d76b7919ef7", Topic: "com.sideshow.Apns2", Payload: []byte(`{"aps":{"alert":"Hello!"}}`), } notification.ApnsID = "40636A2C-C093-493E-936A-2A4333C06DEA" notification.Expiration = time.Now() notification.Priority = apns2.PriorityLow ``` -------------------------------- ### Handling Push Notification Responses and Errors Source: https://github.com/sideshow/apns2/blob/master/README.md Demonstrates how to check the success of a push notification and access details like the APNS ID or reason for failure. It involves checking the error returned by the `Push` method and then inspecting the `Response` struct. ```go res, err := client.Push(notification) if err != nil { log.Println("There was an error", err) return } if res.Sent() { log.Println("Sent:", res.ApnsID) } else { fmt.Printf("Not Sent: %v %v %v\n", res.StatusCode, res.ApnsID, res.Reason) } ``` -------------------------------- ### JWT Command Line Tool Improvements Source: https://github.com/sideshow/apns2/blob/master/vendor/github.com/golang-jwt/jwt/v5/VERSION_HISTORY.md The `jwt` command-line tool has received improvements, including the addition of a `-show` option to display decoded tokens without verification. This enhances the utility of the CLI for inspecting JWTs. ```bash # Example of using the -show flag: jwt --show your.jwt.token.string ``` -------------------------------- ### Custom HTTP Header Parser Source: https://github.com/sideshow/apns2/blob/master/vendor/github.com/alecthomas/kingpin/README.md Defines a custom parser for accumulating HTTP header values, conforming to Go's flag.Value interface. It splits input strings into header names and values and adds them to an http.Header. ```go type HTTPHeaderValue http.Header func (h *HTTPHeaderValue) Set(value string) error { parts := strings.SplitN(value, ":", 2) if len(parts) != 2 { return fmt.Errorf("expected HEADER:VALUE got '%s'", value) } (*http.Header)(h).Add(parts[0], parts[1]) return nil } func (h *HTTPHeaderValue) String() string { return "" } ``` ```go func HTTPHeader(s Settings) (target *http.Header) { target = &http.Header{} s.SetValue((*HTTPHeaderValue)(target)) return } ``` ```go headers := HTTPHeader(kingpin.Flag("header", "Add a HTTP header to the request.").Short('H')) ``` -------------------------------- ### Kingpin Dependency Source: https://github.com/sideshow/apns2/blob/master/vendor/modules.txt Imports the 'kingpin' package from github.com/alecthomas/kingpin. This package is likely used for command-line argument parsing. ```go import "github.com/alecthomas/kingpin" ``` -------------------------------- ### Go YAML v3 Dependency Source: https://github.com/sideshow/apns2/blob/master/vendor/modules.txt Imports the 'yaml.v3' package from gopkg.in/yaml.v3. This package is used for encoding and decoding YAML data. ```go import "gopkg.in/yaml.v3" ``` -------------------------------- ### jwt-go Compliance Notes Source: https://github.com/sideshow/apns2/blob/master/vendor/github.com/golang-jwt/jwt/v5/README.md Details compliance information regarding RFC 7519, specifically highlighting the handling of `alg=none` tokens. It mentions that `jwt.UnsafeAllowNoneSignatureType` must be provided to accept such tokens, enhancing security. ```APIDOC Compliance Notes: - Complies with RFC 7519 (May 2015). - Unsecured JWTs (`alg=none`) are only accepted if `jwt.UnsafeAllowNoneSignatureType` is provided. - This is a security measure to prevent accidental use of unsecured tokens. ``` -------------------------------- ### Custom IP Address List Parser Source: https://github.com/sideshow/apns2/blob/master/vendor/github.com/alecthomas/kingpin/README.md Implements a custom parser for consuming multiple IP addresses as positional arguments. It validates each argument as an IP address and appends it to a slice, allowing for repeatable arguments. ```go type ipList []net.IP func (i *ipList) Set(value string) error { if ip := net.ParseIP(value); ip == nil { return fmt.Errorf("'%s' is not an IP address", value) } else { *i = append(*i, ip) return nil } } func (i *ipList) String() string { return "" } func (i *ipList) IsCumulative() bool { return true } ``` ```go func IPList(s Settings) (target *[]net.IP) { target = new([]net.IP) s.SetValue((*ipList)(target)) return } ``` ```go ips := IPList(kingpin.Arg("ips", "IP addresses to ping.")) ```