/LinksKit

SwiftUI convenience view to show common links in apps settings/help menu.

Primary LanguageSwiftMIT LicenseMIT

LinksKit Logo

LinksKit

Every app on the App Store must provide essential links like a privacy policy and, if applicable, terms of use (for in-app purchases) to comply with Apple's guidelines. Many apps handle this by adding a "Links" section in their settings, including additional helpful links like app ratings, FAQs, and support options.

That's where LinksKit comes in: it offers a simple, ready-to-use solution to handle all these common links, saving you a ton of time. Whether it's legal, help, or app promotion links, LinksKit covers it. And for macOS, it even supports adding these links right into the Help menu!

iOS Example macOS Example

Usage

Getting started with LinksKit is easy. After adding the package to your project, simply import LinksKit and place a LinksView() inside a List or Form view. But before doing that, you'll need to configure the links you want to include.

Minimal Setup

For a basic setup, which includes legal links (like privacy policy and terms of use), app rating, and a contact email, you can configure LinksKit like this:

import SwiftUI

@main
struct YourApp: App {
   init() {
      // other setup code
      
      LinksKit.configure(
         providerToken: "123456",
         linkSections: [
            .helpLinks(appID: "123456789", supportEmail: "support@example.com"),
            .legalLinks(privacyURL: URL(string: "https://example.com")!)
         ]
      )
   }
   
   var body: some Scene {
      // your UI code
   }
}

Tip: Your providerToken already exists and is the same for all your apps. Unfortunately, Apple does not have an easier way to look it up than within the "Campaign" creation form on App Store Connect under Analytics > Acquisition > Campaigns. You don't actually need to press 'Create', just enter some text in the form and you'll see the pt parameter in the Campaign Link preview. Campaign links are a great way to track where users are finding your app. Learn more about them here.

Note: LinksKit will automatically add Apple's terms of use link to .legalLinks for apps with in-app purchases. No need to configure it yourself – it just works! 🚀

Optional Extras

LinksKit goes beyond the basics, offering more customization to fit your needs. You can:

  • Add an FAQ link with faqURL passed to .helpLinks
  • Link to your app's or developer's social media with .socialMenus(appLinks:developerLinks:)
  • Promote your other apps or apps from friends using .appMenus(ownAppLinks:friendsAppLinks:)

Here’s a real-world example from my app TranslateKit, showcasing all of these features:

init() {
   // other setup code

   self.configureLinksKit()
}

func configureLinksKit() {
   // App Links
   let ownDeveloperApps = LinkSection(entries: [
      .link(.ownApp(id: "6502914189", name: "FreemiumKit: In-App Purchases", systemImage: "cart")),
      .link(.ownApp(id: "6480134993", name: "FreelanceKit: Time Tracking", systemImage: "timer")),
   ])

   let ownConsumerApps = LinkSection(entries: [
      .link(.ownApp(id: "6472669260", name: "CrossCraft: Crossword Tests", systemImage: "puzzlepiece")),
      .link(.ownApp(id: "6477829138", name: "FocusBeats: Study Music Timer", systemImage: "music.note")),
      .link(.ownApp(id: "6587583340", name: "Pleydia Organizer: Media Renamer", systemImage: "popcorn")),
   ])

   let ownVisionApps = LinkSection(entries: [
      .link(.ownApp(id: "6479207869", name: "Guided Guest Mode: Device Demo", systemImage: "questionmark.circle")),
      .link(.ownApp(id: "6478062053", name: "Posters: Discover Movies at Home", systemImage: "movieclapper")),
   ])

   let nicosApps = LinkSection(entries: [
      .link(.friendsApp(id: "1249686798", name: "NFC.cool Tools: Tag Reader", systemImage: "tag", providerToken: "106913804")),
      .link(.friendsApp(id: "6443995212", name: "Metadata for Fastlane Tools", systemImage: "hammer", providerToken: "106913804")),
   ])

   let jansApps = LinkSection(entries: [
      .link(.friendsApp(id: "6503256642", name: "App Exhibit: Your App Showcase", systemImage: "square.grid.3x3.fill.square")),
   ])

   // Configure LinksKit
   LinksKit.configure(
      providerToken: "549314",
      linkSections: [
         .helpLinks(appID: "6476773066", faqURL: Constants.faqURL, supportEmail: "translatekit@fline.dev"),
         .socialMenus(
            appLinks: .appSocialLinks(
               platforms: [.twitter, .mastodon(instance: "mastodon.social"), .threads],
               handle: "TranslateKit",
               handleOverrides: [.twitter: "TranslateKitApp"]
            ),
            developerLinks: .developerSocialLinks(
               platforms: [.twitter, .mastodon(instance: "iosdev.space"), .threads],
               handle: "Jeehut"
            )
         ),
         .appMenus(
            ownAppLinks: [ownDeveloperApps, ownConsumerApps, ownVisionApps],
            friendsAppLinks: [nicosApps, jansApps]
         ),
         .legalLinks(privacyURL: Constants.privacyPolicyURL)
      ]
   )
}

