Skip to content

byaruhaf/Samaritan

Repository files navigation

Samaritan

License: MPL 2.0 Platforms Swift Version PRs Welcome Twitter

Overview

Samaritan Browser is a partial implementation of Safari functionality, which includes page navigation and page zoom features. This branch was Compiled with Xcode 14.0.0, and Swift 5.7 and supports iOS 13 and above.

Project Documentation generate using Apples DocC can be accessed using this link Documentation

Implementation Details

Navigation Implementation

Navigation is implemented with both Buttons and Gestures. Both share the same function. The navigation functions use WKWebView functions (goForward & goBack) if those are not available like after State Restoration. The navigation functions will switch and use navigation history persisted to disk.

Buttons

The state of back/forward buttons adapts accordingly to reflect an ability for the user to go either back or forward.

Gestures

The swipe gestures are a combination of both built-in WKWebView swipe gestures and gestures added to the starter view. When the webview is not hidden & webView.canGoBack is true then WKWebView swipe gestures are used. If the starter view is active or webView.canGoBack is false then swipe Gestures added to the starter view are used. Both the webview & startview gestures use slide-in transitions so users can seamlessly swipe between both views and they will act like one view. using the same gestures.

Gestures Navigation Buttons Navigation
Navigation Navigation

Persistence Implementation

The Apps Persistence is implemented using both UserDefaults and Realm

UserDefaults

UserDefaults is used to store the Zoom value to be restored for both App Restarts and App Relaunches. UserDefaults was selected because zoom levels tend to be device-specific. A user may use Zoom = 150% on an iPhone and Zoom = 85% on an iPad.

Realm

Realm is used to store the webview navigation history to be restored for App Relaunches. History is generated from the webView.backForwardList during the encodeRestorableState(with:) The state restoration framework intentionally discards any state information when the user manually kills an app, or when the state restoration process fails. These checks exist so that the app doesn’t get stuck in an infinite loop of bad states and restoration crashes.

Restore Demo showing restore of WKWebView navigation history during Relaunches

Zoom Implementation

The Apps Zoom is implemented using webView?.setValue(pageZoom, forKey: "viewScale") and and is restored in webView(_:didFinish:). Below is a video comparing Safari Zoom & Samaritan Zoom

Safari Zoom vs Samaritan Zoom

Alternatives Considered

Here are a few alternative methods of zoom I tried out.

  • pageZoom: using Instance Property pageZoom. The main issue this is only available for iOS 14.0+
  • webkitTextSizeAdjust & evaluateJavaScript: Zoom is possible but not similar to safari
  • setZoomScale for the scrollView: Zoom is possible but not similar to safari

Known issues