├── .gitignore ├── SafariInMessages.plist ├── prefs ├── Resources │ ├── banner.png │ ├── icon.png │ ├── icon@2x.png │ ├── icon@3x.png │ ├── banner@2x.png │ ├── banner@3x.png │ ├── Info.plist │ └── Root.plist ├── SIMRootListController.h ├── Makefile ├── layout │ └── Library │ │ └── PreferenceLoader │ │ └── Preferences │ │ └── SafariInMessages.plist └── SIMRootListController.m ├── control ├── README.md ├── Makefile ├── LICENSE └── Tweak.x /.gitignore: -------------------------------------------------------------------------------- 1 | .theos 2 | Packages 3 | -------------------------------------------------------------------------------- /SafariInMessages.plist: -------------------------------------------------------------------------------- 1 | { Filter = { Bundles = ( "com.apple.MobileSMS" ); }; } 2 | -------------------------------------------------------------------------------- /prefs/Resources/banner.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aabosh/Safari-In-Messages/HEAD/prefs/Resources/banner.png -------------------------------------------------------------------------------- /prefs/Resources/icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aabosh/Safari-In-Messages/HEAD/prefs/Resources/icon.png -------------------------------------------------------------------------------- /prefs/Resources/icon@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aabosh/Safari-In-Messages/HEAD/prefs/Resources/icon@2x.png -------------------------------------------------------------------------------- /prefs/Resources/icon@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aabosh/Safari-In-Messages/HEAD/prefs/Resources/icon@3x.png -------------------------------------------------------------------------------- /prefs/Resources/banner@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aabosh/Safari-In-Messages/HEAD/prefs/Resources/banner@2x.png -------------------------------------------------------------------------------- /prefs/Resources/banner@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aabosh/Safari-In-Messages/HEAD/prefs/Resources/banner@3x.png -------------------------------------------------------------------------------- /prefs/SIMRootListController.h: -------------------------------------------------------------------------------- 1 | #import 2 | #import 3 | 4 | @interface SIMRootListController : HBRootListController 5 | 6 | @end 7 | -------------------------------------------------------------------------------- /control: -------------------------------------------------------------------------------- 1 | Package: com.andrewabosh.safari-in-messages 2 | Name: Safari in Messages 3 | Depends: mobilesubstrate, ws.hbang.common (>= 1.16), preferenceloader 4 | Version: 1.0.2 5 | Architecture: iphoneos-arm 6 | Description: Open links natively inside Messages 7 | Maintainer: Andrew Abosh 8 | Author: Andrew Abosh 9 | Section: Tweaks 10 | -------------------------------------------------------------------------------- /prefs/Makefile: -------------------------------------------------------------------------------- 1 | include $(THEOS)/makefiles/common.mk 2 | 3 | BUNDLE_NAME = prefs 4 | 5 | prefs_FILES = SIMRootListController.m 6 | prefs_FRAMEWORKS = UIKit 7 | prefs_PRIVATE_FRAMEWORKS = Preferences BackBoardServices 8 | prefs_EXTRA_FRAMEWORKS = Cephei CepheiPrefs 9 | prefs_INSTALL_PATH = /Library/PreferenceBundles 10 | prefs_CFLAGS = -fobjc-arc 11 | 12 | include $(THEOS_MAKE_PATH)/bundle.mk 13 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Safari in Messages 2 | ### Open links natively inside Messages 3 | Safari in Messages adds functionality in the native Messages app to conveniently open links directly within Messages, rather than launching Safari. 4 | 5 | ![Video Demo](https://thumbs.gfycat.com/LiveEvilCopperbutterfly-size_restricted.gif) 6 | 7 | [Available for download on Chariz.](https://chariz.com/get/safari-in-messages) 8 | ## License 9 | Safari in Messages is licensed under the MIT license. 10 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | include $(THEOS)/makefiles/common.mk 2 | 3 | TWEAK_NAME = SafariInMessages 4 | 5 | SafariInMessages_FILES = Tweak.x 6 | SafariInMessages_CFLAGS = -fobjc-arc 7 | SafariInMessages_FRAMEWORKS = SafariServices UIKit 8 | SafariInMessages_EXTRA_FRAMEWORKS = Cephei 9 | SUBPROJECTS += prefs 10 | export ARCHS = armv7 arm64 arm64e 11 | 12 | include $(THEOS_MAKE_PATH)/tweak.mk 13 | include $(THEOS_MAKE_PATH)/aggregate.mk 14 | 15 | after-install:: 16 | install.exec "killall -9 MobileSMS Preferences" -------------------------------------------------------------------------------- /prefs/layout/Library/PreferenceLoader/Preferences/SafariInMessages.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | entry 6 | 7 | bundle 8 | prefs 9 | cell 10 | PSLinkCell 11 | detail 12 | SIMRootListController 13 | icon 14 | icon.png 15 | isController 16 | 17 | label 18 | Safari in Messages 19 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /prefs/Resources/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | English 7 | CFBundleExecutable 8 | prefs 9 | CFBundleIdentifier 10 | com.andrewabosh.safari-in-messages-prefs 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundlePackageType 14 | BNDL 15 | CFBundleShortVersionString 16 | 1.0.0 17 | CFBundleSignature 18 | ???? 19 | CFBundleVersion 20 | 1.0 21 | NSPrincipalClass 22 | SIMRootListController 23 | 24 | 25 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2020 Andrew Abosh 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /prefs/SIMRootListController.m: -------------------------------------------------------------------------------- 1 | #include "SIMRootListController.h" 2 | void BKSTerminateApplicationForReasonAndReportWithDescription(NSString* bundleId, int reasonId, bool report, NSString *description); 3 | 4 | @implementation SIMRootListController 5 | 6 | - (NSArray *)specifiers { 7 | if (!_specifiers) { 8 | _specifiers = [self loadSpecifiersFromPlistName:@"Root" target:self]; 9 | } 10 | 11 | return _specifiers; 12 | } 13 | 14 | - (void)setPreferenceValue:(id)value specifier:(PSSpecifier *)specifier { 15 | [super setPreferenceValue:value specifier:specifier]; 16 | BKSTerminateApplicationForReasonAndReportWithDescription(@"com.apple.MobileSMS", 5, false, @"Killing Messages to refresh Safari In Messages preferences."); 17 | } 18 | 19 | - (instancetype)init { 20 | self = [super init]; 21 | 22 | if (self) { 23 | HBAppearanceSettings *appearanceSettings = [[HBAppearanceSettings alloc] init]; 24 | appearanceSettings.tintColor = [UIColor colorWithRed: 0.23 green: 0.70 blue: 0.72 alpha: 1.00]; 25 | appearanceSettings.largeTitleStyle = HBAppearanceSettingsLargeTitleStyleNever; 26 | self.hb_appearanceSettings = appearanceSettings; 27 | } 28 | 29 | return self; 30 | } 31 | 32 | @end 33 | -------------------------------------------------------------------------------- /prefs/Resources/Root.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | items 6 | 7 | 8 | cell 9 | PSGroupCell 10 | headerCellClass 11 | HBImageTableCell 12 | height 13 | 120 14 | icon 15 | banner.png 16 | 17 | 18 | cell 19 | PSSwitchCell 20 | default 21 | 22 | defaults 23 | com.andrewabosh.safari-in-messages-prefs 24 | key 25 | IsEnabled 26 | label 27 | Enabled 28 | 29 | 30 | cell 31 | PSGroupCell 32 | label 33 | Options 34 | footerText 35 | Open Universal Links within Messages too. 36 | 37 | 38 | cell 39 | PSSwitchCell 40 | default 41 | 42 | defaults 43 | com.andrewabosh.safari-in-messages-prefs 44 | key 45 | OpenUniversalLinks 46 | label 47 | Open Universal Links 48 | 49 | 50 | title 51 | Safari in Messages 52 | 53 | 54 | -------------------------------------------------------------------------------- /Tweak.x: -------------------------------------------------------------------------------- 1 | #import 2 | #import 3 | 4 | // MARK: Preferences 5 | 6 | static NSString* const kPrefsBundleId = @"com.andrewabosh.safari-in-messages-prefs"; 7 | static NSString* const kPrefsEnabledKey = @"IsEnabled"; 8 | static NSString* const kPrefsOpenUniversalLinksKey = @"OpenUniversalLinks"; 9 | HBPreferences *preferences; 10 | BOOL isEnabled; 11 | BOOL openUniversalLinks; 12 | 13 | %ctor { 14 | preferences = [[HBPreferences alloc] initWithIdentifier:kPrefsBundleId]; 15 | [preferences registerDefaults:@{ 16 | kPrefsEnabledKey: @YES, 17 | kPrefsOpenUniversalLinksKey: @NO, 18 | }]; 19 | [preferences registerBool:&isEnabled default:YES forKey:kPrefsEnabledKey]; 20 | [preferences registerBool:&openUniversalLinks default:NO forKey:kPrefsOpenUniversalLinksKey]; 21 | } 22 | 23 | 24 | // MARK: The Magic 25 | 26 | @interface SMSApplication: UIApplication 27 | - (void)presentUrlInSafariVC:(NSURL*)url; 28 | - (void)openLink:(NSURL*)url; 29 | @end 30 | 31 | %hook SMSApplication 32 | 33 | %new 34 | - (void)presentUrlInSafariVC:(NSURL*)url { 35 | UIViewController *topController = [UIApplication sharedApplication].keyWindow.rootViewController; 36 | while (topController.presentedViewController) { 37 | topController = topController.presentedViewController; 38 | } 39 | SFSafariViewController *safariViewController = [[SFSafariViewController alloc] initWithURL:url]; 40 | [topController presentViewController:safariViewController animated:YES completion:nil]; 41 | } 42 | 43 | %new 44 | - (void)openLink:(NSURL*)url { 45 | if (openUniversalLinks) { 46 | [self presentUrlInSafariVC:url]; 47 | return; 48 | } 49 | // We only want to open URLs that aren't universal links in the SFSafariViewController 50 | [[UIApplication sharedApplication] openURL:url options:@{UIApplicationOpenURLOptionUniversalLinksOnly: @YES} completionHandler:^(BOOL success) { 51 | if (!success) { 52 | [self presentUrlInSafariVC:url]; 53 | } 54 | }]; 55 | } 56 | 57 | - (BOOL)openURL:(NSURL*)url { 58 | if (isEnabled && ([url.scheme isEqual:@"http"] || [url.scheme isEqual:@"https"])) { 59 | [self openLink:url]; 60 | return YES; 61 | } else { 62 | return %orig; 63 | } 64 | } 65 | 66 | - (void)openURL:(NSURL*)url options:(NSDictionary *)options completionHandler:(void (^)(BOOL success))completion { 67 | BOOL universalLinksOnly = [[options objectForKey:UIApplicationOpenURLOptionUniversalLinksOnly] boolValue]; 68 | if (isEnabled && ([url.scheme isEqual:@"http"] || [url.scheme isEqual:@"https"]) && !universalLinksOnly) { 69 | [self openLink:url]; 70 | } else { 71 | %orig; 72 | } 73 | } 74 | 75 | %end --------------------------------------------------------------------------------