Skip to content

Commit

Permalink
Added working implementation for Firefox, Chrome
Browse files Browse the repository at this point in the history
  • Loading branch information
alexbartisro committed May 13, 2020
1 parent 536a0ef commit 24f9ec7
Show file tree
Hide file tree
Showing 6 changed files with 104 additions and 35 deletions.
17 changes: 14 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,10 +1,21 @@
# iOSSwitchr
### A simple tool to change the iOS Default Browser

___
![GIF!](https://media.giphy.com/media/SURDoJI3yRCk7utlLh/giphy.gif)
___

This app cannot be published on the AppStore as changing the default browser on iOS is prohibited by Apple.

You either deploy it by yourself to your device from Xcode or self sign the `.ipa` downloaded from [here](https://github.com/trusk89/iOSSwitchr/releases).
To install, you either deploy it by yourself to your device from Xcode OR you can use [Cydia Impactor](http://www.cydiaimpactor.com/) to install the `.ipa` directly from [here](https://github.com/trusk89/iOSSwitchr/releases)).

To self sign, you can use [Cydia Impactor](http://www.cydiaimpactor.com/).
___

### Known issues:
1. Brave, Vivaldi, Opera don't work yet

2. Some URLs (I saw the behavior only in the Messages app and in Notes) are not handled as URLs by the OS, so you need to long press on them and than select `Open Link`

3. Need to do some propper organising of the classes, as everything is just thrown in there at this point
___

### If you like this project, please consider staring it. Thanks!
15 changes: 11 additions & 4 deletions iOSSwitchr/iOSSwitchr.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
objects = {

/* Begin PBXBuildFile section */
FA10E481246C7C6D0064FCFE /* DeepLinkHandler.swift in Sources */ = {isa = PBXBuildFile; fileRef = FA10E480246C7C6D0064FCFE /* DeepLinkHandler.swift */; };
FE5EABB9246C00770076D826 /* Browser.swift in Sources */ = {isa = PBXBuildFile; fileRef = FE5EABB8246C00770076D826 /* Browser.swift */; };
FE5EABBB246C07750076D826 /* Settings.swift in Sources */ = {isa = PBXBuildFile; fileRef = FE5EABBA246C07750076D826 /* Settings.swift */; };
FE5EABBD246C20800076D826 /* Player.swift in Sources */ = {isa = PBXBuildFile; fileRef = FE5EABBC246C20800076D826 /* Player.swift */; };
Expand Down Expand Up @@ -39,6 +40,7 @@
/* End PBXContainerItemProxy section */

/* Begin PBXFileReference section */
FA10E480246C7C6D0064FCFE /* DeepLinkHandler.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DeepLinkHandler.swift; sourceTree = "<group>"; };
FE5EABB8246C00770076D826 /* Browser.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Browser.swift; sourceTree = "<group>"; };
FE5EABBA246C07750076D826 /* Settings.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Settings.swift; sourceTree = "<group>"; };
FE5EABBC246C20800076D826 /* Player.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Player.swift; sourceTree = "<group>"; };
Expand Down Expand Up @@ -118,6 +120,7 @@
FE5EABB8246C00770076D826 /* Browser.swift */,
FE5EABBA246C07750076D826 /* Settings.swift */,
FE5EABBC246C20800076D826 /* Player.swift */,
FA10E480246C7C6D0064FCFE /* DeepLinkHandler.swift */,
);
path = iOSSwitchr;
sourceTree = "<group>";
Expand Down Expand Up @@ -216,6 +219,7 @@
TargetAttributes = {
FEC9D869246BDF17008A84F7 = {
CreatedOnToolsVersion = 11.3.1;
LastSwiftMigration = 1150;
};
FEC9D87F246BDF19008A84F7 = {
CreatedOnToolsVersion = 11.3.1;
Expand Down Expand Up @@ -286,6 +290,7 @@
FEC9D872246BDF17008A84F7 /* ContentView.swift in Sources */,
FE5EABBD246C20800076D826 /* Player.swift in Sources */,
FE5EABBB246C07750076D826 /* Settings.swift in Sources */,
FA10E481246C7C6D0064FCFE /* DeepLinkHandler.swift in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
Expand Down Expand Up @@ -450,10 +455,11 @@
isa = XCBuildConfiguration;
buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
CODE_SIGN_IDENTITY = "Apple Development";
CLANG_ENABLE_MODULES = YES;
CODE_SIGN_IDENTITY = "iPhone Developer";
CODE_SIGN_STYLE = Manual;
DEVELOPMENT_ASSET_PATHS = "\"iOSSwitchr/Preview Content\"";
DEVELOPMENT_TEAM = "";
DEVELOPMENT_TEAM = JEW4ZQXUL9;
ENABLE_PREVIEWS = YES;
INFOPLIST_FILE = iOSSwitchr/Info.plist;
LD_RUNPATH_SEARCH_PATHS = (
Expand All @@ -473,10 +479,11 @@
isa = XCBuildConfiguration;
buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
CODE_SIGN_IDENTITY = "Apple Development";
CLANG_ENABLE_MODULES = YES;
CODE_SIGN_IDENTITY = "iPhone Developer";
CODE_SIGN_STYLE = Manual;
DEVELOPMENT_ASSET_PATHS = "\"iOSSwitchr/Preview Content\"";
DEVELOPMENT_TEAM = "";
DEVELOPMENT_TEAM = JEW4ZQXUL9;
ENABLE_PREVIEWS = YES;
INFOPLIST_FILE = iOSSwitchr/Info.plist;
LD_RUNPATH_SEARCH_PATHS = (
Expand Down
11 changes: 6 additions & 5 deletions iOSSwitchr/iOSSwitchr/Browser.swift
Original file line number Diff line number Diff line change
Expand Up @@ -10,25 +10,26 @@ import Foundation

class Browser {
var name = ""
var key = Keys.none
var id = ID.none

enum Keys: String {
enum ID: String {
case none = "none"
case Firefox = "firefox"
case Chrome = "chrome"
case Vivaldi = "vivaldi"
case Brave = "brave"
case Opera = "opera"
}

init(name: String = "none", key: Keys = Keys.none) {
init(name: String = "none", id: ID = ID.none) {
self.name = name
self.key = key
self.id = id
}
}

extension Browser: ObservableObject, Hashable {
public static func == (lhs: Browser, rhs: Browser) -> Bool {
return lhs.key == rhs.key && lhs.name == rhs.name
return lhs.id == rhs.id && lhs.name == rhs.name
}

func hash(into hasher: inout Hasher) {
Expand Down
55 changes: 55 additions & 0 deletions iOSSwitchr/iOSSwitchr/DeepLinkHandler.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
//
// DeepLinkHandler.swift
// iOSSwitchr
//
// Created by Alex Bartis on 13/05/2020.
// Copyright © 2020 Alex Bartis. All rights reserved.
//

import Foundation
import UIKit

class DeepLinkHandler {
static func handle(urlString: String, for browserType: Browser.ID) {

var newURL: URL!

switch browserType {
case .Firefox:
if let unwrappedURL = getFirefoxURL(from: urlString) {
newURL = unwrappedURL
}

case .Chrome:
if let unwrappedURL = getChromeURL(from: urlString) {
newURL = unwrappedURL
}

default:
return
}

UIApplication.shared.open(newURL)
}

private static func getFirefoxURL(from oldURLString: String) -> URL? {
let newString = "firefox://open-url?url=" + oldURLString
guard let url = URL(string: newString) else {
return nil
}

return url
}

private static func getChromeURL(from oldURLString: String) -> URL? {
let existingScheme = oldURLString.components(separatedBy: ":").first ?? "https"
let chromeScheme = existingScheme == "http" ? "googlechrome" : "googlechromes"
let newURLString = oldURLString.replacingOccurrences(of: existingScheme, with: chromeScheme)

guard let url = URL(string: newURLString) else {
return nil
}

return url
}
}
26 changes: 10 additions & 16 deletions iOSSwitchr/iOSSwitchr/SceneDelegate.swift
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,12 @@ class SceneDelegate: UIResponder, UIWindowSceneDelegate {
let settings = Settings()

func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {
// Use this method to optionally configure and attach the UIWindow `window` to the provided UIWindowScene `scene`.
// If using a storyboard, the `window` property will automatically be initialized and attached to the scene.
// This delegate does not imply the connecting scene or session are new (see `application:configurationForConnectingSceneSession` instead).

// Create the SwiftUI view that provides the window contents.

let defaultBrowser = settings.defaultBrowser
if let url = connectionOptions.urlContexts.first?.url.absoluteString {
DeepLinkHandler.handle(urlString: url, for: defaultBrowser.id)
}

let contentView = ContentView().environmentObject(settings)

// Use a UIHostingController as window root view controller.
Expand All @@ -33,19 +34,12 @@ class SceneDelegate: UIResponder, UIWindowSceneDelegate {

func scene(_ scene: UIScene, openURLContexts URLContexts: Set<UIOpenURLContext>) {
let defaultBrowser = settings.defaultBrowser

guard let oldURLString = URLContexts.first?.url.absoluteString,
let schema = oldURLString.components(separatedBy: ":").first else {

guard let urlString = URLContexts.first?.url.absoluteString else {
return
}


let newURLString = oldURLString.replacingOccurrences(of: schema, with: defaultBrowser.key.rawValue)
guard let newURL = URL(string: newURLString) else {
return
}

UIApplication.shared.open(newURL)

DeepLinkHandler.handle(urlString: urlString, for: defaultBrowser.id)
}

func sceneDidDisconnect(_ scene: UIScene) {
Expand Down
15 changes: 8 additions & 7 deletions iOSSwitchr/iOSSwitchr/Settings.swift
Original file line number Diff line number Diff line change
Expand Up @@ -14,26 +14,27 @@ class Settings: ObservableObject {
private let defaults = UserDefaults.standard
private let defaultsKey = "DefaultBrowser"

@Published var browsers = [Browser(name: "Firefox", key: .Firefox),
Browser(name: "Chrome", key: .Chrome),
Browser(name: "Vivaldi", key: .Vivaldi),
Browser(name: "Brave", key: .Brave)]
@Published var browsers = [Browser(name: "Firefox", id: .Firefox),
Browser(name: "Chrome", id: .Chrome),
Browser(name: "Vivaldi", id: .Vivaldi),
Browser(name: "Brave", id: .Brave),
Browser(name: "Opera", id: .Opera)]

@Published var defaultBrowser: Browser {
didSet {
defaults.set(defaultBrowser.key.rawValue, forKey: defaultsKey)
defaults.set(defaultBrowser.id.rawValue, forKey: defaultsKey)
}
}

init() {
guard let existingDefault = defaults.object(forKey: defaultsKey) as? String,
let existingKey = Browser.Keys(rawValue: existingDefault) else {
let existingId = Browser.ID(rawValue: existingDefault) else {
self.defaultBrowser = Browser()

return
}

self.defaultBrowser = Browser(name: existingDefault.capitalizingFirstLetter(), key: existingKey)
self.defaultBrowser = Browser(name: existingDefault.capitalizingFirstLetter(), id: existingId)
}
}

Expand Down

0 comments on commit 24f9ec7

Please sign in to comment.