├── .github └── sceenshot_ios_alerts.png ├── .gitignore ├── CHANGELOG.md ├── CHANGELOG.md.meta ├── LICENSE.md ├── LICENSE.md.meta ├── README.md ├── README.md.meta ├── Runtime.meta ├── Runtime ├── IOS.meta ├── IOS │ ├── IOSNativeAlert.m │ └── IOSNativeAlert.m.meta ├── IOSNativeAlert.cs ├── IOSNativeAlert.cs.meta ├── com.nrjwolf.ios-native-alerts.asmdef └── com.nrjwolf.ios-native-alerts.asmdef.meta ├── Samples~ ├── IOSNativeAlertsExample.meta └── IOSNativeAlertsExample │ ├── IOSNativeAlertsExample.cs │ └── IOSNativeAlertsExample.cs.meta ├── package.json └── package.json.meta /.github/sceenshot_ios_alerts.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Nrjwolf/unity-ios-easy-native-alert/7e6ba4c11fac99bbaaf7afe5549d8e543eb46659/.github/sceenshot_ios_alerts.png -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | *.DS_Store 2 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Changelog 2 | All notable changes to this package will be documented in this file. 3 | 4 | The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/) 5 | 6 | ## [1.0.0] - 2020-03-16 7 | ### This is the first release of IOSNativeAlerts, as a Package 8 | -------------------------------------------------------------------------------- /CHANGELOG.md.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: e75adf6ee44434a72a66d1308180171f 3 | TextScriptImporter: 4 | externalObjects: {} 5 | userData: 6 | assetBundleName: 7 | assetBundleVariant: 8 | -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2020 Nrjwolf 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 | -------------------------------------------------------------------------------- /LICENSE.md.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: ffb1d52a9716a4f548445f4928d8e405 3 | DefaultImporter: 4 | externalObjects: {} 5 | userData: 6 | assetBundleName: 7 | assetBundleVariant: 8 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # IOS Easy Alert 2 | 3 | ### Install 4 | 5 | Add this as a package to your project by adding the below as an entry to the dependencies in the `/Packages/manifest.json` file: 6 | 7 | ```json 8 | "nrjwolf.games.iosnativealerts": "git+https://github.com/Nrjwolf/unity-ios-easy-native-alert" 9 | ``` 10 | For more information on adding git repositories as a package see the [Git support on Package Manager](https://docs.unity3d.com/Manual/upm-git.html) in the Unity Documentation. 11 | 12 | --- 13 | 14 | Example 15 | ``` c# 16 | using UnityEngine; 17 | 18 | namespace Nrjwolf.Tools 19 | { 20 | public class IOSNativeAlertsExample : MonoBehaviour 21 | { 22 | private void OnGUI() 23 | { 24 | #if UNITY_IOS 25 | GUI.matrix = Matrix4x4.Scale(new Vector3(3.5f, 3.5f, 3.5f)); 26 | if (GUILayout.Button("Simple Allert")) 27 | { 28 | IOSNativeAlert.ShowAlertMessage("Simple alert", "Press ok, if you're ok"); 29 | } 30 | if (GUILayout.Button("Cancel/Ok")) 31 | { 32 | IOSNativeAlert.ShowAlertMessage( 33 | "Check out my github", 34 | "You can find another great plugins for unity on my github account", 35 | new IOSNativeAlert.AlertButton("Cancel", null, ButtonStyle.Cancel), 36 | new IOSNativeAlert.AlertButton("Github", () => Application.OpenURL("https://github.com/Nrjwolf")) 37 | ); 38 | } 39 | if (GUILayout.Button("Sheet")) 40 | { 41 | IOSNativeAlert.ShowSheetMessage( 42 | "Do you want to reset your phone?", 43 | "Just kidding, I can't do it :)", 44 | new IOSNativeAlert.AlertButton("Cancel", null, ButtonStyle.Cancel), 45 | new IOSNativeAlert.AlertButton("Let's do it", () => IOSNativeAlert.ShowToast("Reseting..."), ButtonStyle.Destructive) 46 | ); 47 | } 48 | #endif 49 | } 50 | } 51 | } 52 | ``` 53 | 54 | ![](https://github.com/Nrjwolf/unity-ios-easy-native-alert/blob/master/.github/sceenshot_ios_alerts.png "")
55 | 56 | For *Android* check another my plugin https://github.com/Nrjwolf/unity-android-easy-native-alerts
57 | Do not forgot to ⭐️ it. 58 | 59 | >I'm on [reddit](https://www.reddit.com/r/Nrjwolf/) 60 | >Мой [телеграм канал](https://t.me/nrjwolf_games) 61 | -------------------------------------------------------------------------------- /README.md.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 59b2a4405625346eb9ca27e7cc46ecaa 3 | TextScriptImporter: 4 | externalObjects: {} 5 | userData: 6 | assetBundleName: 7 | assetBundleVariant: 8 | -------------------------------------------------------------------------------- /Runtime.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: abf0439c4f2e84cb08699dd641d22db4 3 | folderAsset: yes 4 | DefaultImporter: 5 | externalObjects: {} 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /Runtime/IOS.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 56da4aef3a2f2454db71deb0a0cf501b 3 | folderAsset: yes 4 | DefaultImporter: 5 | externalObjects: {} 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /Runtime/IOS/IOSNativeAlert.m: -------------------------------------------------------------------------------- 1 | // 2 | // IOSNativeAlert.m 3 | // Alert 4 | // 5 | // Created by Nrjwolf on 04/12/2019. 6 | // Copyright © 2019 Nrjwolf. All rights reserved. 7 | // 8 | 9 | extern UIViewController *UnityGetGLViewController(); 10 | 11 | NSString *ToNSString(char* string) { 12 | return [NSString stringWithUTF8String:string]; 13 | } 14 | 15 | // Unity button delegate delegate 16 | typedef void (*MonoPAlertButtonDelegate)(const char* buttonId); 17 | static MonoPAlertButtonDelegate _onButtonClick = NULL; 18 | 19 | // Register unity message handler 20 | FOUNDATION_EXPORT void IOSRegisterMessageHandler(MonoPAlertButtonDelegate onButtonClick) 21 | { 22 | _onButtonClick = onButtonClick; 23 | } 24 | 25 | // Send message to unity 26 | void SendMessageToUnity(const char* buttonId) { 27 | NSLog(@"Clicked %s", buttonId); 28 | if(_onButtonClick != NULL) { 29 | _onButtonClick(buttonId); 30 | } 31 | } 32 | 33 | // Alert function 34 | void _IOSShowAlertMsg (int alertStyle, char* title, char* message, char* buttons[], int buttonsStyle[], int buttonsLength) { 35 | UIAlertController * alert = [UIAlertController alertControllerWithTitle : ToNSString(title) message : ToNSString(message) preferredStyle : (UIAlertControllerStyle)alertStyle]; 36 | 37 | // Add buttons 38 | if (buttons && buttonsLength > 0) { 39 | for (int i = 0; i < buttonsLength; i++) { 40 | NSString *buttonTitle = ToNSString(buttons[i]); 41 | UIAlertActionStyle style = (UIAlertActionStyle)buttonsStyle[i]; 42 | UIAlertAction * button = [UIAlertAction actionWithTitle: buttonTitle style:style handler:^(UIAlertAction * action) { 43 | NSString* buttonId = [NSString stringWithFormat:@"%@%d", buttonTitle, i]; 44 | SendMessageToUnity((char*)[buttonId UTF8String]); 45 | }]; 46 | [alert addAction:button]; 47 | } 48 | } 49 | 50 | dispatch_async(dispatch_get_main_queue(), ^{ 51 | [UnityGetGLViewController() presentViewController:alert animated:YES completion:nil]; 52 | }); 53 | } 54 | 55 | /// Show something like android toast 56 | void _IOSShowToast (char* message, BOOL isLongDuration) { 57 | NSString *messageString = ToNSString(message); 58 | UIAlertController *alert = [UIAlertController alertControllerWithTitle:nil 59 | message:messageString 60 | preferredStyle:UIAlertControllerStyleAlert]; 61 | 62 | [UnityGetGLViewController() presentViewController:alert animated:YES completion:nil]; 63 | int duration = isLongDuration ? 1 : .5; 64 | dispatch_after(dispatch_time(DISPATCH_TIME_NOW, duration * NSEC_PER_SEC), dispatch_get_main_queue(), ^{ 65 | [alert dismissViewControllerAnimated:YES completion:nil]; 66 | }); 67 | } 68 | -------------------------------------------------------------------------------- /Runtime/IOS/IOSNativeAlert.m.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 3b62e07a57ed44c8d9eaef5a5e2b4ca7 3 | PluginImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | iconMap: {} 7 | executionOrder: {} 8 | defineConstraints: [] 9 | isPreloaded: 0 10 | isOverridable: 0 11 | isExplicitlyReferenced: 0 12 | validateReferences: 1 13 | platformData: 14 | - first: 15 | Any: 16 | second: 17 | enabled: 0 18 | settings: {} 19 | - first: 20 | Editor: Editor 21 | second: 22 | enabled: 0 23 | settings: 24 | DefaultValueInitialized: true 25 | - first: 26 | iPhone: iOS 27 | second: 28 | enabled: 1 29 | settings: 30 | AddToEmbeddedBinaries: false 31 | userData: 32 | assetBundleName: 33 | assetBundleVariant: 34 | -------------------------------------------------------------------------------- /Runtime/IOSNativeAlert.cs: -------------------------------------------------------------------------------- 1 | #if UNITY_IOS 2 | using System; 3 | using System.Runtime.InteropServices; 4 | #if !UNITY_EDITOR 5 | using System.Linq; 6 | #endif 7 | using UnityEngine; 8 | #endif 9 | 10 | namespace Nrjwolf.Tools 11 | { 12 | public enum ButtonStyle 13 | { 14 | Default, 15 | Cancel, 16 | Destructive, 17 | } 18 | 19 | public class IOSNativeAlert 20 | { 21 | #if UNITY_IOS 22 | private enum AlertStyle 23 | { 24 | Sheet, 25 | Alert, 26 | } 27 | 28 | public class AlertButton 29 | { 30 | public ButtonStyle Style; 31 | public string Title; 32 | public Action Callback; 33 | internal string m_Id; 34 | 35 | public AlertButton(string title, Action callback, ButtonStyle style = ButtonStyle.Default) 36 | { 37 | Title = title; 38 | Callback = callback; 39 | Style = style; 40 | } 41 | } 42 | 43 | // button callback delegate 44 | private delegate void MonoPAlertButtonDelegate(string buttonId); 45 | [DllImport("__Internal")] private static extern void IOSRegisterMessageHandler(MonoPAlertButtonDelegate onButtonClick); 46 | [DllImport("__Internal")] private static extern void _IOSShowAlertMsg(int alertStyle, string title, string message, string[] buttons, int[] buttonsStyle, int buttonsLength); 47 | [DllImport("__Internal")] private static extern void _IOSShowToast(string message, bool isLongDuration); 48 | 49 | private static AlertButton[] m_CurrentAlertButtons; 50 | 51 | [RuntimeInitializeOnLoadMethod] 52 | public static void Initialize() 53 | { 54 | #if !UNITY_EDITOR 55 | IOSRegisterMessageHandler(OnAlertButtonClick); 56 | #endif 57 | } 58 | 59 | [AOT.MonoPInvokeCallback(typeof(MonoPAlertButtonDelegate))] 60 | public static void OnAlertButtonClick(string buttonId) 61 | { 62 | if (m_CurrentAlertButtons == null || m_CurrentAlertButtons.Length == 0) return; 63 | 64 | Debug.Log($"Clicked {buttonId}"); 65 | foreach (var alertButton in m_CurrentAlertButtons) 66 | { 67 | if (alertButton.m_Id == buttonId) 68 | { 69 | alertButton.Callback?.Invoke(); 70 | break; 71 | } 72 | } 73 | } 74 | 75 | public static void ShowSheetMessage(string title, string message) => ShowAlertMessage(title, message, new AlertButton("Ok", null)); 76 | public static void ShowSheetMessage(string title, string message, params AlertButton[] buttons) => CallNativeAlertMessage(AlertStyle.Sheet, title, message, buttons); 77 | 78 | public static void ShowAlertMessage(string title, string message) => ShowAlertMessage(title, message, new AlertButton("Ok", null)); 79 | public static void ShowAlertMessage(string title, string message, params AlertButton[] buttons) => CallNativeAlertMessage(AlertStyle.Alert, title, message, buttons); 80 | 81 | private static void CallNativeAlertMessage(AlertStyle alertStyle, string title, string message, params AlertButton[] buttons) 82 | { 83 | // creating unique id for buttons 84 | for (int i = 0; i < buttons.Length; i++) 85 | buttons[i].m_Id = buttons[i].Title + i; 86 | 87 | // cache current alert buttons 88 | m_CurrentAlertButtons = buttons; 89 | 90 | #if !UNITY_EDITOR 91 | // call native ios function 92 | _IOSShowAlertMsg((int)alertStyle, title, message, buttons.Select(x => x.Title).ToArray(), buttons.Select(x => (int)x.Style).ToArray(), buttons.Length); 93 | #endif 94 | } 95 | 96 | public static void ShowToast(string text, bool isLongDuration = false) 97 | { 98 | #if !UNITY_EDITOR 99 | _IOSShowToast(text, isLongDuration); 100 | #endif 101 | } 102 | 103 | #endif 104 | } 105 | } 106 | -------------------------------------------------------------------------------- /Runtime/IOSNativeAlert.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 6378209cd3bbf44cf9110d4477e9bd4b 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Runtime/com.nrjwolf.ios-native-alerts.asmdef: -------------------------------------------------------------------------------- 1 | { 2 | "name": "nrjwolf.tools.iosnativealerts", 3 | "references": [], 4 | "includePlatforms": [], 5 | "excludePlatforms": [], 6 | "allowUnsafeCode": false, 7 | "overrideReferences": false, 8 | "precompiledReferences": [], 9 | "autoReferenced": true, 10 | "defineConstraints": [], 11 | "versionDefines": [], 12 | "noEngineReferences": false 13 | } -------------------------------------------------------------------------------- /Runtime/com.nrjwolf.ios-native-alerts.asmdef.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: fcfe32140634f49559f986101d2a2909 3 | AssemblyDefinitionImporter: 4 | externalObjects: {} 5 | userData: 6 | assetBundleName: 7 | assetBundleVariant: 8 | -------------------------------------------------------------------------------- /Samples~/IOSNativeAlertsExample.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 783f0e35e4ed42f45a64f84b81661746 3 | folderAsset: yes 4 | DefaultImporter: 5 | externalObjects: {} 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /Samples~/IOSNativeAlertsExample/IOSNativeAlertsExample.cs: -------------------------------------------------------------------------------- 1 | using UnityEngine; 2 | 3 | namespace Nrjwolf.Tools 4 | { 5 | public class IOSNativeAlertsExample : MonoBehaviour 6 | { 7 | private void OnGUI() 8 | { 9 | #if UNITY_IOS 10 | GUI.matrix = Matrix4x4.Scale(new Vector3(3.5f, 3.5f, 3.5f)); 11 | if (GUILayout.Button("Simple Allert")) 12 | { 13 | IOSNativeAlert.ShowAlertMessage("Simple alert", "Press ok, if you're ok"); 14 | } 15 | if (GUILayout.Button("Cancel/Ok")) 16 | { 17 | IOSNativeAlert.ShowAlertMessage( 18 | "Check out my github", 19 | "You can find another great plugins for unity on my github account", 20 | new IOSNativeAlert.AlertButton("Cancel", null, ButtonStyle.Cancel), 21 | new IOSNativeAlert.AlertButton("Github", () => Application.OpenURL("https://github.com/Nrjwolf")) 22 | ); 23 | } 24 | if (GUILayout.Button("Sheet")) 25 | { 26 | IOSNativeAlert.ShowSheetMessage( 27 | "Do you want to reset your phone?", 28 | "Just kidding, I can't do it :)", 29 | new IOSNativeAlert.AlertButton("Cancel", null, ButtonStyle.Cancel), 30 | new IOSNativeAlert.AlertButton("Let's do it", () => IOSNativeAlert.ShowToast("Reseting..."), ButtonStyle.Destructive) 31 | ); 32 | } 33 | #endif 34 | } 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /Samples~/IOSNativeAlertsExample/IOSNativeAlertsExample.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 736dc84899e2a194d9d4c216407b133f 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "nrjwolf.games.iosnativealerts", 3 | "displayName": "IOSNativeAlerts", 4 | "version": "1.0.0", 5 | "unity": "2018.3", 6 | "description": "Ease native IOS alerts", 7 | "keywords": [ 8 | "ios", 9 | "native", 10 | "alerts" 11 | ], 12 | "author": { 13 | "name": "Nrjwolf", 14 | "email": "alexander@nrjwolf.games", 15 | "url": "https://nrjwolf.games" 16 | }, 17 | "samples": [ 18 | { 19 | "displayName": "IOSNativeAlerts Example", 20 | "path": "Samples~/IOSNativeAlertsExample" 21 | } 22 | ] 23 | } 24 | -------------------------------------------------------------------------------- /package.json.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 728ca7142946c47cf9b603b1f68dea26 3 | PackageManifestImporter: 4 | externalObjects: {} 5 | userData: 6 | assetBundleName: 7 | assetBundleVariant: 8 | --------------------------------------------------------------------------------