Tip: If you have appLinks but no developerLinks (or vice versa) when using the .socialMenus helper, you can just pass .appSocialLinks or .developerSocialLinks directly instead of passing .socialMenus.

Note: The .ownApp and .friendsApp helpers behave differently for a reason. LinksKit will automatically append your providerToken for your own apps, while you'll need to manually include a providerToken for your friends’ apps if you know it.

View Setup

To add LinksKit to your app’s settings screen, typically structured as a Form or List, just insert a LinksView() like so:

import SwiftUI

struct SettingsView: View {
   var body: some View {
      Form {
         // other sections/views like a paid status view or app settings
         
         #if !os(macOS)
         LinksView()
         #endif
      }
   }
}

And that’s it! If you’re not targeting macOS, the result should look like this:

For macOS apps, the best place for these links is often in the Help menu. You can easily add a LinksView() to the menu bar:

import SwiftUI

@main
struct YourApp: App {
   var body: some Scene {
      WindowGroup {
         // your UI code
      }
      #if os(macOS)
      .commands {
         CommandGroup(replacing: .help) {
            LinksView()
               .labelStyle(.titleAndIcon)
         }
      }
      #endif
   }
}

Here’s what that will look like on macOS:

Custom Links & Menus

If the default helpers like .helpLinks or .appMenus don't fit your exact use case, you can create fully custom LinkSection instances and add your own links. You can even nest them! For example, .appMenus is just a convenience for this equivalent LinkSection:

LinkSection(
   title: "App Links",
   entries: [
      .menu(LinkMenu(
         title: "More Apps from Developer",
         systemImage: "plus.square.on.square",
         linkSections: [ownDeveloperApps, ownConsumerApps, ownVisionApps]
      )),
      .menu(LinkMenu(
         title: "Apps from Friends",
         systemImage: "hand.thumbsup",
         linkSections: [nicosApps, jansApps]
      )),
   ]
)

The entries parameter accepts one of .menu(LinkMenu) or .link(Link) and you can nest as many levels as SwiftUI supports (.menu is rendered as a Menu view, .link as a Button).

Label Styles

LinksKit ships with additional Label styles which you can use to give your Form/List view a different look:

  • .labelStyle(.titleAndTrailingIcon): Renders exactly like the default .titleAndIcon style, but with the icon at the trailing end.
  • .labelStyle(.titleAndIconBadge(color:)): Resembles Apple's style in the Settings app by adding a colored background to the leading icons.
  • .labelStyle(.titleAndTrailingIconBadge(color:)): Same as the above, but the icon is placed at the trailing end.

Localization

All of LinksKit's built-in strings are already localized in around 40 languages, covering all the languages supported by iOS. No setup is needed. If you require additional languages, feel free to open an issue on GitHub – I’m happy to add them!

If you need to localize the names of your apps or any other passed text, you can use String(localized:) as usual in your app.

Showcase

I extracted this library from my following Indie apps (rate them with 5 stars to support me!):

App Icon App Name & Description Supported Platforms
TranslateKit: App Localizer
Simple drag & drop translation of String Catalog files with support for multiple translation services & smart correctness checks.
Mac
Pleydia Organizer: Movie & Series Renamer
Simple, fast, and smart media management for your Movie, TV Show and Anime collection.
Mac
FreemiumKit: In-App Purchases
Simple In-App Purchases and Subscriptions for Apple Platforms: Automation, Paywalls, A/B Testing, Live Notifications, PPP, and more.
iPhone, iPad, Mac, Vision
FreelanceKit: Time Tracking
Simple & affordable time tracking with a native experience for all  devices. iCloud sync & CSV export included.
iPhone, iPad, Mac, Vision
CrossCraft: Custom Crosswords
Create themed & personalized crosswords. Solve them yourself or share them to challenge others.
iPhone, iPad, Mac, Vision
FocusBeats: Pomodoro + Music
Deep Focus with proven Pomodoro method & select Apple Music playlists & themes. Automatically pauses music during breaks.
iPhone, iPad, Mac, Vision
Guided Guest Mode
Showcase Apple Vision Pro effortlessly to friends & family. Customizable, easy-to-use guides for everyone!
Vision
Posters: Discover Movies at Home
Auto-updating & interactive posters for your home with trailers, showtimes, and links to streaming services.
Vision