BetterSafariView alternatives and similar libraries
Based on the "Utility" category.
Alternatively, view BetterSafariView alternatives based on common mentions on social networks and blogs.
-
SwifterSwift
A handy collection of more than 500 native Swift extensions to boost your productivity. -
SwiftGen-Storyboard
The Swift code generator for your assets, storyboards, Localizable.strings, … — Get rid of all String-based APIs! -
R.swift
Strong typed, autocompleted resources like images, fonts and segues in Swift projects -
SwiftGen
The Swift code generator for your assets, storyboards, Localizable.strings, … — Get rid of all String-based APIs! -
Dollar
A functional tool-belt for Swift Language similar to Lo-Dash or Underscore.js in Javascript -
swift-protobuf
Plugin and runtime library for using protobuf with Swift -
ExSwift
a set of Swift extensions for standard types and classes. -
EZSwiftExtensions
:smirk: How Swift standard types and classes were supposed to work. -
DifferenceKit
💻 A fast and flexible O(n) difference algorithm framework for Swift collection. -
LifetimeTracker
Find retain cycles / memory leaks sooner. -
Result
Swift type modelling the success/failure of arbitrary operations. -
DeepDiff
🦀Amazingly incredible extraordinary lightning fast diffing in Swift -
Device
Light weight tool for detecting the current device and screen size written in swift. -
SwiftLinkPreview
It makes a preview from an URL, grabbing all the information such as title, relevant texts and images. -
WhatsNew
Showcase new features after an app update similar to Pages, Numbers and Keynote. -
Codextended
Extensions giving Swift's Codable API type inference super powers 🦸♂️🦹♀️ -
AwesomeCache
Delightful on-disk cache (written in Swift) -
Popsicle
Delightful, extensible Swift value interpolation framework. -
SwiftyJSONAccelerator
macOS app to generate Swift 5 code for models from JSON (with Codeable) -
Playbook
📘A library for isolated developing UI components and automatically taking snapshots of them. -
ReadabilityKit
Preview extractor for news, articles and full-texts in Swift -
PDFGenerator
A simple generator of PDF written in Swift. -
Compass
:earth_africa: Compass helps you setup a central navigation system for your application -
ObjectiveKit
Swift-friendly API for a set of powerful Objective C runtime functions. -
Bow
🏹 Bow is a cross-platform library for Typed Functional Programming in Swift -
Solar
A Swift micro library for generating Sunrise and Sunset times. -
Pythonic.swift
Pythonic tool-belt for Swift – a Swift implementation of selected parts of Python standard library. -
SwiftyUtils
All the reusable code that we need in each project -
Rugby
🏈 Cache CocoaPods for faster rebuild and indexing Xcode project -
Prototope
Swift library of lightweight interfaces for prototyping, bridged to JS.
Appwrite - The Open Source Firebase alternative introduces iOS support
* Code Quality Rankings and insights are calculated and provided by Lumnify.
They vary from L1 to L5 with "L5" being the highest.
Do you think we are missing an alternative of BetterSafariView or a related project?
README
BetterSafariView
A better way to present a SFSafariViewController or start a ASWebAuthenticationSession in SwiftUI.
Contents
Motivation
SwiftUI is a strong, intuitive way to build user interfaces, but was released with some part of existing elements missing. One example of those missing elements is the SFSafariViewController
.
Fortunately, Apple provides a way to wrap UIKit elements into SwiftUI views. A common approach to place the SFSafariViewController
inside SwiftUI is to create a simple view representing a SFSafariViewController
, then present it with a sheet(isPresented:onDismiss:content:)
modifier or a NavigationLink
button (See RootView.swift
in the demo project).
However, there’s a problem in this approach: it can’t present the SFSafariViewController
with its default presentation style — a push transition covers full screen. A sheet modifier can present the view only in a modal sheet, and a navigation link shows the two navigation bars at the top so we have to deal with them. This comes down to the conclusion that there’s no option to present it the right way except for using present(_:animated:completion:)
method of a UIViewController
instance, but it is prohibited and not a good design to access the UIHostingController
directly from the SwiftUI view.
BetterSafariView
clearly achieves this goal by hosting a simple UIViewController
to present a SFSafariViewController
as a view’s background. In this way, a ASWebAuthenticationSession
is also able to be started without any issue in SwiftUI.
Requirements
- Xcode 11.0+
- Swift 5.1+
SafariView
- iOS 13.0+
- Mac Catalyst 13.0+
WebAuthenticationSession
- iOS 13.0+
- Mac Catalyst 13.0+
- macOS 10.15+
- watchOS 6.2+
Usage
With the following modifiers, you can use it in a similar way to present a sheet.
SafariView
Example
import SwiftUI
import BetterSafariView
struct ContentView: View {
@State private var presentingSafariView = false
var body: some View {
Button(action: {
self.presentingSafariView = true
}) {
Text("Present SafariView")
}
.safariView(isPresented: $presentingSafariView) {
SafariView(
url: URL(string: "https://github.com/")!,
configuration: SafariView.Configuration(
entersReaderIfAvailable: false,
barCollapsingEnabled: true
)
)
.preferredBarAccentColor(.clear)
.preferredControlAccentColor(.accentColor)
.dismissButtonStyle(.done)
}
}
}
View
Modifiers
safariView(isPresented:onDismiss:content:)
/// Presents a Safari view when a given condition is true.
func safariView(
isPresented: Binding<Bool>,
onDismiss: (() -> Void)? = nil,
content: @escaping () -> SafariView
) -> some View
safariView(item:onDismiss:content:)
/// Presents a Safari view using the given item as a data source for the `SafariView` to present.
func safariView<Item: Identifiable>(
item: Binding<Item?>,
onDismiss: (() -> Void)? = nil,
content: @escaping (Item) -> SafariView
) -> some View
SafariView
Initializers
init(url:)
/// Creates a Safari view that loads the specified URL.
init(url: URL)
init(url:configuration:)
/// Creates and configures a Safari view that loads the specified URL.
init(url: URL, configuration: SafariView.Configuration)
SafariView
Modifiers
preferredBarAccentColor(_:)
/// Sets the accent color for the background of the navigation bar and the toolbar.
func preferredBarAccentColor(_ color: Color?) -> SafariView
preferredControlAccentColor(_:)
/// Sets the accent color for the control buttons on the navigation bar and the toolbar.
func preferredControlAccentColor(_ color: Color?) -> SafariView
dismissButtonStyle(_:)
/// Sets the style of dismiss button to use in the navigation bar to close `SafariView`.
func dismissButtonStyle(_ style: SafariView.DismissButtonStyle) -> SafariView
WebAuthenticationSession
Example
import SwiftUI
import BetterSafariView
struct ContentView: View {
@State private var startingWebAuthenticationSession = false
var body: some View {
Button(action: {
self.startingWebAuthenticationSession = true
}) {
Text("Start WebAuthenticationSession")
}
.webAuthenticationSession(isPresented: $startingWebAuthenticationSession) {
WebAuthenticationSession(
url: URL(string: "https://github.com/login/oauth/authorize")!,
callbackURLScheme: "github"
) { callbackURL, error in
print(callbackURL, error)
}
.prefersEphemeralWebBrowserSession(false)
}
}
}
View
Modifiers
webAuthenticationSession(isPresented:content:)
/// Starts a web authentication session when a given condition is true.
func webAuthenticationSession(
isPresented: Binding<Bool>,
content: @escaping () -> WebAuthenticationSession
) -> some View
webAuthenticationSession(item:content:)
/// Starts a web authentication session using the given item as a data source for the `WebAuthenticationSession` to start.
func webAuthenticationSession<Item: Identifiable>(
item: Binding<Item?>,
content: @escaping (Item) -> WebAuthenticationSession
) -> some View
WebAuthenticationSession
Initializers
init(url:callbackURLScheme:completionHandler:)
/// Creates a web authentication session instance.
init(
url: URL,
callbackURLScheme: String?,
completionHandler: @escaping (URL?, Error?) -> Void
)
init(url:callbackURLScheme:onCompletion:)
/// Creates a web authentication session instance.
init(
url: URL,
callbackURLScheme: String?,
onCompletion: @escaping (Result<URL, Error>) -> Void
)
WebAuthenticationSession
Modifier
prefersEphemeralWebBrowserSession(_:)
/// Configures whether the session should ask the browser for a private authentication session.
func prefersEphemeralWebBrowserSession(_ prefersEphemeralWebBrowserSession: Bool) -> WebAuthenticationSession
Known Issues
- In
.webAuthenticationSession(item:content:)
modifier, the functionality that replaces a session on theitem
's identity change is not implemented, as there is no non-hacky way to be notified when the session's dismissal animation is completed.
Installation
Swift Package Manager
Add the following line to the dependencies
in your Package.swift
file:
.package(url: "https://github.com/stleamist/BetterSafariView.git", .upToNextMajor(from: "2.4.0"))
Next, add BetterSafariView
as a dependency for your targets:
.target(name: "MyTarget", dependencies: ["BetterSafariView"])
Your completed description may look like this:
// swift-tools-version:5.1
import PackageDescription
let package = Package(
name: "MyPackage",
dependencies: [
.package(url: "https://github.com/stleamist/BetterSafariView.git", .upToNextMajor(from: "2.4.0"))
],
targets: [
.target(name: "MyTarget", dependencies: ["BetterSafariView"])
]
)
Xcode
Select File > Swift Packages > Add Package Dependency, then enter the following URL:
https://github.com/stleamist/BetterSafariView.git
For more details, see Adding Package Dependencies to Your App.
Demo
You can see how it works on each platform and compare it with the other naive implementations in the demo project. Check out the demo app by opening BetterSafariView.xcworkspace.
NOTE: This demo project is available for iOS 14.0+, macOS 11.0+, and watchOS 7.0+, while the package is compatible with iOS 13.0+, macOS 10.15+, and watchOS 6.2+.
License
BetterSafariView is released under the MIT license. See LICENSE for details.
*Note that all licence references and agreements mentioned in the BetterSafariView README section above
are relevant to that project's source code only.