├── .editorconfig ├── .github ├── dependabot.yml └── workflows │ ├── autoformat-push.yml │ └── autoformat.yml ├── .gitignore ├── CODE-OF-CONDUCT.md ├── LICENSE ├── README.md ├── UnitTests ├── PListObjectTests.cs ├── TestData │ ├── PropertyLists │ │ ├── binary-integers.plist │ │ └── xml-integers.plist │ └── Provisioning Profiles │ │ ├── 29cbf4b4-a170-4c74-a29a-64ecd55b102e.mobileprovision │ │ └── 7079f389-6ff4-4290-bf76-c8a222947616.mobileprovision ├── TestHelper.cs ├── TestMobileProvisionIndex.cs └── UnitTests.csproj ├── Xamarin.MacDev.sln └── Xamarin.MacDev ├── AnalyticsService.cs ├── AppleCodeSigningIdentity.cs ├── AppleIPhoneSdk.cs ├── AppleSdk.cs ├── AppleSdkSettings.cs ├── AppleSdkVersion.cs ├── AppleTVOSSdk.cs ├── AppleWatchSdk.cs ├── EntitlementExtensions.cs ├── ExtendedVersion.cs ├── HttpMessageHandler.cs ├── IAppleSdk.cs ├── IAppleSdkVersion.cs ├── IMonoMacSdk.cs ├── IPhoneArchitecture.cs ├── IPhoneCertificate.cs ├── IPhoneDeviceCapabilities.cs ├── IPhoneDeviceType.cs ├── IPhoneImageSizes.cs ├── IPhoneSdkVersion.cs ├── Keychain.cs ├── LoggingService.cs ├── MacCatalystSupport.cs ├── MacOSXSdk.cs ├── MacOSXSdkVersion.cs ├── ManifestExtensions.cs ├── MobileProvision.cs ├── MobileProvisionIndex.cs ├── MonoMacSdk.cs ├── MonoTouchSdk.cs ├── NullableAttributes.cs ├── PListObject.cs ├── PlatformAvailability.cs ├── ProcessArgumentBuilder.cs ├── Properties └── AssemblyInfo.cs ├── XamMacSdk.cs └── Xamarin.MacDev.csproj /.editorconfig: -------------------------------------------------------------------------------- 1 | [*.{props,targets}] 2 | indent_style = tab 3 | indent_size = 4 4 | charset = utf-8 5 | 6 | [*.{csproj}] 7 | indent_style = space 8 | indent_size = 2 9 | charset = utf-8 10 | 11 | # C# files 12 | [*.cs] 13 | max_line_length = 120 14 | charset = utf-8 15 | 16 | #### Core EditorConfig Options #### 17 | 18 | # Indentation and spacing 19 | indent_style = tab 20 | indent_size = 4 21 | tab_width = 4 22 | 23 | # New line preferences 24 | end_of_line = lf 25 | insert_final_newline = true 26 | 27 | #### .NET Coding Conventions #### 28 | 29 | # Organize usings 30 | dotnet_separate_import_directive_groups = false 31 | dotnet_sort_system_directives_first = true 32 | 33 | # this. and Me. preferences 34 | dotnet_style_qualification_for_event = false:silent 35 | dotnet_style_qualification_for_field = false:silent 36 | dotnet_style_qualification_for_method = false:silent 37 | dotnet_style_qualification_for_property = false:silent 38 | 39 | # Language keywords vs BCL types preferences 40 | dotnet_style_predefined_type_for_locals_parameters_members = true:silent 41 | dotnet_style_predefined_type_for_member_access = true:silent 42 | 43 | # Parentheses preferences 44 | dotnet_style_parentheses_in_arithmetic_binary_operators = always_for_clarity:silent 45 | dotnet_style_parentheses_in_other_binary_operators = always_for_clarity:silent 46 | dotnet_style_parentheses_in_other_operators = never_if_unnecessary:silent 47 | dotnet_style_parentheses_in_relational_binary_operators = always_for_clarity:silent 48 | 49 | # Modifier preferences 50 | dotnet_style_require_accessibility_modifiers = omit_if_default:suggestion 51 | 52 | # Expression-level preferences 53 | dotnet_style_coalesce_expression = true:suggestion 54 | dotnet_style_collection_initializer = true:suggestion 55 | dotnet_style_explicit_tuple_names = true:suggestion 56 | dotnet_style_null_propagation = true:suggestion 57 | dotnet_style_object_initializer = true:suggestion 58 | dotnet_style_prefer_auto_properties = true:silent 59 | dotnet_style_prefer_compound_assignment = true:suggestion 60 | dotnet_style_prefer_conditional_expression_over_assignment = true:silent 61 | dotnet_style_prefer_conditional_expression_over_return = true:silent 62 | dotnet_style_prefer_inferred_anonymous_type_member_names = true:suggestion 63 | dotnet_style_prefer_inferred_tuple_names = true:suggestion 64 | dotnet_style_prefer_is_null_check_over_reference_equality_method = true:suggestion 65 | dotnet_style_prefer_simplified_interpolation = true:suggestion 66 | 67 | # Field preferences 68 | dotnet_style_readonly_field = true:suggestion 69 | 70 | # Parameter preferences 71 | dotnet_code_quality_unused_parameters = all:suggestion 72 | 73 | #### C# Coding Conventions #### 74 | 75 | # var preferences 76 | csharp_style_var_elsewhere = false:none 77 | csharp_style_var_for_built_in_types = false:none 78 | csharp_style_var_when_type_is_apparent = false:suggestion 79 | 80 | # Expression-bodied members 81 | csharp_style_expression_bodied_accessors = true:none 82 | csharp_style_expression_bodied_constructors = false:none 83 | csharp_style_expression_bodied_indexers = true:none 84 | csharp_style_expression_bodied_lambdas = true:none 85 | csharp_style_expression_bodied_local_functions = false:none 86 | csharp_style_expression_bodied_methods = false:none 87 | csharp_style_expression_bodied_operators = false:none 88 | csharp_style_expression_bodied_properties = true:none 89 | 90 | # Pattern matching preferences 91 | csharp_style_pattern_matching_over_as_with_null_check = true:suggestion 92 | csharp_style_pattern_matching_over_is_with_cast_check = true:suggestion 93 | csharp_style_prefer_switch_expression = true:silent 94 | 95 | # Null-checking preferences 96 | csharp_style_conditional_delegate_call = true:suggestion 97 | 98 | # Modifier preferences 99 | csharp_prefer_static_local_function = true:suggestion 100 | csharp_preferred_modifier_order = public,private,protected,internal,static,extern,new,virtual,abstract,sealed,override,readonly,unsafe,volatile,async:silent 101 | 102 | # Code-block preferences 103 | csharp_prefer_braces = when_multiline:suggestion 104 | csharp_prefer_simple_using_statement = true:suggestion 105 | 106 | # Expression-level preferences 107 | csharp_prefer_simple_default_expression = true:suggestion 108 | csharp_style_deconstructed_variable_declaration = true:suggestion 109 | csharp_style_inlined_variable_declaration = true:suggestion 110 | csharp_style_pattern_local_over_anonymous_function = true:suggestion 111 | csharp_style_prefer_index_operator = true:suggestion 112 | csharp_style_prefer_range_operator = true:suggestion 113 | csharp_style_throw_expression = true:suggestion 114 | csharp_style_unused_value_assignment_preference = discard_variable:suggestion 115 | csharp_style_unused_value_expression_statement_preference = discard_variable:silent 116 | 117 | # 'using' directive preferences 118 | csharp_using_directive_placement = outside_namespace:suggestion 119 | 120 | #### C# Formatting Rules #### 121 | 122 | # New line preferences 123 | csharp_new_line_before_catch = false 124 | csharp_new_line_before_else = false 125 | csharp_new_line_before_finally = false 126 | csharp_new_line_before_members_in_anonymous_types = true 127 | csharp_new_line_before_members_in_object_initializers = true 128 | csharp_new_line_before_open_brace = anonymous_methods,methods 129 | csharp_new_line_between_query_expression_clauses = true 130 | 131 | # Indentation preferences 132 | csharp_indent_block_contents = true 133 | csharp_indent_braces = false 134 | csharp_indent_case_contents = true 135 | csharp_indent_case_contents_when_block = false 136 | csharp_indent_labels = one_less_than_current 137 | csharp_indent_switch_labels = false 138 | 139 | # Space preferences 140 | csharp_space_after_cast = true 141 | csharp_space_after_colon_in_inheritance_clause = true 142 | csharp_space_after_comma = true 143 | csharp_space_after_dot = false 144 | csharp_space_after_keywords_in_control_flow_statements = true 145 | csharp_space_after_semicolon_in_for_statement = true 146 | csharp_space_around_binary_operators = before_and_after 147 | csharp_space_around_declaration_statements = false 148 | csharp_space_before_colon_in_inheritance_clause = true 149 | csharp_space_before_comma = false 150 | csharp_space_before_dot = false 151 | csharp_space_before_open_square_brackets = true 152 | csharp_space_before_semicolon_in_for_statement = false 153 | csharp_space_between_empty_square_brackets = false 154 | csharp_space_between_method_call_empty_parameter_list_parentheses = false 155 | csharp_space_between_method_call_name_and_opening_parenthesis = true 156 | csharp_space_between_method_call_parameter_list_parentheses = false 157 | csharp_space_between_method_declaration_empty_parameter_list_parentheses = false 158 | csharp_space_between_method_declaration_name_and_open_parenthesis = true 159 | csharp_space_between_method_declaration_parameter_list_parentheses = false 160 | csharp_space_between_parentheses = false 161 | csharp_space_between_square_brackets = false 162 | 163 | # Wrapping preferences 164 | csharp_preserve_single_line_blocks = true 165 | csharp_preserve_single_line_statements = true 166 | 167 | #### Naming styles #### 168 | 169 | # Naming rules 170 | 171 | dotnet_naming_rule.interface_should_be_begins_with_i.severity = suggestion 172 | dotnet_naming_rule.interface_should_be_begins_with_i.symbols = interface 173 | dotnet_naming_rule.interface_should_be_begins_with_i.style = begins_with_i 174 | 175 | dotnet_naming_rule.types_should_be_pascalcase.severity = suggestion 176 | dotnet_naming_rule.types_should_be_pascalcase.symbols = types 177 | dotnet_naming_rule.types_should_be_pascalcase.style = pascalcase 178 | 179 | dotnet_naming_rule.non_field_members_should_be_pascalcase.severity = suggestion 180 | dotnet_naming_rule.non_field_members_should_be_pascalcase.symbols = non_field_members 181 | dotnet_naming_rule.non_field_members_should_be_pascalcase.style = pascalcase 182 | 183 | dotnet_naming_rule.private_or_internal_field_should_be_camelcase.severity = suggestion 184 | dotnet_naming_rule.private_or_internal_field_should_be_camelcase.symbols = private_or_internal_field 185 | dotnet_naming_rule.private_or_internal_field_should_be_camelcase.style = camelcase 186 | 187 | # Symbol specifications 188 | 189 | dotnet_naming_symbols.interface.applicable_kinds = interface 190 | dotnet_naming_symbols.interface.applicable_accessibilities = public, internal, private, protected, protected_internal, private_protected 191 | dotnet_naming_symbols.interface.required_modifiers = 192 | 193 | dotnet_naming_symbols.private_or_internal_field.applicable_kinds = field 194 | dotnet_naming_symbols.private_or_internal_field.applicable_accessibilities = internal, private, private_protected 195 | dotnet_naming_symbols.private_or_internal_field.required_modifiers = 196 | 197 | dotnet_naming_symbols.types.applicable_kinds = class, struct, interface, enum 198 | dotnet_naming_symbols.types.applicable_accessibilities = public, internal, private, protected, protected_internal, private_protected 199 | dotnet_naming_symbols.types.required_modifiers = 200 | 201 | dotnet_naming_symbols.non_field_members.applicable_kinds = property, event, method 202 | dotnet_naming_symbols.non_field_members.applicable_accessibilities = public, internal, private, protected, protected_internal, private_protected 203 | dotnet_naming_symbols.non_field_members.required_modifiers = 204 | 205 | # Naming styles 206 | 207 | dotnet_naming_style.pascalcase.required_prefix = 208 | dotnet_naming_style.pascalcase.required_suffix = 209 | dotnet_naming_style.pascalcase.word_separator = 210 | dotnet_naming_style.pascalcase.capitalization = pascal_case 211 | 212 | dotnet_naming_style.begins_with_i.required_prefix = I 213 | dotnet_naming_style.begins_with_i.required_suffix = 214 | dotnet_naming_style.begins_with_i.word_separator = 215 | dotnet_naming_style.begins_with_i.capitalization = pascal_case 216 | 217 | dotnet_naming_style.camelcase.required_prefix = 218 | dotnet_naming_style.camelcase.required_suffix = 219 | dotnet_naming_style.camelcase.word_separator = 220 | dotnet_naming_style.camelcase.capitalization = camel_case 221 | 222 | # specify StringComparison for correctness 223 | dotnet_diagnostic.CA1309.severity = error 224 | 225 | # generated code from the project 226 | [*.g.cs] 227 | generated_code = true 228 | dotnet_diagnostic.BI1234.severity = silent 229 | -------------------------------------------------------------------------------- /.github/dependabot.yml: -------------------------------------------------------------------------------- 1 | # To get started with Dependabot version updates, you'll need to specify which 2 | # package ecosystems to update and where the package manifests are located. 3 | # Please see the documentation for all configuration options: 4 | # https://docs.github.com/code-security/dependabot/dependabot-version-updates/configuration-options-for-the-dependabot.yml-file 5 | 6 | version: 2 7 | updates: 8 | - package-ecosystem: "github-action" # See documentation for possible values 9 | directory: "/" # Location of package manifests 10 | schedule: 11 | interval: "weekly" 12 | -------------------------------------------------------------------------------- /.github/workflows/autoformat-push.yml: -------------------------------------------------------------------------------- 1 | name: Autoformat code - push results 2 | on: 3 | workflow_run: 4 | workflows: ["Autoformat code"] 5 | types: 6 | - completed 7 | 8 | permissions: 9 | pull-requests: write 10 | contents: write 11 | 12 | jobs: 13 | push-and-notify: 14 | name: Push autoformatted code and notify user 15 | runs-on: ubuntu-latest 16 | if: > 17 | github.event.workflow_run.event == 'pull_request' && 18 | github.event.workflow_run.conclusion == 'success' 19 | steps: 20 | - name: 'Push autoformatted patch' 21 | uses: rolfbjarne/autoformat-push@v0.1 22 | with: 23 | githubToken: ${{ secrets.GITHUB_TOKEN }} 24 | -------------------------------------------------------------------------------- /.github/workflows/autoformat.yml: -------------------------------------------------------------------------------- 1 | name: Autoformat code 2 | on: pull_request 3 | 4 | # This action only need a single permission in order to autoformat the code. 5 | permissions: 6 | contents: read 7 | 8 | jobs: 9 | autoformat-code: 10 | name: Autoformat code 11 | runs-on: ubuntu-latest 12 | 13 | steps: 14 | - name: 'Autoformat' 15 | uses: rolfbjarne/autoformat@v0.1 16 | with: 17 | projects: "Xamarin.MacDev.sln" 18 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | bin 2 | obj 3 | *.userprefs 4 | 5 | /packages/ 6 | .vs/ 7 | -------------------------------------------------------------------------------- /CODE-OF-CONDUCT.md: -------------------------------------------------------------------------------- 1 | # Code of Conduct 2 | 3 | This project has adopted the code of conduct defined by the Contributor Covenant 4 | to clarify expected behavior in our community. 5 | 6 | For more information, see the [.NET Foundation Code of Conduct](https://dotnetfoundation.org/code-of-conduct). 7 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Xamarin SDK 2 | 3 | The MIT License (MIT) 4 | 5 | Copyright (c) .NET Foundation Contributors 6 | 7 | All rights reserved. 8 | 9 | Permission is hereby granted, free of charge, to any person obtaining a copy 10 | of this software and associated documentation files (the "Software"), to deal 11 | in the Software without restriction, including without limitation the rights 12 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 13 | copies of the Software, and to permit persons to whom the Software is 14 | furnished to do so, subject to the following conditions: 15 | 16 | The above copyright notice and this permission notice shall be included in all 17 | copies or substantial portions of the Software. 18 | 19 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 20 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 21 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 22 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 23 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 24 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 25 | SOFTWARE. 26 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Xamarin.MacDev 2 | 3 | ## Welcome! 4 | 5 | This module is a support repository used by both **Xamarin.iOS** and **Xamarin.Mac**. 6 | 7 | It contains support libraries used during msbuild builds. 8 | 9 | See [xamarin-macios](https://github.com/xamarin/xamarin-macios/blob/master/README.md#contributing) for more information on contributing to and providing feedback on Xamarin.iOS and Xamarin.Mac. 10 | 11 | ## License 12 | 13 | Copyright (c) .NET Foundation Contributors. All rights reserved. 14 | Licensed under the [MIT](https://github.com/xamarin/Xamarin.MacDev/blob/master/LICENSE) License. 15 | -------------------------------------------------------------------------------- /UnitTests/PListObjectTests.cs: -------------------------------------------------------------------------------- 1 | // 2 | // TestMobileProvisionIndex.cs 3 | // 4 | // Author: Jeffrey Stedfast 5 | // 6 | // Copyright (c) 2017 Microsoft Corp. 7 | // 8 | // Permission is hereby granted, free of charge, to any person obtaining a copy 9 | // of this software and associated documentation files (the "Software"), to deal 10 | // in the Software without restriction, including without limitation the rights 11 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 12 | // copies of the Software, and to permit persons to whom the Software is 13 | // furnished to do so, subject to the following conditions: 14 | // 15 | // The above copyright notice and this permission notice shall be included in 16 | // all copies or substantial portions of the Software. 17 | // 18 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 19 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 20 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 21 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 22 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 23 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 24 | // THE SOFTWARE. 25 | 26 | using System; 27 | using System.Collections.Generic; 28 | using System.IO; 29 | using System.Runtime.InteropServices.ComTypes; 30 | using System.Text; 31 | using NUnit.Framework; 32 | using Xamarin.MacDev; 33 | 34 | namespace UnitTests { 35 | [TestFixture] 36 | public class PListObjectTests { 37 | static readonly KeyValuePair [] IntegerKeyValuePairs = new KeyValuePair [] { 38 | new KeyValuePair ("Negative1", -1), 39 | new KeyValuePair ("SByteMaxValueMinusOne", sbyte.MaxValue - 1), 40 | new KeyValuePair ("SByteMaxValue", sbyte.MaxValue), 41 | new KeyValuePair ("ByteMaxValueMinusOne", byte.MaxValue - 1), 42 | new KeyValuePair ("ByteMaxValue", byte.MaxValue), 43 | new KeyValuePair ("ShortMaxValueMinusOne", short.MaxValue - 1), 44 | new KeyValuePair ("ShortMaxValue", short.MaxValue), 45 | new KeyValuePair ("UShortMaxValueMinusOne", ushort.MaxValue - 1), 46 | new KeyValuePair ("UShortMaxValue", ushort.MaxValue), 47 | new KeyValuePair ("IntMaxValueMinusOne", int.MaxValue - 1), 48 | new KeyValuePair ("IntMaxValue", int.MaxValue), 49 | new KeyValuePair ("IntMaxValuePlusOne", ((long) int.MaxValue) + 1), 50 | new KeyValuePair ("UIntMaxValue", uint.MaxValue), 51 | new KeyValuePair ("UIntMaxValuePlusOne", ((long) uint.MaxValue) + 1), 52 | new KeyValuePair ("LongMaxValue", long.MaxValue), 53 | 54 | // FIXME: Apple supports up to ulong.MaxValue 55 | // new KeyValuePair ("ULongMaxValue", ulong.MaxValue), 56 | }; 57 | 58 | [TestCase ("xml-integers.plist")] 59 | [TestCase ("binary-integers.plist")] 60 | public void TestIntegerDeserialization (string fileName) 61 | { 62 | PDictionary plist; 63 | 64 | using (var stream = GetType ().Assembly.GetManifestResourceStream ($"UnitTests.TestData.PropertyLists.{fileName}")) 65 | plist = (PDictionary) PObject.FromStream (stream); 66 | 67 | Assert.That (plist.Count, Is.EqualTo (IntegerKeyValuePairs.Length)); 68 | 69 | foreach (var kvp in IntegerKeyValuePairs) { 70 | Assert.That (plist.TryGetValue (kvp.Key, out PObject value), Is.True); 71 | Assert.That (value, Is.InstanceOf ()); 72 | var integer = (PNumber) value; 73 | Assert.That (integer.Value, Is.EqualTo (kvp.Value)); 74 | } 75 | } 76 | 77 | [Test] 78 | public void TestIntegerXmlSerialization () 79 | { 80 | var plist = new PDictionary (); 81 | 82 | foreach (var kvp in IntegerKeyValuePairs) 83 | plist.Add (kvp.Key, new PNumber (kvp.Value)); 84 | 85 | var output = plist.ToXml (); 86 | string expected; 87 | 88 | using (var stream = GetType ().Assembly.GetManifestResourceStream ("UnitTests.TestData.PropertyLists.xml-integers.plist")) { 89 | var buffer = new byte [stream.Length]; 90 | stream.Read (buffer, 0, buffer.Length); 91 | 92 | expected = Encoding.UTF8.GetString (buffer); 93 | } 94 | 95 | Assert.That (output, Is.EqualTo (expected)); 96 | } 97 | 98 | [Test] 99 | public void TestIntegerBinarySerialization () 100 | { 101 | var plist = new PDictionary (); 102 | 103 | foreach (var kvp in IntegerKeyValuePairs) 104 | plist.Add (kvp.Key, new PNumber (kvp.Value)); 105 | 106 | var output = plist.ToByteArray (PropertyListFormat.Binary); 107 | 108 | plist = (PDictionary) PObject.FromByteArray (output, 0, output.Length, out var isBinary); 109 | 110 | Assert.That (isBinary, Is.True); 111 | Assert.That (plist.Count, Is.EqualTo (IntegerKeyValuePairs.Length)); 112 | 113 | foreach (var kvp in IntegerKeyValuePairs) { 114 | Assert.That (plist.TryGetValue (kvp.Key, out PObject value), Is.True); 115 | Assert.That (value, Is.InstanceOf ()); 116 | var integer = (PNumber) value; 117 | Assert.That (integer.Value, Is.EqualTo (kvp.Value)); 118 | } 119 | } 120 | } 121 | } 122 | 123 | -------------------------------------------------------------------------------- /UnitTests/TestData/PropertyLists/binary-integers.plist: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dotnet/macios-devtools/e47d6b1ebfeffbde3b83e9152ced52a545759122/UnitTests/TestData/PropertyLists/binary-integers.plist -------------------------------------------------------------------------------- /UnitTests/TestData/PropertyLists/xml-integers.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Negative1 6 | -1 7 | SByteMaxValueMinusOne 8 | 126 9 | SByteMaxValue 10 | 127 11 | ByteMaxValueMinusOne 12 | 254 13 | ByteMaxValue 14 | 255 15 | ShortMaxValueMinusOne 16 | 32766 17 | ShortMaxValue 18 | 32767 19 | UShortMaxValueMinusOne 20 | 65534 21 | UShortMaxValue 22 | 65535 23 | IntMaxValueMinusOne 24 | 2147483646 25 | IntMaxValue 26 | 2147483647 27 | IntMaxValuePlusOne 28 | 2147483648 29 | UIntMaxValue 30 | 4294967295 31 | UIntMaxValuePlusOne 32 | 4294967296 33 | LongMaxValue 34 | 9223372036854775807 35 | 36 | 37 | -------------------------------------------------------------------------------- /UnitTests/TestData/Provisioning Profiles/29cbf4b4-a170-4c74-a29a-64ecd55b102e.mobileprovision: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dotnet/macios-devtools/e47d6b1ebfeffbde3b83e9152ced52a545759122/UnitTests/TestData/Provisioning Profiles/29cbf4b4-a170-4c74-a29a-64ecd55b102e.mobileprovision -------------------------------------------------------------------------------- /UnitTests/TestData/Provisioning Profiles/7079f389-6ff4-4290-bf76-c8a222947616.mobileprovision: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dotnet/macios-devtools/e47d6b1ebfeffbde3b83e9152ced52a545759122/UnitTests/TestData/Provisioning Profiles/7079f389-6ff4-4290-bf76-c8a222947616.mobileprovision -------------------------------------------------------------------------------- /UnitTests/TestHelper.cs: -------------------------------------------------------------------------------- 1 | // 2 | // TestHelper.cs 3 | // 4 | // Author: Jeffrey Stedfast 5 | // 6 | // Copyright (c) 2017 Microsoft Corp. 7 | // 8 | // Permission is hereby granted, free of charge, to any person obtaining a copy 9 | // of this software and associated documentation files (the "Software"), to deal 10 | // in the Software without restriction, including without limitation the rights 11 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 12 | // copies of the Software, and to permit persons to whom the Software is 13 | // furnished to do so, subject to the following conditions: 14 | // 15 | // The above copyright notice and this permission notice shall be included in 16 | // all copies or substantial portions of the Software. 17 | // 18 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 19 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 20 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 21 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 22 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 23 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 24 | // THE SOFTWARE. 25 | 26 | using System; 27 | using System.IO; 28 | 29 | using NUnit.Framework; 30 | 31 | namespace UnitTests { 32 | [SetUpFixture] 33 | static class TestHelper { 34 | public static readonly string ProjectDir; 35 | 36 | static TestHelper () 37 | { 38 | #if NET5_0_OR_GREATER 39 | var codeBase = typeof (TestHelper).Assembly.Location; 40 | #else 41 | var codeBase = typeof (TestHelper).Assembly.CodeBase; 42 | if (codeBase.StartsWith ("file://", StringComparison.OrdinalIgnoreCase)) 43 | codeBase = codeBase.Substring ("file://".Length); 44 | 45 | if (Path.DirectorySeparatorChar == '\\') { 46 | if (codeBase [0] == '/') 47 | codeBase = codeBase.Substring (1); 48 | 49 | codeBase = codeBase.Replace ('/', '\\'); 50 | } 51 | #endif 52 | 53 | var dir = Path.GetDirectoryName (codeBase); 54 | 55 | while (Path.GetFileName (dir) != "UnitTests") 56 | dir = Path.GetFullPath (Path.Combine (dir, "..")); 57 | 58 | ProjectDir = Path.GetFullPath (dir); 59 | } 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /UnitTests/TestMobileProvisionIndex.cs: -------------------------------------------------------------------------------- 1 | // 2 | // TestMobileProvisionIndex.cs 3 | // 4 | // Author: Jeffrey Stedfast 5 | // 6 | // Copyright (c) 2017 Microsoft Corp. 7 | // 8 | // Permission is hereby granted, free of charge, to any person obtaining a copy 9 | // of this software and associated documentation files (the "Software"), to deal 10 | // in the Software without restriction, including without limitation the rights 11 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 12 | // copies of the Software, and to permit persons to whom the Software is 13 | // furnished to do so, subject to the following conditions: 14 | // 15 | // The above copyright notice and this permission notice shall be included in 16 | // all copies or substantial portions of the Software. 17 | // 18 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 19 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 20 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 21 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 22 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 23 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 24 | // THE SOFTWARE. 25 | 26 | using System; 27 | using System.IO; 28 | 29 | using NUnit.Framework; 30 | 31 | using Xamarin.MacDev; 32 | 33 | namespace UnitTests { 34 | [TestFixture] 35 | public class TestMobileProvisionIndex { 36 | static readonly string [] ProfileDirectories; 37 | 38 | static TestMobileProvisionIndex () 39 | { 40 | ProfileDirectories = new string [] { 41 | Path.Combine (TestHelper.ProjectDir, "TestData", "Provisioning Profiles") 42 | }; 43 | } 44 | 45 | [Test] 46 | public void TestCreateIndex () 47 | { 48 | var index = MobileProvisionIndex.CreateIndex (ProfileDirectories, "profiles.index"); 49 | 50 | Assert.That (index.ProvisioningProfiles.Count, Is.EqualTo (2)); 51 | 52 | var idCompanyName = index.ProvisioningProfiles.FindIndex ((v) => v.ApplicationIdentifier.Contains ("companyname")); 53 | var idXamarin = index.ProvisioningProfiles.FindIndex ((v) => v.ApplicationIdentifier.Contains ("xamarin")); 54 | Assert.That (idCompanyName, Is.Not.EqualTo (-1), "Company Name Index"); 55 | Assert.That (idXamarin, Is.Not.EqualTo (-1), "Xamarin Index"); 56 | Assert.That (idCompanyName, Is.Not.EqualTo (idXamarin), "Indices"); 57 | Assert.That (index.ProvisioningProfiles [idCompanyName].ApplicationIdentifier, Is.EqualTo ("YHT9CR87YA.com.companyname.*")); 58 | Assert.That (index.ProvisioningProfiles [idCompanyName].CreationDate, Is.EqualTo (new DateTime (2017, 07, 19, 19, 43, 45, DateTimeKind.Utc))); 59 | Assert.That (index.ProvisioningProfiles [idCompanyName].DeveloperCertificates.Count, Is.EqualTo (1)); 60 | Assert.That (index.ProvisioningProfiles [idCompanyName].DeveloperCertificates [0].Name, Is.EqualTo ("iPhone Developer: Jeffrey Stedfast (FZ77UAV9SW)")); 61 | Assert.That (index.ProvisioningProfiles [idCompanyName].DeveloperCertificates [0].Thumbprint, Is.EqualTo ("2097D37F4D16AB7D8D927E7C1872F2A94D8DC718")); 62 | Assert.That (index.ProvisioningProfiles [idCompanyName].Distribution, Is.EqualTo (MobileProvisionDistributionType.Development)); 63 | Assert.That (index.ProvisioningProfiles [idCompanyName].ExpirationDate, Is.EqualTo (new DateTime (2018, 07, 19, 19, 43, 45, DateTimeKind.Utc))); 64 | Assert.That (Path.GetFileName (index.ProvisioningProfiles [idCompanyName].FileName), Is.EqualTo ("29cbf4b4-a170-4c74-a29a-64ecd55b102e.mobileprovision")); 65 | //Assert.AreEqual (index.ProvisioningProfiles[0].LastModified); 66 | Assert.That (index.ProvisioningProfiles [idCompanyName].Name, Is.EqualTo ("CompanyName Development Profile")); 67 | Assert.That (index.ProvisioningProfiles [0].Platforms.Count, Is.EqualTo (1)); 68 | Assert.That (index.ProvisioningProfiles [idCompanyName].Platforms [0], Is.EqualTo (MobileProvisionPlatform.iOS)); 69 | Assert.That (index.ProvisioningProfiles [idCompanyName].Uuid, Is.EqualTo ("29cbf4b4-a170-4c74-a29a-64ecd55b102e")); 70 | 71 | Assert.That (index.ProvisioningProfiles [idXamarin].ApplicationIdentifier, Is.EqualTo ("YHT9CR87YA.com.xamarin.*")); 72 | Assert.That (index.ProvisioningProfiles [idXamarin].CreationDate, Is.EqualTo (new DateTime (2017, 07, 19, 19, 44, 0, DateTimeKind.Utc))); 73 | Assert.That (index.ProvisioningProfiles [idXamarin].DeveloperCertificates.Count, Is.EqualTo (1)); 74 | Assert.That (index.ProvisioningProfiles [idXamarin].DeveloperCertificates [0].Name, Is.EqualTo ("iPhone Developer: Jeffrey Stedfast (FZ77UAV9SW)")); 75 | Assert.That (index.ProvisioningProfiles [idXamarin].DeveloperCertificates [0].Thumbprint, Is.EqualTo ("2097D37F4D16AB7D8D927E7C1872F2A94D8DC718")); 76 | Assert.That (index.ProvisioningProfiles [idXamarin].Distribution, Is.EqualTo (MobileProvisionDistributionType.Development)); 77 | Assert.That (index.ProvisioningProfiles [idXamarin].ExpirationDate, Is.EqualTo (new DateTime (2018, 07, 19, 19, 44, 0, DateTimeKind.Utc))); 78 | Assert.That (Path.GetFileName (index.ProvisioningProfiles [idXamarin].FileName), Is.EqualTo ("7079f389-6ff4-4290-bf76-c8a222947616.mobileprovision")); 79 | //Assert.AreEqual (index.ProvisioningProfiles[0].LastModified); 80 | Assert.That (index.ProvisioningProfiles [idXamarin].Name, Is.EqualTo ("Xamarin Development Profile")); 81 | Assert.That (index.ProvisioningProfiles [idXamarin].Platforms.Count, Is.EqualTo (1)); 82 | Assert.That (index.ProvisioningProfiles [idXamarin].Platforms [0], Is.EqualTo (MobileProvisionPlatform.iOS)); 83 | Assert.That (index.ProvisioningProfiles [idXamarin].Uuid, Is.EqualTo ("7079f389-6ff4-4290-bf76-c8a222947616")); 84 | } 85 | 86 | [Test] 87 | public void TestOpenIndex () 88 | { 89 | var index = MobileProvisionIndex.OpenIndex (ProfileDirectories, "profiles.index"); 90 | 91 | Assert.That (index.ProvisioningProfiles.Count, Is.EqualTo (2)); 92 | 93 | var idCompanyName = index.ProvisioningProfiles.FindIndex ((v) => v.ApplicationIdentifier.Contains ("companyname")); 94 | var idXamarin = index.ProvisioningProfiles.FindIndex ((v) => v.ApplicationIdentifier.Contains ("xamarin")); 95 | Assert.That (idCompanyName, Is.Not.EqualTo (-1), "Company Name Index"); 96 | Assert.That (idXamarin, Is.Not.EqualTo (-1), "Xamarin Index"); 97 | Assert.That (idCompanyName, Is.Not.EqualTo (idXamarin), "Indices"); 98 | Assert.That (index.ProvisioningProfiles [idCompanyName].ApplicationIdentifier, Is.EqualTo ("YHT9CR87YA.com.companyname.*")); 99 | Assert.That (index.ProvisioningProfiles [idCompanyName].CreationDate, Is.EqualTo (new DateTime (2017, 07, 19, 19, 43, 45, DateTimeKind.Utc))); 100 | Assert.That (index.ProvisioningProfiles [idCompanyName].DeveloperCertificates.Count, Is.EqualTo (1)); 101 | Assert.That (index.ProvisioningProfiles [idCompanyName].DeveloperCertificates [0].Name, Is.EqualTo ("iPhone Developer: Jeffrey Stedfast (FZ77UAV9SW)")); 102 | Assert.That (index.ProvisioningProfiles [idCompanyName].DeveloperCertificates [0].Thumbprint, Is.EqualTo ("2097D37F4D16AB7D8D927E7C1872F2A94D8DC718")); 103 | Assert.That (index.ProvisioningProfiles [idCompanyName].Distribution, Is.EqualTo (MobileProvisionDistributionType.Development)); 104 | Assert.That (index.ProvisioningProfiles [idCompanyName].ExpirationDate, Is.EqualTo (new DateTime (2018, 07, 19, 19, 43, 45, DateTimeKind.Utc))); 105 | Assert.That (Path.GetFileName (index.ProvisioningProfiles [idCompanyName].FileName), Is.EqualTo ("29cbf4b4-a170-4c74-a29a-64ecd55b102e.mobileprovision")); 106 | //Assert.AreEqual (index.ProvisioningProfiles[0].LastModified); 107 | Assert.That (index.ProvisioningProfiles [idCompanyName].Name, Is.EqualTo ("CompanyName Development Profile")); 108 | Assert.That (index.ProvisioningProfiles [idCompanyName].Platforms.Count, Is.EqualTo (1)); 109 | Assert.That (index.ProvisioningProfiles [idCompanyName].Platforms [0], Is.EqualTo (MobileProvisionPlatform.iOS)); 110 | Assert.That (index.ProvisioningProfiles [idCompanyName].Uuid, Is.EqualTo ("29cbf4b4-a170-4c74-a29a-64ecd55b102e")); 111 | 112 | Assert.That (index.ProvisioningProfiles [idXamarin].ApplicationIdentifier, Is.EqualTo ("YHT9CR87YA.com.xamarin.*")); 113 | Assert.That (index.ProvisioningProfiles [idXamarin].CreationDate, Is.EqualTo (new DateTime (2017, 07, 19, 19, 44, 0, DateTimeKind.Utc))); 114 | Assert.That (index.ProvisioningProfiles [idXamarin].DeveloperCertificates.Count, Is.EqualTo (1)); 115 | Assert.That (index.ProvisioningProfiles [idXamarin].DeveloperCertificates [0].Name, Is.EqualTo ("iPhone Developer: Jeffrey Stedfast (FZ77UAV9SW)")); 116 | Assert.That (index.ProvisioningProfiles [idXamarin].DeveloperCertificates [0].Thumbprint, Is.EqualTo ("2097D37F4D16AB7D8D927E7C1872F2A94D8DC718")); 117 | Assert.That (index.ProvisioningProfiles [idXamarin].Distribution, Is.EqualTo (MobileProvisionDistributionType.Development)); 118 | Assert.That (index.ProvisioningProfiles [idXamarin].ExpirationDate, Is.EqualTo (new DateTime (2018, 07, 19, 19, 44, 0, DateTimeKind.Utc))); 119 | Assert.That (Path.GetFileName (index.ProvisioningProfiles [idXamarin].FileName), Is.EqualTo ("7079f389-6ff4-4290-bf76-c8a222947616.mobileprovision")); 120 | //Assert.AreEqual (index.ProvisioningProfiles[0].LastModified); 121 | Assert.That (index.ProvisioningProfiles [idXamarin].Name, Is.EqualTo ("Xamarin Development Profile")); 122 | Assert.That (index.ProvisioningProfiles [idXamarin].Platforms.Count, Is.EqualTo (1)); 123 | Assert.That (index.ProvisioningProfiles [idXamarin].Platforms [0], Is.EqualTo (MobileProvisionPlatform.iOS)); 124 | Assert.That (index.ProvisioningProfiles [idXamarin].Uuid, Is.EqualTo ("7079f389-6ff4-4290-bf76-c8a222947616")); 125 | } 126 | } 127 | } 128 | -------------------------------------------------------------------------------- /UnitTests/UnitTests.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | net472 5 | 6 | 7 | 8 | 9 | all 10 | runtime; build; native; contentfiles; analyzers; buildtransitive 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | -------------------------------------------------------------------------------- /Xamarin.MacDev.sln: -------------------------------------------------------------------------------- 1 | 2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio 2012 4 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Xamarin.MacDev", "Xamarin.MacDev\Xamarin.MacDev.csproj", "{CC3D9353-20C4-467A-8522-A9DED6F0C753}" 5 | EndProject 6 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "UnitTests", "UnitTests\UnitTests.csproj", "{39DBAAF8-57A5-49A3-9E9A-11B545906AED}" 7 | EndProject 8 | Global 9 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 10 | Debug|Any CPU = Debug|Any CPU 11 | Release|Any CPU = Release|Any CPU 12 | EndGlobalSection 13 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 14 | {CC3D9353-20C4-467A-8522-A9DED6F0C753}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 15 | {CC3D9353-20C4-467A-8522-A9DED6F0C753}.Debug|Any CPU.Build.0 = Debug|Any CPU 16 | {CC3D9353-20C4-467A-8522-A9DED6F0C753}.Release|Any CPU.ActiveCfg = Debug|Any CPU 17 | {CC3D9353-20C4-467A-8522-A9DED6F0C753}.Release|Any CPU.Build.0 = Debug|Any CPU 18 | {39DBAAF8-57A5-49A3-9E9A-11B545906AED}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 19 | {39DBAAF8-57A5-49A3-9E9A-11B545906AED}.Debug|Any CPU.Build.0 = Debug|Any CPU 20 | {39DBAAF8-57A5-49A3-9E9A-11B545906AED}.Release|Any CPU.ActiveCfg = Release|Any CPU 21 | {39DBAAF8-57A5-49A3-9E9A-11B545906AED}.Release|Any CPU.Build.0 = Release|Any CPU 22 | EndGlobalSection 23 | EndGlobal 24 | -------------------------------------------------------------------------------- /Xamarin.MacDev/AnalyticsService.cs: -------------------------------------------------------------------------------- 1 | // 2 | // AnalyticsService.cs 3 | // 4 | // Author: 5 | // Greg Munn 6 | // 7 | // Copyright (c) 2014 Xamarin Inc 8 | // 9 | 10 | using System; 11 | using System.Collections.Generic; 12 | 13 | namespace Xamarin.MacDev { 14 | public interface ICustomAnalytics { 15 | /// 16 | /// Reports the sdk versions to analytics. These are sent as a single event with properties derived from `values` 17 | /// 18 | void ReportSdkVersions (Dictionary values); 19 | } 20 | 21 | /// 22 | /// Provides a way to log analytics to Xamarin Insights, or other analytics service 23 | /// 24 | public static class AnalyticsService { 25 | static ICustomAnalytics Analytics; 26 | 27 | public static void SetCustomAnalytics (ICustomAnalytics customAnalytics) 28 | { 29 | Analytics = customAnalytics; 30 | } 31 | 32 | /// 33 | /// Reports the sdk versions to analytics. These are sent as a single event with properties derived from `values` 34 | /// 35 | public static void ReportSdkVersions (Dictionary values) 36 | { 37 | if (Analytics != null) { 38 | Analytics.ReportSdkVersions (values); 39 | } 40 | } 41 | 42 | /// 43 | /// Reports the sdk versions to analytics. These are sent as a single event with properties derived from `sdkProperty` and `sdkValue` 44 | /// 45 | public static void ReportSdkVersion (string sdkProperty, string sdkValue) 46 | { 47 | if (Analytics != null) { 48 | Analytics.ReportSdkVersions (new Dictionary { { sdkProperty, sdkValue } }); 49 | } 50 | } 51 | 52 | [Obsolete ("This method does nothing. The telemetry API is changing and for the time being we are only sending the minimum of events that need to be processed server side.")] 53 | public static void Track (string trackId, Dictionary table = null) 54 | { 55 | } 56 | 57 | [Obsolete ("This method does nothing. The telemetry API is changing and for the time being we are only sending the minimum of events that need to be processed server side.")] 58 | public static void Track (string trackId, string key, string value) 59 | { 60 | } 61 | 62 | [Obsolete ("This method does nothing. The telemetry API is changing and for the time being we are only sending the minimum of events that need to be processed server side.")] 63 | public static IDisposable TrackTime (string trackId, Dictionary table = null) 64 | { 65 | return NullTimeTracker.Default; 66 | } 67 | 68 | [Obsolete ("This method does nothing. The telemetry API is changing and for the time being we are only sending the minimum of events that need to be processed server side.")] 69 | public static IDisposable TrackTime (string trackId, string key, string value) 70 | { 71 | return TrackTime (trackId, new Dictionary () { { key, value } }); 72 | } 73 | 74 | [Obsolete ("This method does nothing. The telemetry API is changing and for the time being we are only sending the minimum of events that need to be processed server side.")] 75 | public static void IdentifyTrait (string trait, string value) 76 | { 77 | } 78 | 79 | class NullTimeTracker : IDisposable { 80 | public static NullTimeTracker Default = new NullTimeTracker (); 81 | 82 | public void Dispose () 83 | { 84 | } 85 | } 86 | } 87 | } 88 | -------------------------------------------------------------------------------- /Xamarin.MacDev/AppleCodeSigningIdentity.cs: -------------------------------------------------------------------------------- 1 | // 2 | // AppleCodeSigningIdentity.cs 3 | // 4 | // Author: 5 | // Jeffrey Stedfast 6 | // 7 | // Copyright (c) 2013 Xamarin Inc. 8 | // 9 | 10 | using System.Security.Cryptography.X509Certificates; 11 | 12 | namespace Xamarin.MacDev { 13 | public class AppleCodeSigningIdentity { 14 | public string CommonName { get { return Keychain.GetCertificateCommonName (Certificate); } } 15 | public X509Certificate2 Certificate { get; private set; } 16 | public bool HasPrivateKey { get; private set; } 17 | 18 | public AppleCodeSigningIdentity (X509Certificate2 certificate, bool hasPrivateKey) 19 | { 20 | Certificate = certificate; 21 | HasPrivateKey = hasPrivateKey; 22 | } 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /Xamarin.MacDev/AppleIPhoneSdk.cs: -------------------------------------------------------------------------------- 1 | // 2 | // AppleIPhoneSdk.cs 3 | // 4 | // Authors: Michael Hutchinson 5 | // Jeffrey Stedfast 6 | // 7 | // Copyright (c) 2011-2013 Xamarin Inc. 8 | // 9 | // Permission is hereby granted, free of charge, to any person obtaining a copy 10 | // of this software and associated documentation files (the "Software"), to deal 11 | // in the Software without restriction, including without limitation the rights 12 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 13 | // copies of the Software, and to permit persons to whom the Software is 14 | // furnished to do so, subject to the following conditions: 15 | // 16 | // The above copyright notice and this permission notice shall be included in 17 | // all copies or substantial portions of the Software. 18 | // 19 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 20 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 21 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 22 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 23 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 24 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 25 | // THE SOFTWARE. 26 | 27 | using System.Collections.Generic; 28 | 29 | namespace Xamarin.MacDev { 30 | public class AppleIPhoneSdk : AppleSdk { 31 | protected override string SimulatorPlatformName { 32 | get { 33 | return "iPhoneSimulator"; 34 | } 35 | } 36 | 37 | protected override string DevicePlatformName { 38 | get { 39 | return "iPhoneOS"; 40 | } 41 | } 42 | 43 | public AppleIPhoneSdk (string sdkRoot, string versionPlist) 44 | { 45 | DeveloperRoot = sdkRoot; 46 | VersionPlist = versionPlist; 47 | Init (); 48 | } 49 | } 50 | 51 | public class AppleDTSettings { 52 | public string DTXcodeBuild { get; set; } 53 | public string DTPlatformVersion { get; set; } 54 | public string DTPlatformBuild { get; set; } 55 | public string BuildMachineOSBuild { get; set; } 56 | } 57 | 58 | public class AppleDTSdkSettings { 59 | public string CanonicalName { get; set; } 60 | public string AlternateSDK { get; set; } 61 | public string DTCompiler { get; set; } 62 | public string DTSDKBuild { get; set; } 63 | public IPhoneDeviceType DeviceFamilies { get; set; } 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /Xamarin.MacDev/AppleSdk.cs: -------------------------------------------------------------------------------- 1 | // 2 | // AppleSdk.cs 3 | // 4 | // Authors: Rolf Bjarne Kvinge 5 | // 6 | // Copyright (c) 2015 Xamarin Inc. 7 | // 8 | // Permission is hereby granted, free of charge, to any person obtaining a copy 9 | // of this software and associated documentation files (the "Software"), to deal 10 | // in the Software without restriction, including without limitation the rights 11 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 12 | // copies of the Software, and to permit persons to whom the Software is 13 | // furnished to do so, subject to the following conditions: 14 | // 15 | // The above copyright notice and this permission notice shall be included in 16 | // all copies or substantial portions of the Software. 17 | // 18 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 19 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 20 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 21 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 22 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 23 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 24 | // THE SOFTWARE. 25 | 26 | using System; 27 | using System.Collections.Generic; 28 | using System.IO; 29 | using System.Linq; 30 | 31 | namespace Xamarin.MacDev { 32 | public abstract class AppleSdk : IAppleSdk { 33 | public string DeveloperRoot { get; protected set; } 34 | public string VersionPlist { get; protected set; } 35 | 36 | protected abstract string DevicePlatformName { get; } 37 | protected abstract string SimulatorPlatformName { get; } 38 | 39 | public string DevicePlatform { get { return Path.Combine (DeveloperRoot, "Platforms/" + DevicePlatformName + ".platform"); } } 40 | public string SimPlatform { get { return Path.Combine (DeveloperRoot, "Platforms/" + SimulatorPlatformName + ".platform"); } } 41 | 42 | public bool IsInstalled { get; private set; } 43 | public AppleSdkVersion [] InstalledSdkVersions { get; private set; } 44 | public AppleSdkVersion [] InstalledSimVersions { get; private set; } 45 | 46 | readonly Dictionary sdkSettingsCache = new Dictionary (); 47 | readonly Dictionary simSettingsCache = new Dictionary (); 48 | AppleDTSettings dtSettings; 49 | 50 | const string PLATFORM_VERSION_PLIST = "version.plist"; 51 | const string SYSTEM_VERSION_PLIST = "/System/Library/CoreServices/SystemVersion.plist"; 52 | 53 | protected void Init () 54 | { 55 | IsInstalled = File.Exists (Path.Combine (DevicePlatform, "Info.plist")); 56 | 57 | if (IsInstalled) { 58 | File.GetLastWriteTimeUtc (VersionPlist); 59 | InstalledSdkVersions = EnumerateSdks (Path.Combine (DevicePlatform, "Developer/SDKs"), DevicePlatformName); 60 | InstalledSimVersions = EnumerateSdks (Path.Combine (SimPlatform, "Developer/SDKs"), SimulatorPlatformName); 61 | } else { 62 | InstalledSdkVersions = new AppleSdkVersion [0]; 63 | InstalledSimVersions = new AppleSdkVersion [0]; 64 | } 65 | } 66 | 67 | 68 | public string GetPlatformPath (bool sim) 69 | { 70 | return sim ? SimPlatform : DevicePlatform; 71 | } 72 | 73 | public string GetSdkPath (IAppleSdkVersion version, bool sim) 74 | { 75 | return GetSdkPath (version.ToString (), sim); 76 | } 77 | 78 | public string GetSdkPath (string version, bool sim) 79 | { 80 | if (sim) 81 | return Path.Combine (SimPlatform, "Developer/SDKs/" + SimulatorPlatformName + version + ".sdk"); 82 | 83 | return Path.Combine (DevicePlatform, "Developer/SDKs/" + DevicePlatformName + version + ".sdk"); 84 | } 85 | 86 | public string GetSdkPath (bool isSimulator) 87 | { 88 | return GetSdkPath (string.Empty, isSimulator); 89 | } 90 | 91 | public string GetSdkPath () 92 | { 93 | throw new InvalidOperationException ($"This AppleSdk requires specifying whether we're targeting the simulator or not, so please use the other overload taking a 'bool isSimulator' parameter."); 94 | } 95 | 96 | public string GetSdkPath (string version) 97 | { 98 | throw new InvalidOperationException ($"This AppleSdk requires specifying whether we're targeting the simulator or not, so please use the other overload taking a 'bool isSimulator' parameter."); 99 | } 100 | 101 | string GetSdkPlistFilename (string version, bool sim) 102 | { 103 | return Path.Combine (GetSdkPath (version, sim), "SDKSettings.plist"); 104 | } 105 | 106 | bool IAppleSdk.SdkIsInstalled (IAppleSdkVersion version, bool isSimulator) 107 | { 108 | return SdkIsInstalled ((AppleSdkVersion) version, isSimulator); 109 | } 110 | 111 | public bool SdkIsInstalled (AppleSdkVersion version, bool sim) 112 | { 113 | foreach (var v in (sim ? InstalledSimVersions : InstalledSdkVersions)) 114 | if (v.Equals (version)) 115 | return true; 116 | return false; 117 | } 118 | 119 | public AppleDTSdkSettings GetSdkSettings (AppleSdkVersion sdk, bool isSim) 120 | { 121 | return GetSdkSettings ((IAppleSdkVersion) sdk, isSim); 122 | } 123 | 124 | public AppleDTSdkSettings GetSdkSettings (IAppleSdkVersion sdk, bool isSim) 125 | { 126 | var cache = isSim ? simSettingsCache : sdkSettingsCache; 127 | 128 | AppleDTSdkSettings settings; 129 | if (cache.TryGetValue (sdk.ToString (), out settings)) 130 | return settings; 131 | 132 | try { 133 | settings = LoadSdkSettings (sdk, isSim); 134 | } catch (Exception ex) { 135 | var sdkName = isSim ? SimulatorPlatformName : DevicePlatformName; 136 | LoggingService.LogError (string.Format ("Error loading settings for SDK {0} {1}", sdkName, sdk), ex); 137 | } 138 | 139 | cache [sdk.ToString ()] = settings; 140 | return settings; 141 | } 142 | 143 | AppleDTSdkSettings LoadSdkSettings (IAppleSdkVersion sdk, bool isSim) 144 | { 145 | var settings = new AppleDTSdkSettings (); 146 | 147 | var plist = PDictionary.FromFile (GetSdkPlistFilename (sdk.ToString (), isSim)); 148 | if (!isSim) 149 | settings.AlternateSDK = plist.GetString ("AlternateSDK").Value; 150 | 151 | settings.CanonicalName = plist.GetString ("CanonicalName").Value; 152 | 153 | var props = plist.Get ("DefaultProperties"); 154 | 155 | PString gcc; 156 | if (!props.TryGetValue ("GCC_VERSION", out gcc)) 157 | settings.DTCompiler = "com.apple.compilers.llvm.clang.1_0"; 158 | else 159 | settings.DTCompiler = gcc.Value; 160 | 161 | settings.DeviceFamilies = props.GetUIDeviceFamily ("SUPPORTED_DEVICE_FAMILIES"); 162 | var plstPlist = Path.Combine (GetPlatformPath (isSim), PLATFORM_VERSION_PLIST); 163 | settings.DTSDKBuild = GrabRootString (plstPlist, "ProductBuildVersion"); 164 | 165 | return settings; 166 | } 167 | 168 | public AppleDTSettings GetDTSettings () 169 | { 170 | if (dtSettings != null) 171 | return dtSettings; 172 | 173 | var dict = PDictionary.FromFile (Path.Combine (DevicePlatform, "Info.plist")); 174 | var infos = dict.Get ("AdditionalInfo"); 175 | 176 | return (dtSettings = new AppleDTSettings { 177 | DTPlatformVersion = infos.Get ("DTPlatformVersion").Value, 178 | DTPlatformBuild = GrabRootString (Path.Combine (DevicePlatform, "version.plist"), "ProductBuildVersion"), 179 | DTXcodeBuild = GrabRootString (VersionPlist, "ProductBuildVersion"), 180 | BuildMachineOSBuild = GrabRootString (SYSTEM_VERSION_PLIST, "ProductBuildVersion"), 181 | }); 182 | } 183 | 184 | public AppleDTSettings GetAppleDTSettings () 185 | { 186 | return GetDTSettings (); 187 | } 188 | 189 | IAppleSdkVersion IAppleSdk.GetClosestInstalledSdk (IAppleSdkVersion version, bool isSimulator) 190 | { 191 | return GetClosestInstalledSdk ((AppleSdkVersion) version, isSimulator); 192 | } 193 | 194 | public AppleSdkVersion GetClosestInstalledSdk (AppleSdkVersion v, bool sim) 195 | { 196 | //sorted low to high, so get first that's >= requested version 197 | foreach (var i in GetInstalledSdkVersions (sim)) { 198 | if (i.CompareTo (v) >= 0) 199 | return i; 200 | } 201 | return AppleSdkVersion.UseDefault; 202 | } 203 | 204 | IList IAppleSdk.GetInstalledSdkVersions (bool isSimulator) 205 | { 206 | return GetInstalledSdkVersions (isSimulator).Cast ().ToArray (); 207 | } 208 | 209 | public IList GetInstalledSdkVersions (bool sim) 210 | { 211 | return sim ? InstalledSimVersions : InstalledSdkVersions; 212 | } 213 | 214 | protected static AppleSdkVersion [] EnumerateSdks (string sdkDir, string name) 215 | { 216 | if (!Directory.Exists (sdkDir)) 217 | return new AppleSdkVersion [0]; 218 | 219 | var sdks = new List (); 220 | 221 | foreach (var dir in Directory.GetDirectories (sdkDir)) { 222 | if (!File.Exists (Path.Combine (dir, "SDKSettings.plist"))) 223 | continue; 224 | 225 | string d = Path.GetFileName (dir); 226 | if (!d.StartsWith (name, StringComparison.Ordinal)) 227 | continue; 228 | 229 | d = d.Substring (name.Length); 230 | if (!d.EndsWith (".sdk", StringComparison.Ordinal)) 231 | continue; 232 | 233 | d = d.Substring (0, d.Length - ".sdk".Length); 234 | if (d.Length > 0) 235 | sdks.Add (d); 236 | } 237 | 238 | var vs = new List (); 239 | foreach (var s in sdks) { 240 | try { 241 | vs.Add (AppleSdkVersion.Parse (s)); 242 | } catch (Exception ex) { 243 | LoggingService.LogError ("Could not parse {0} SDK version '{1}':\n{2}", name, s, ex.ToString ()); 244 | } 245 | } 246 | 247 | var versions = vs.ToArray (); 248 | Array.Sort (versions); 249 | return versions; 250 | } 251 | 252 | protected static string GrabRootString (string file, string key) 253 | { 254 | if (!File.Exists (file)) 255 | return null; 256 | 257 | var dict = PDictionary.FromFile (file); 258 | PString value; 259 | 260 | if (dict.TryGetValue (key, out value)) 261 | return value.Value; 262 | 263 | return null; 264 | } 265 | 266 | bool IAppleSdk.TryParseSdkVersion (string value, out IAppleSdkVersion version) 267 | { 268 | return IAppleSdkVersion_Extensions.TryParse (value, out version); 269 | } 270 | } 271 | } 272 | -------------------------------------------------------------------------------- /Xamarin.MacDev/AppleSdkSettings.cs: -------------------------------------------------------------------------------- 1 | // 2 | // AppleSdkSettings.cs 3 | // 4 | // Authors: Michael Hutchinson 5 | // Jeffrey Stedfast 6 | // 7 | // Copyright (c) 2011 Xamarin Inc. (http://xamarin.com) 8 | // 9 | // Permission is hereby granted, free of charge, to any person obtaining a copy 10 | // of this software and associated documentation files (the "Software"), to deal 11 | // in the Software without restriction, including without limitation the rights 12 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 13 | // copies of the Software, and to permit persons to whom the Software is 14 | // furnished to do so, subject to the following conditions: 15 | // 16 | // The above copyright notice and this permission notice shall be included in 17 | // all copies or substantial portions of the Software. 18 | // 19 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 20 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 21 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 22 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 23 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 24 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 25 | // THE SOFTWARE. 26 | 27 | using System; 28 | using System.ComponentModel; 29 | using System.Diagnostics; 30 | using System.IO; 31 | 32 | namespace Xamarin.MacDev { 33 | public static class AppleSdkSettings { 34 | static readonly string SettingsPath; 35 | 36 | // Put newer SDKs at the top as we scan from 0 -> List.Count 37 | public static readonly string [] DefaultRoots = new string [] { 38 | "/Applications/Xcode.app", 39 | }; 40 | static DateTime lastWritten; 41 | 42 | public static string SdkNotInstalledReason { get; private set; } 43 | 44 | static void GetNewPaths (string root, out string xcode, out string vplist, out string devroot) 45 | { 46 | xcode = root; 47 | vplist = Path.Combine (root, "Contents", "version.plist"); 48 | devroot = Path.Combine (root, "Contents", "Developer"); 49 | } 50 | 51 | static void GetOldPaths (string root, out string xcode, out string vplist, out string devroot) 52 | { 53 | xcode = Path.Combine (root, "Applications", "Xcode.app"); 54 | vplist = Path.Combine (root, "Library", "version.plist"); 55 | devroot = root; 56 | } 57 | 58 | static bool ValidatePaths (string xcode, string vplist, string devroot) 59 | { 60 | return Directory.Exists (xcode) 61 | && Directory.Exists (devroot) 62 | && File.Exists (vplist) 63 | && File.Exists (Path.Combine (xcode, "Contents", "Info.plist")); 64 | } 65 | 66 | public static bool ValidateSdkLocation (string location, out string xcode, out string vplist, out string devroot) 67 | { 68 | GetNewPaths (location, out xcode, out vplist, out devroot); 69 | if (ValidatePaths (xcode, vplist, devroot)) 70 | return true; 71 | 72 | GetOldPaths (location, out xcode, out vplist, out devroot); 73 | if (ValidatePaths (xcode, vplist, devroot)) 74 | return true; 75 | 76 | return false; 77 | } 78 | 79 | public static void SetConfiguredSdkLocation (string location) 80 | { 81 | PDictionary plist; 82 | bool binary; 83 | 84 | try { 85 | plist = PDictionary.FromFile (SettingsPath, out binary); 86 | } catch (FileNotFoundException) { 87 | plist = new PDictionary (); 88 | binary = false; 89 | } 90 | 91 | if (!string.IsNullOrEmpty (location)) { 92 | plist.SetString ("AppleSdkRoot", location); 93 | } else { 94 | plist.Remove ("AppleSdkRoot"); 95 | } 96 | 97 | plist.Save (SettingsPath, true, binary); 98 | 99 | //Init (); 100 | //var changed = Changed; 101 | //if (changed != null) 102 | // changed (); 103 | } 104 | 105 | public static string GetConfiguredSdkLocation () 106 | { 107 | PDictionary plist = null; 108 | PString value; 109 | 110 | try { 111 | if (File.Exists (SettingsPath)) 112 | plist = PDictionary.FromFile (SettingsPath, out var _); 113 | } catch (FileNotFoundException) { 114 | } 115 | 116 | // First try the configured location in Visual Studio 117 | if (plist != null && plist.TryGetValue ("AppleSdkRoot", out value) && !string.IsNullOrEmpty (value?.Value)) { 118 | LoggingService.LogInfo (string.Format ("An Xcode location was found in the file '{0}': {1}", SettingsPath, value.Value)); 119 | return value.Value; 120 | } 121 | 122 | // Then check the system's default Xcode 123 | if (TryGetSystemXcode (out var path)) 124 | return path; 125 | 126 | // Finally return the hardcoded default 127 | LoggingService.LogInfo (string.Format ("Using the default Xcode location '{0}'", DefaultRoots [0])); 128 | return DefaultRoots [0]; 129 | } 130 | 131 | static void SetInvalid () 132 | { 133 | XcodePath = string.Empty; 134 | InvalidDeveloperRoot = DeveloperRoot; 135 | DeveloperRoot = string.Empty; 136 | DeveloperRootVersionPlist = string.Empty; 137 | IsValid = false; 138 | DTXcode = null; 139 | XcodeVersion = new Version (0, 0, 0); 140 | XcodeRevision = string.Empty; 141 | lastWritten = DateTime.MinValue; 142 | } 143 | 144 | static AppleSdkSettings () 145 | { 146 | var home = Environment.GetFolderPath (Environment.SpecialFolder.UserProfile); 147 | 148 | SettingsPath = Path.Combine (home, "Library", "Preferences", "maui", "Settings.plist"); 149 | 150 | if (!File.Exists (SettingsPath)) { 151 | var oldSettings = Path.Combine (home, "Library", "Preferences", "Xamarin", "Settings.plist"); 152 | if (File.Exists (oldSettings)) 153 | SettingsPath = oldSettings; 154 | } 155 | 156 | Directory.CreateDirectory (Path.GetDirectoryName (SettingsPath)); 157 | 158 | Init (); 159 | } 160 | 161 | public static bool TryGetSystemXcode (out string path) 162 | { 163 | path = null; 164 | if (!File.Exists ("/usr/bin/xcode-select")) 165 | return false; 166 | 167 | try { 168 | using var process = new Process (); 169 | process.StartInfo.FileName = "/usr/bin/xcode-select"; 170 | process.StartInfo.Arguments = "--print-path"; 171 | process.StartInfo.RedirectStandardOutput = true; 172 | process.StartInfo.UseShellExecute = false; 173 | process.Start (); 174 | var stdout = process.StandardOutput.ReadToEnd (); 175 | process.WaitForExit (); 176 | 177 | stdout = stdout.Trim (); 178 | if (Directory.Exists (stdout)) { 179 | if (stdout.EndsWith ("/Contents/Developer", StringComparison.Ordinal)) 180 | stdout = stdout.Substring (0, stdout.Length - "/Contents/Developer".Length); 181 | 182 | path = stdout; 183 | LoggingService.LogInfo (string.Format ("Using the Xcode location configured for this system (found using 'xcode-select -p'): {0}", path)); 184 | return true; 185 | } 186 | 187 | LoggingService.LogInfo ("The system's Xcode location {0} does not exist", stdout); 188 | 189 | return false; 190 | } catch (Exception e) { 191 | LoggingService.LogInfo ("Could not get the system's Xcode location: {0}", e); 192 | return false; 193 | } 194 | } 195 | 196 | public static void Init () 197 | { 198 | string devroot = null, vplist = null, xcode = null; 199 | bool foundSdk = false; 200 | 201 | SetInvalid (); 202 | 203 | DeveloperRoot = Environment.GetEnvironmentVariable ("MD_APPLE_SDK_ROOT"); 204 | if (!string.IsNullOrEmpty (DeveloperRoot)) 205 | LoggingService.LogInfo (string.Format ("An Xcode location was specified in the environment variable 'MD_APPLE_SDK_ROOT': {0}", DeveloperRoot)); 206 | 207 | if (string.IsNullOrEmpty (DeveloperRoot)) 208 | DeveloperRoot = GetConfiguredSdkLocation (); 209 | 210 | if (string.IsNullOrEmpty (DeveloperRoot)) { 211 | foreach (var v in DefaultRoots) { 212 | if (ValidateSdkLocation (v, out xcode, out vplist, out devroot)) { 213 | foundSdk = true; 214 | break; 215 | } 216 | 217 | SdkNotInstalledReason += string.Format ("A valid Xcode installation was not found at '{0}'\n", v); 218 | LoggingService.LogInfo (SdkNotInstalledReason); 219 | } 220 | } else if (!ValidateSdkLocation (DeveloperRoot, out xcode, out vplist, out devroot)) { 221 | SdkNotInstalledReason = string.Format ("A valid Xcode installation was not found at the configured location: '{0}'", DeveloperRoot); 222 | LoggingService.LogError (SdkNotInstalledReason); 223 | SetInvalid (); 224 | return; 225 | } else { 226 | foundSdk = true; 227 | } 228 | 229 | if (foundSdk) { 230 | XcodePath = xcode; 231 | DeveloperRoot = devroot; 232 | DeveloperRootVersionPlist = vplist; 233 | Environment.SetEnvironmentVariable ("XCODE_DEVELOPER_DIR_PATH", DeveloperRoot); 234 | } else { 235 | SetInvalid (); 236 | return; 237 | } 238 | 239 | try { 240 | var plist = Path.Combine (XcodePath, "Contents", "Info.plist"); 241 | 242 | if (!File.Exists (plist)) { 243 | SetInvalid (); 244 | return; 245 | } 246 | 247 | lastWritten = File.GetLastWriteTimeUtc (plist); 248 | 249 | XcodeVersion = new Version (3, 2, 6); 250 | XcodeRevision = "0"; 251 | 252 | // DTXCode was introduced after xcode 3.2.6 so it may not exist 253 | var dict = PDictionary.FromFile (plist); 254 | 255 | PString value; 256 | if (dict.TryGetValue ("DTXcode", out value)) 257 | DTXcode = value.Value; 258 | 259 | if (dict.TryGetValue ("CFBundleShortVersionString", out value)) 260 | XcodeVersion = Version.Parse (value.Value); 261 | 262 | if (dict.TryGetValue ("CFBundleVersion", out value)) 263 | XcodeRevision = value.Value; 264 | 265 | LoggingService.LogInfo ("Found Xcode, version {0} ({1}).", XcodeVersion, XcodeRevision); 266 | AnalyticsService.ReportSdkVersion ("XS.Core.SDK.Xcode.Version", XcodeVersion.ToString ()); 267 | IsValid = true; 268 | } catch (Exception ex) { 269 | SdkNotInstalledReason = string.Format ("Error loading Xcode information for prefix '" + DeveloperRoot + "'"); 270 | LoggingService.LogError (SdkNotInstalledReason, ex); 271 | SetInvalid (); 272 | } 273 | } 274 | 275 | public static string DeveloperRoot { get; private set; } 276 | 277 | public static string InvalidDeveloperRoot { get; private set; } 278 | 279 | public static string DeveloperRootVersionPlist { 280 | get; private set; 281 | } 282 | 283 | public static string XcodePath { 284 | get; private set; 285 | } 286 | 287 | [Obsolete ("This method does nothing")] 288 | public static void CheckChanged () 289 | { 290 | //var plist = Path.Combine (XcodePath, "Contents", "Info.plist"); 291 | //var mtime = DateTime.MinValue; 292 | 293 | //if (File.Exists (plist)) 294 | // mtime = File.GetLastWriteTimeUtc (plist); 295 | 296 | //if (mtime != lastWritten) { 297 | // Init (); 298 | // Changed (); 299 | //} 300 | } 301 | 302 | public static bool IsValid { get; private set; } 303 | public static string DTXcode { get; private set; } 304 | 305 | public static Version XcodeVersion { get; private set; } 306 | public static string XcodeRevision { get; private set; } 307 | 308 | #pragma warning disable 0067 309 | [Obsolete ("This event is never raised")] 310 | public static event Action Changed; 311 | #pragma warning restore 0067 312 | } 313 | } 314 | -------------------------------------------------------------------------------- /Xamarin.MacDev/AppleSdkVersion.cs: -------------------------------------------------------------------------------- 1 | // 2 | // AppleSdkVersion.cs 3 | // 4 | // Authors: Michael Hutchinson 5 | // Jeffrey Stedfast 6 | // 7 | // Copyright (c) 2010 Novell, Inc. (http://www.novell.com) 8 | // Copyright (c) 2011-2013 Xamarin Inc. (http://www.xamarin.com) 9 | // Copyright (c) 2021 Microsoft Corp. (http://www.microsoft.com) 10 | // 11 | // Permission is hereby granted, free of charge, to any person obtaining a copy 12 | // of this software and associated documentation files (the "Software"), to deal 13 | // in the Software without restriction, including without limitation the rights 14 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 15 | // copies of the Software, and to permit persons to whom the Software is 16 | // furnished to do so, subject to the following conditions: 17 | // 18 | // The above copyright notice and this permission notice shall be included in 19 | // all copies or substantial portions of the Software. 20 | // 21 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 22 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 23 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 24 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 25 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 26 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 27 | // THE SOFTWARE. 28 | 29 | using System; 30 | 31 | namespace Xamarin.MacDev { 32 | public struct AppleSdkVersion : IComparable, IEquatable, IAppleSdkVersion { 33 | int [] version; 34 | 35 | public AppleSdkVersion (Version version) 36 | { 37 | if (version == null) 38 | throw new ArgumentNullException (); 39 | 40 | if (version.Build != -1) { 41 | this.version = new int [3]; 42 | this.version [2] = version.Build; 43 | } else { 44 | this.version = new int [2]; 45 | } 46 | 47 | this.version [0] = version.Major; 48 | this.version [1] = version.Minor; 49 | } 50 | 51 | public AppleSdkVersion (params int [] version) 52 | { 53 | if (version == null) 54 | throw new ArgumentNullException (nameof (version)); 55 | 56 | this.version = version; 57 | } 58 | 59 | void IAppleSdkVersion.SetVersion (int [] version) 60 | { 61 | this.version = version; 62 | } 63 | 64 | public static AppleSdkVersion Parse (string s) 65 | { 66 | return IAppleSdkVersion_Extensions.Parse (s); 67 | } 68 | 69 | public static bool TryParse (string s, out AppleSdkVersion result) 70 | { 71 | return IAppleSdkVersion_Extensions.TryParse (s, out result); 72 | } 73 | 74 | public int [] Version { get { return version; } } 75 | 76 | public override string ToString () 77 | { 78 | return IAppleSdkVersion_Extensions.ToString (this); 79 | } 80 | 81 | public int CompareTo (AppleSdkVersion other) 82 | { 83 | return IAppleSdkVersion_Extensions.CompareTo (this, other); 84 | } 85 | 86 | public int CompareTo (IAppleSdkVersion other) 87 | { 88 | return IAppleSdkVersion_Extensions.CompareTo (this, other); 89 | } 90 | 91 | public bool Equals (IAppleSdkVersion other) 92 | { 93 | return IAppleSdkVersion_Extensions.Equals (this, other); 94 | } 95 | 96 | public bool Equals (AppleSdkVersion other) 97 | { 98 | return IAppleSdkVersion_Extensions.Equals (this, other); 99 | } 100 | 101 | public override bool Equals (object obj) 102 | { 103 | return IAppleSdkVersion_Extensions.Equals (this, obj); 104 | } 105 | 106 | public override int GetHashCode () 107 | { 108 | return IAppleSdkVersion_Extensions.GetHashCode (this); 109 | } 110 | 111 | public static bool operator == (AppleSdkVersion a, IAppleSdkVersion b) 112 | { 113 | return a.Equals (b); 114 | } 115 | 116 | public static bool operator != (AppleSdkVersion a, IAppleSdkVersion b) 117 | { 118 | return !a.Equals (b); 119 | } 120 | 121 | public static bool operator < (AppleSdkVersion a, IAppleSdkVersion b) 122 | { 123 | return a.CompareTo (b) < 0; 124 | } 125 | 126 | public static bool operator > (AppleSdkVersion a, IAppleSdkVersion b) 127 | { 128 | return a.CompareTo (b) > 0; 129 | } 130 | 131 | public static bool operator <= (AppleSdkVersion a, IAppleSdkVersion b) 132 | { 133 | return a.CompareTo (b) <= 0; 134 | } 135 | 136 | public static bool operator >= (AppleSdkVersion a, IAppleSdkVersion b) 137 | { 138 | return a.CompareTo (b) >= 0; 139 | } 140 | 141 | public bool IsUseDefault { 142 | get { return version == null || version.Length == 0; } 143 | } 144 | 145 | IAppleSdkVersion IAppleSdkVersion.GetUseDefault () 146 | { 147 | return UseDefault; 148 | } 149 | 150 | #if !WINDOWS 151 | public AppleSdkVersion ResolveIfDefault (AppleSdk sdk, bool sim) 152 | { 153 | return IsUseDefault ? GetDefault (sdk, sim) : this; 154 | } 155 | 156 | public static AppleSdkVersion GetDefault (AppleSdk sdk, bool sim) 157 | { 158 | var v = sdk.GetInstalledSdkVersions (sim); 159 | return v.Count > 0 ? v [v.Count - 1] : UseDefault; 160 | } 161 | #endif 162 | 163 | public static readonly AppleSdkVersion UseDefault = new AppleSdkVersion (new int [0]); 164 | 165 | public static readonly AppleSdkVersion V1_0 = new AppleSdkVersion (1, 0); 166 | public static readonly AppleSdkVersion V2_0 = new AppleSdkVersion (2, 0); 167 | public static readonly AppleSdkVersion V2_1 = new AppleSdkVersion (2, 1); 168 | public static readonly AppleSdkVersion V2_2 = new AppleSdkVersion (2, 2); 169 | public static readonly AppleSdkVersion V3_0 = new AppleSdkVersion (3, 0); 170 | public static readonly AppleSdkVersion V3_1 = new AppleSdkVersion (3, 1); 171 | public static readonly AppleSdkVersion V3_2 = new AppleSdkVersion (3, 2); 172 | public static readonly AppleSdkVersion V3_99 = new AppleSdkVersion (3, 99); 173 | public static readonly AppleSdkVersion V4_0 = new AppleSdkVersion (4, 0); 174 | public static readonly AppleSdkVersion V4_1 = new AppleSdkVersion (4, 1); 175 | public static readonly AppleSdkVersion V4_2 = new AppleSdkVersion (4, 2); 176 | public static readonly AppleSdkVersion V4_3 = new AppleSdkVersion (4, 3); 177 | public static readonly AppleSdkVersion V5_0 = new AppleSdkVersion (5, 0); 178 | public static readonly AppleSdkVersion V5_1 = new AppleSdkVersion (5, 1); 179 | public static readonly AppleSdkVersion V5_1_1 = new AppleSdkVersion (5, 1, 1); 180 | public static readonly AppleSdkVersion V5_2 = new AppleSdkVersion (5, 2); 181 | public static readonly AppleSdkVersion V6_0 = new AppleSdkVersion (6, 0); 182 | public static readonly AppleSdkVersion V6_1 = new AppleSdkVersion (6, 1); 183 | public static readonly AppleSdkVersion V6_2 = new AppleSdkVersion (6, 2); 184 | public static readonly AppleSdkVersion V7_0 = new AppleSdkVersion (7, 0); 185 | public static readonly AppleSdkVersion V7_1 = new AppleSdkVersion (7, 1); 186 | public static readonly AppleSdkVersion V7_2_1 = new AppleSdkVersion (7, 2, 1); 187 | public static readonly AppleSdkVersion V8_0 = new AppleSdkVersion (8, 0); 188 | public static readonly AppleSdkVersion V8_1 = new AppleSdkVersion (8, 1); 189 | public static readonly AppleSdkVersion V8_2 = new AppleSdkVersion (8, 2); 190 | public static readonly AppleSdkVersion V8_3 = new AppleSdkVersion (8, 3); 191 | public static readonly AppleSdkVersion V8_4 = new AppleSdkVersion (8, 4); 192 | public static readonly AppleSdkVersion V9_0 = new AppleSdkVersion (9, 0); 193 | public static readonly AppleSdkVersion V9_1 = new AppleSdkVersion (9, 1); 194 | public static readonly AppleSdkVersion V9_2 = new AppleSdkVersion (9, 2); 195 | public static readonly AppleSdkVersion V9_3 = new AppleSdkVersion (9, 3); 196 | public static readonly AppleSdkVersion V10_0 = new AppleSdkVersion (10, 0); 197 | public static readonly AppleSdkVersion V10_1 = new AppleSdkVersion (10, 1); 198 | public static readonly AppleSdkVersion V10_2 = new AppleSdkVersion (10, 2); 199 | public static readonly AppleSdkVersion V10_3 = new AppleSdkVersion (10, 3); 200 | public static readonly AppleSdkVersion V10_4 = new AppleSdkVersion (10, 4); 201 | public static readonly AppleSdkVersion V10_5 = new AppleSdkVersion (10, 5); 202 | public static readonly AppleSdkVersion V10_6 = new AppleSdkVersion (10, 6); 203 | public static readonly AppleSdkVersion V10_7 = new AppleSdkVersion (10, 7); 204 | public static readonly AppleSdkVersion V10_8 = new AppleSdkVersion (10, 8); 205 | public static readonly AppleSdkVersion V10_9 = new AppleSdkVersion (10, 9); 206 | public static readonly AppleSdkVersion V10_10 = new AppleSdkVersion (10, 10); 207 | public static readonly AppleSdkVersion V10_11 = new AppleSdkVersion (10, 11); 208 | public static readonly AppleSdkVersion V10_12 = new AppleSdkVersion (10, 12); 209 | public static readonly AppleSdkVersion V10_13 = new AppleSdkVersion (10, 13); 210 | public static readonly AppleSdkVersion V10_14 = new AppleSdkVersion (10, 14); 211 | public static readonly AppleSdkVersion V10_15 = new AppleSdkVersion (10, 15); 212 | public static readonly AppleSdkVersion V11_0 = new AppleSdkVersion (11, 0); 213 | } 214 | } 215 | -------------------------------------------------------------------------------- /Xamarin.MacDev/AppleTVOSSdk.cs: -------------------------------------------------------------------------------- 1 | // 2 | // AppleTVOSSdk.cs 3 | // 4 | // Authors: Michael Hutchinson 5 | // Jeffrey Stedfast 6 | // Rolf Bjarne Kvinge 7 | // 8 | // Copyright (c) 2011-2013, 2015 Xamarin Inc. 9 | // 10 | // Permission is hereby granted, free of charge, to any person obtaining a copy 11 | // of this software and associated documentation files (the "Software"), to deal 12 | // in the Software without restriction, including without limitation the rights 13 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 14 | // copies of the Software, and to permit persons to whom the Software is 15 | // furnished to do so, subject to the following conditions: 16 | // 17 | // The above copyright notice and this permission notice shall be included in 18 | // all copies or substantial portions of the Software. 19 | // 20 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 21 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 22 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 23 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 24 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 25 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 26 | // THE SOFTWARE. 27 | 28 | namespace Xamarin.MacDev { 29 | public class AppleTVOSSdk : AppleSdk { 30 | protected override string SimulatorPlatformName { 31 | get { 32 | return "AppleTVSimulator"; 33 | } 34 | } 35 | 36 | protected override string DevicePlatformName { 37 | get { 38 | return "AppleTVOS"; 39 | } 40 | } 41 | 42 | public AppleTVOSSdk (string sdkRoot, string versionPlist) 43 | { 44 | DeveloperRoot = sdkRoot; 45 | VersionPlist = versionPlist; 46 | Init (); 47 | } 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /Xamarin.MacDev/AppleWatchSdk.cs: -------------------------------------------------------------------------------- 1 | // 2 | // AppleIPhoneSdk.cs 3 | // 4 | // Authors: Michael Hutchinson 5 | // Jeffrey Stedfast 6 | // 7 | // Copyright (c) 2011-2013 Xamarin Inc. 8 | // 9 | // Permission is hereby granted, free of charge, to any person obtaining a copy 10 | // of this software and associated documentation files (the "Software"), to deal 11 | // in the Software without restriction, including without limitation the rights 12 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 13 | // copies of the Software, and to permit persons to whom the Software is 14 | // furnished to do so, subject to the following conditions: 15 | // 16 | // The above copyright notice and this permission notice shall be included in 17 | // all copies or substantial portions of the Software. 18 | // 19 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 20 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 21 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 22 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 23 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 24 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 25 | // THE SOFTWARE. 26 | 27 | namespace Xamarin.MacDev { 28 | public class AppleWatchSdk : AppleSdk { 29 | protected override string SimulatorPlatformName { 30 | get { 31 | return "WatchSimulator"; 32 | } 33 | } 34 | 35 | protected override string DevicePlatformName { 36 | get { 37 | return "WatchOS"; 38 | } 39 | } 40 | 41 | public AppleWatchSdk (string sdkRoot, string versionPlist) 42 | { 43 | DeveloperRoot = sdkRoot; 44 | VersionPlist = versionPlist; 45 | Init (); 46 | } 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /Xamarin.MacDev/EntitlementExtensions.cs: -------------------------------------------------------------------------------- 1 | // 2 | // EntitlementExtensions.cs 3 | // 4 | // Author: Jeffrey Stedfast 5 | // 6 | // Copyright (c) 2016 Xamarin Inc. (www.xamarin.com) 7 | // 8 | 9 | using System.Collections.Generic; 10 | using System.Linq; 11 | using System.Reflection; 12 | 13 | namespace Xamarin.MacDev { 14 | public static class EntitlementKeys { 15 | public const string SystemExtension = "com.apple.developer.system-extension.install"; 16 | public const string UserManagement = "com.apple.developer.user-management"; 17 | public const string Fonts = "com.apple.developer.user-fonts"; 18 | public const string AccessWiFiInfo = "com.apple.developer.networking.wifi-info"; 19 | public const string SignInWithApple = "com.apple.developer.applesignin"; 20 | public const string ClassKit = "com.apple.developer.ClassKit-environment"; 21 | public const string DataProtection = "com.apple.developer.default-data-protection"; 22 | public const string WirelessAccessoryConfiguration = "com.apple.external-accessory.wireless-configuration"; 23 | public const string UbiquityKeyValueStore = "com.apple.developer.ubiquity-kvstore-identifier"; 24 | public const string UbiquityContainers = "com.apple.developer.ubiquity-container-identifiers"; 25 | public const string iCloudContainers = "com.apple.developer.icloud-container-identifiers"; 26 | public const string iCloudServices = "com.apple.developer.icloud-services"; 27 | public const string PassBookIdentifiers = "com.apple.developer.pass-type-identifiers"; 28 | public const string AssociatedDomains = "com.apple.developer.associated-domains"; 29 | public const string ApplicationGroups = "com.apple.security.application-groups"; 30 | public const string NetworkingVpnApi = "com.apple.developer.networking.vpn.api"; 31 | public const string NetworkExtensions = "com.apple.developer.networking.networkextension"; 32 | public const string NFC = "com.apple.developer.nfc.readersession.formats"; 33 | public const string HotspotConfiguration = "com.apple.developer.networking.HotspotConfiguration"; 34 | public const string Multipath = "com.apple.developer.networking.multipath"; 35 | public const string InAppPayments = "com.apple.developer.in-app-payments"; 36 | public const string KeychainAccessGroups = "keychain-access-groups"; 37 | public const string HealthKit = "com.apple.developer.healthkit"; 38 | public const string HomeKit = "com.apple.developer.homekit"; 39 | public const string InterAppAudio = "inter-app-audio"; 40 | public const string AutoFillCredentialProvider = "com.apple.developer.authentication-services.autofill-credential-provider"; 41 | public const string GetTaskAllow = "get-task-allow"; 42 | public const string Siri = "com.apple.developer.siri"; 43 | public const string APS = "aps-environment"; 44 | 45 | public const string AllowExecutionOfJitCode = "com.apple.security.cs.allow-jit"; 46 | public const string AllowUnsignedExecutableMemory = "com.apple.security.cs.allow-unsigned-executable-memory"; 47 | public const string AllowDYLDEnvironmentVariable = "com.apple.security.cs.allow-dyld-environment-variables"; 48 | public const string DisableLibraryValidation = "com.apple.security.cs.disable-library-validation"; 49 | public const string DisableExecutableMemoryProtection = "com.apple.security.cs.disable-executable-page-protection"; 50 | public const string DebuggingTool = "com.apple.security.cs.debugger"; 51 | 52 | public const string AudioInput = "com.apple.security.device.audio-input"; 53 | public const string Camera = "com.apple.security.device.camera"; 54 | public const string Location = "com.apple.security.personal-information.location"; 55 | public const string AddressBook = "com.apple.security.personal-information.addressbook"; 56 | public const string Calendar = "com.apple.security.personal-information.calendars"; 57 | public const string PhotosLibrary = "com.apple.security.personal-information.photos-library"; 58 | public const string AppleEvents = "com.apple.security.automation.apple-events"; 59 | 60 | public const string AppAttest = "com.apple.developer.devicecheck.appattest-environment"; 61 | public const string CommunicatesWithDrivers = "com.apple.developer.driverkit.communicates-with-drivers"; 62 | public const string CommunicationNotifications = "com.apple.developer.usernotifications.communication"; 63 | public const string CustomNetworkProtocol = "com.apple.developer.networking.custom-protocol"; 64 | public const string ExtendedVirtualAddressing = "com.apple.developer.kernel.extended-virtual-addressing"; 65 | public const string FamilyControls = "com.apple.developer.family-controls"; 66 | public const string FileProviderTestingMode = "com.apple.developer.fileprovider.testing-mode"; 67 | public const string GameCenter = "com.apple.developer.game-center"; 68 | public const string GameControllers = "GCSupportedGameControllers"; 69 | public const string GroupActivities = "com.apple.developer.group-session"; 70 | public const string IncreasedMemoryLimit = "com.apple.developer.kernel.increased-memory-limit"; 71 | public const string MDMManagedAssociatedDomains = "com.apple.developer.associated-domains.mdm-managed"; 72 | public const string PushToTalk = "com.apple.developer.push-to-talk"; 73 | public const string SharedWithYou = "com.apple.developer.shared-with-you"; 74 | public const string TimeSensitiveNotifications = "com.apple.developer.usernotifications.time-sensitive"; 75 | public const string WeatherKit = "com.apple.developer.weatherkit"; 76 | 77 | static string [] allKeys; 78 | 79 | public static string [] AllKeys { 80 | get { 81 | if (allKeys == null) { 82 | allKeys = typeof (EntitlementKeys).GetFields (BindingFlags.Public | BindingFlags.Static). 83 | Where (f => f.FieldType == typeof (string)). 84 | Select (field => (string) field.GetValue (null)). 85 | ToArray (); 86 | } 87 | 88 | return allKeys; 89 | } 90 | } 91 | } 92 | 93 | public static class EntitlementExtensions { 94 | public static PArray GetApplePayMerchants (this PDictionary dict) 95 | { 96 | return dict.Get (EntitlementKeys.InAppPayments); 97 | } 98 | 99 | public static void SetApplePayMerchants (this PDictionary dict, PArray value) 100 | { 101 | if (value == null) 102 | dict.Remove (EntitlementKeys.InAppPayments); 103 | else 104 | dict [EntitlementKeys.InAppPayments] = value; 105 | } 106 | 107 | public static PArray GetApplicationGroups (this PDictionary dict) 108 | { 109 | return dict.Get (EntitlementKeys.ApplicationGroups); 110 | } 111 | 112 | public static void SetApplicationGroups (this PDictionary dict, PArray value) 113 | { 114 | if (value == null) 115 | dict.Remove (EntitlementKeys.ApplicationGroups); 116 | else 117 | dict [EntitlementKeys.ApplicationGroups] = value; 118 | } 119 | 120 | public static PArray GetAssociatedDomains (this PDictionary dict) 121 | { 122 | return dict.Get (EntitlementKeys.AssociatedDomains); 123 | } 124 | 125 | public static void SetAssociatedDomains (this PDictionary dict, PArray value) 126 | { 127 | if (value == null) 128 | dict.Remove (EntitlementKeys.AssociatedDomains); 129 | else 130 | dict [EntitlementKeys.AssociatedDomains] = value; 131 | } 132 | 133 | public static PArray GetiCloudContainers (this PDictionary dict) 134 | { 135 | return dict.Get (EntitlementKeys.iCloudContainers); 136 | } 137 | 138 | public static void SetiCloudContainers (this PDictionary dict, PArray value) 139 | { 140 | if (value == null) 141 | dict.Remove (EntitlementKeys.iCloudContainers); 142 | else 143 | dict [EntitlementKeys.iCloudContainers] = value; 144 | } 145 | 146 | public static string GetUbiquityKeyValueStore (this PDictionary dict) 147 | { 148 | var str = dict.Get (EntitlementKeys.UbiquityKeyValueStore); 149 | return str == null ? null : str.Value; 150 | } 151 | 152 | public static void SetUbiquityKeyValueStore (this PDictionary dict, string value) 153 | { 154 | if (string.IsNullOrEmpty (value)) 155 | dict.Remove (EntitlementKeys.UbiquityKeyValueStore); 156 | else 157 | dict [EntitlementKeys.UbiquityKeyValueStore] = value; 158 | } 159 | 160 | public static PArray GetiCloudServices (this PDictionary dict) 161 | { 162 | return dict.Get (EntitlementKeys.iCloudServices); 163 | } 164 | 165 | public static void SetiCloudServices (this PDictionary dict, PArray value) 166 | { 167 | if (value == null) 168 | dict.Remove (EntitlementKeys.iCloudServices); 169 | else 170 | dict [EntitlementKeys.iCloudServices] = value; 171 | } 172 | 173 | public static PArray GetKeychainAccessGroups (this PDictionary dict) 174 | { 175 | return dict.Get (EntitlementKeys.KeychainAccessGroups); 176 | } 177 | 178 | public static void SetKeychainAccessGroups (this PDictionary dict, PArray value) 179 | { 180 | if (value == null) 181 | dict.Remove (EntitlementKeys.KeychainAccessGroups); 182 | else 183 | dict [EntitlementKeys.KeychainAccessGroups] = value; 184 | } 185 | 186 | public static PArray GetPassBookIdentifiers (this PDictionary dict) 187 | { 188 | return dict.Get (EntitlementKeys.PassBookIdentifiers); 189 | } 190 | 191 | public static void SetPassBookIdentifiers (this PDictionary dict, PArray value) 192 | { 193 | if (value == null) 194 | dict.Remove (EntitlementKeys.PassBookIdentifiers); 195 | else 196 | dict [EntitlementKeys.PassBookIdentifiers] = value; 197 | } 198 | 199 | public static List GetEntitlementKeys (this PDictionary dict) 200 | { 201 | var enabledEntitlements = new List (); 202 | var keys = EntitlementKeys.AllKeys; 203 | 204 | for (int i = 0; i < keys.Length; i++) { 205 | if (dict.ContainsKey (keys [i])) 206 | enabledEntitlements.Add (keys [i]); 207 | } 208 | 209 | return enabledEntitlements; 210 | } 211 | } 212 | } 213 | -------------------------------------------------------------------------------- /Xamarin.MacDev/ExtendedVersion.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.IO; 3 | 4 | namespace Xamarin.MacDev { 5 | public class ExtendedVersion { 6 | public Version Version { get; set; } 7 | public string Hash { get; set; } 8 | public string Branch { get; set; } 9 | public string BuildDate { get; set; } 10 | 11 | public static ExtendedVersion Read (string file) 12 | { 13 | if (!File.Exists (file)) 14 | return null; 15 | 16 | var rv = new ExtendedVersion (); 17 | foreach (var line in File.ReadAllLines (file)) { 18 | var colon = line.IndexOf (':'); 19 | if (colon == -1) 20 | continue; 21 | var name = line.Substring (0, colon); 22 | var value = line.Substring (colon + 2); 23 | 24 | switch (name) { 25 | case "Version": 26 | Version ev; 27 | if (Version.TryParse (value, out ev)) 28 | rv.Version = ev; 29 | break; 30 | case "Hash": 31 | rv.Hash = value; 32 | break; 33 | case "Branch": 34 | rv.Branch = value; 35 | break; 36 | case "Build date": 37 | rv.BuildDate = value; 38 | break; 39 | } 40 | } 41 | return rv; 42 | } 43 | } 44 | } 45 | 46 | -------------------------------------------------------------------------------- /Xamarin.MacDev/HttpMessageHandler.cs: -------------------------------------------------------------------------------- 1 | // 2 | // HttpMessageHandler.cs 3 | // 4 | // Author: Vincent Dondain 5 | // 6 | // Copyright (c) 2015 Xamarin Inc. (www.xamarin.com) 7 | // 8 | 9 | using System; 10 | 11 | namespace Xamarin.MacDev { 12 | [Flags] 13 | public enum HttpMessageHandler { 14 | HttpClientHandler, 15 | CFNetworkHandler, 16 | NSUrlSessionHandler 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /Xamarin.MacDev/IAppleSdk.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | 4 | namespace Xamarin.MacDev { 5 | public interface IAppleSdk { 6 | bool IsInstalled { get; } 7 | string DeveloperRoot { get; } 8 | string GetPlatformPath (bool isSimulator); 9 | string GetSdkPath (string version, bool isSimulator); 10 | string GetSdkPath (bool isSimulator); 11 | string GetSdkPath (string version); 12 | string GetSdkPath (); 13 | bool SdkIsInstalled (IAppleSdkVersion version, bool isSimulator); 14 | bool TryParseSdkVersion (string value, out IAppleSdkVersion version); 15 | IAppleSdkVersion GetClosestInstalledSdk (IAppleSdkVersion version, bool isSimulator); 16 | IList GetInstalledSdkVersions (bool isSimulator); 17 | AppleDTSettings GetAppleDTSettings (); 18 | AppleDTSdkSettings GetSdkSettings (IAppleSdkVersion version, bool isSimulator); 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /Xamarin.MacDev/IAppleSdkVersion.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | namespace Xamarin.MacDev { 3 | public interface IAppleSdkVersion : IEquatable { 4 | bool IsUseDefault { get; } 5 | void SetVersion (int [] version); 6 | IAppleSdkVersion GetUseDefault (); 7 | int [] Version { get; } 8 | } 9 | 10 | public static class IAppleSdkVersion_Extensions { 11 | public static IAppleSdkVersion ResolveIfDefault (this IAppleSdkVersion @this, IAppleSdk sdk, bool sim) 12 | { 13 | return @this.IsUseDefault ? @this.GetDefault (sdk, sim) : @this; 14 | } 15 | 16 | public static IAppleSdkVersion GetDefault (this IAppleSdkVersion @this, IAppleSdk sdk, bool sim) 17 | { 18 | var v = sdk.GetInstalledSdkVersions (sim); 19 | return v.Count > 0 ? v [v.Count - 1] : @this.GetUseDefault (); 20 | } 21 | 22 | public static bool TryParse (string s, out int [] result) 23 | { 24 | if (s == null) { 25 | result = null; 26 | return false; 27 | } 28 | 29 | var vstr = s.Split ('.'); 30 | result = new int [vstr.Length]; 31 | 32 | for (int j = 0; j < vstr.Length; j++) { 33 | int component; 34 | if (!int.TryParse (vstr [j], out component)) 35 | return false; 36 | 37 | result [j] = component; 38 | } 39 | 40 | return true; 41 | } 42 | 43 | public static bool TryParse (string s, out T result) where T : IAppleSdkVersion, new() 44 | { 45 | result = new T (); 46 | if (s == null) 47 | return false; 48 | 49 | if (!TryParse (s, out var vint)) 50 | return false; 51 | 52 | result.SetVersion (vint); 53 | return true; 54 | } 55 | 56 | public static bool TryParse (string s, out IAppleSdkVersion result) where T : IAppleSdkVersion, new() 57 | { 58 | var rv = TryParse (s, out T tmp); 59 | result = tmp; 60 | return rv; 61 | } 62 | 63 | public static T Parse (string s) where T : IAppleSdkVersion, new() 64 | { 65 | var vstr = s.Split ('.'); 66 | var vint = new int [vstr.Length]; 67 | for (int j = 0; j < vstr.Length; j++) 68 | vint [j] = int.Parse (vstr [j]); 69 | var rv = new T (); 70 | rv.SetVersion (vint); 71 | return rv; 72 | } 73 | 74 | public static bool Equals (IAppleSdkVersion a, IAppleSdkVersion b) 75 | { 76 | if ((object) a == (object) b) 77 | return true; 78 | 79 | if (a != null ^ b != null) 80 | return false; 81 | 82 | var x = a.Version; 83 | var y = b.Version; 84 | if (x == null || y == null || x.Length != y.Length) 85 | return false; 86 | 87 | for (int i = 0; i < x.Length; i++) 88 | if (x [i] != y [i]) 89 | return false; 90 | 91 | return true; 92 | } 93 | 94 | public static bool Equals (IAppleSdkVersion @this, object other) 95 | { 96 | if (other is IAppleSdkVersion obj) 97 | return Equals (@this, obj); 98 | return false; 99 | } 100 | 101 | public static int CompareTo (IAppleSdkVersion @this, IAppleSdkVersion other) 102 | { 103 | var x = @this.Version; 104 | var y = other.Version; 105 | if (ReferenceEquals (x, y)) 106 | return 0; 107 | 108 | if (x == null) 109 | return -1; 110 | if (y == null) 111 | return 1; 112 | 113 | for (int i = 0; i < Math.Min (x.Length, y.Length); i++) { 114 | int res = x [i] - y [i]; 115 | if (res != 0) 116 | return res; 117 | } 118 | return x.Length - y.Length; 119 | } 120 | 121 | public static string ToString (IAppleSdkVersion @this) 122 | { 123 | if (@this.IsUseDefault) 124 | return ""; 125 | 126 | var version = @this.Version; 127 | var v = new string [version.Length]; 128 | for (int i = 0; i < v.Length; i++) 129 | v [i] = version [i].ToString (); 130 | 131 | return string.Join (".", v); 132 | } 133 | 134 | public static int GetHashCode (IAppleSdkVersion @this) 135 | { 136 | unchecked { 137 | var x = @this.Version; 138 | int acc = 0; 139 | for (int i = 0; i < x.Length; i++) 140 | acc ^= x [i] << i; 141 | return acc; 142 | } 143 | } 144 | } 145 | } 146 | -------------------------------------------------------------------------------- /Xamarin.MacDev/IMonoMacSdk.cs: -------------------------------------------------------------------------------- 1 | namespace Xamarin.MacDev { 2 | public interface IMonoMacSdk { 3 | string LegacyFrameworkAssembly { get; } 4 | string LegacyAppLauncherPath { get; } 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /Xamarin.MacDev/IPhoneArchitecture.cs: -------------------------------------------------------------------------------- 1 | // 2 | // IPhoneArchitecture.cs 3 | // 4 | // Author: Jeffrey Stedfast 5 | // 6 | // Copyright (c) 2015 Xamarin Inc. (www.xamarin.com) 7 | // 8 | 9 | using System; 10 | 11 | namespace Xamarin.MacDev { 12 | [Flags] 13 | public enum IPhoneArchitecture { 14 | Default = 0, 15 | 16 | i386 = 1, 17 | x86_64 = 2, 18 | 19 | ARMv6 = 4, 20 | ARMv7 = 8, 21 | ARMv7s = 16, 22 | ARMv7k = 32, 23 | ARM64 = 64, 24 | ARM64_32 = 128, 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /Xamarin.MacDev/IPhoneCertificate.cs: -------------------------------------------------------------------------------- 1 | // 2 | // IPhoneCertificate.cs 3 | // 4 | // Author: Jeffrey Stedfast 5 | // 6 | // Copyright (c) 2014 Xamarin Inc. (www.xamarin.com) 7 | // 8 | 9 | using System; 10 | using System.Security.Cryptography.X509Certificates; 11 | 12 | namespace Xamarin.MacDev { 13 | public static class IPhoneCertificate { 14 | public static readonly string [] DevelopmentPrefixes = { "iPhone Developer", "iOS Development", "Apple Development" }; 15 | public static readonly string [] DistributionPrefixes = { "iPhone Distribution", "iOS Distribution", "Apple Distribution" }; 16 | 17 | public static bool IsDevelopment (string name) 18 | { 19 | foreach (var prefix in DevelopmentPrefixes) { 20 | if (name.StartsWith (prefix, StringComparison.Ordinal)) 21 | return true; 22 | } 23 | 24 | return false; 25 | } 26 | 27 | public static bool IsDevelopment (X509Certificate2 cert) 28 | { 29 | return IsDevelopment (Keychain.GetCertificateCommonName (cert)); 30 | } 31 | 32 | public static bool IsDistribution (string name) 33 | { 34 | foreach (var prefix in DistributionPrefixes) { 35 | if (name.StartsWith (prefix, StringComparison.Ordinal)) 36 | return true; 37 | } 38 | 39 | return false; 40 | } 41 | 42 | public static bool IsDistribution (X509Certificate2 cert) 43 | { 44 | return IsDistribution (Keychain.GetCertificateCommonName (cert)); 45 | } 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /Xamarin.MacDev/IPhoneDeviceCapabilities.cs: -------------------------------------------------------------------------------- 1 | // 2 | // IPhoneDeviceCapabilities.cs 3 | // 4 | // Author: Jeffrey Stedfast 5 | // 6 | // Copyright (c) 2016 Microsoft Corp. (www.microsoft.com) 7 | // 8 | 9 | using System; 10 | 11 | namespace Xamarin.MacDev { 12 | // https://developer.apple.com/library/content/documentation/DeviceInformation/Reference/iOSDeviceCompatibility/DeviceCompatibilityMatrix/DeviceCompatibilityMatrix.html#//apple_ref/doc/uid/TP40013599-CH17-SW1 13 | 14 | [Flags] 15 | public enum IPhoneDeviceCapabilities { 16 | None = 0, 17 | Accelerometer = 1 << 0, 18 | ARMv6 = 1 << 1, 19 | ARMv7 = 1 << 2, 20 | ARM64 = 1 << 3, 21 | AutoFocusCamera = 1 << 4, 22 | BluetoothLE = 1 << 5, 23 | CameraFlash = 1 << 6, 24 | FrontFacingCamera = 1 << 7, 25 | GameKit = 1 << 8, 26 | GPS = 1 << 9, 27 | Gyroscope = 1 << 10, 28 | HealthKit = 1 << 11, 29 | LocationServices = 1 << 12, 30 | Magnetometer = 1 << 13, 31 | Metal = 1 << 14, 32 | Microphone = 1 << 15, 33 | OpenGLES1 = 1 << 16, 34 | OpenGLES2 = 1 << 17, 35 | OpenGLES3 = 1 << 18, 36 | PeerPeer = 1 << 19, 37 | SMS = 1 << 20, 38 | StillCamera = 1 << 21, 39 | Telephony = 1 << 22, 40 | VideoCamera = 1 << 23, 41 | WatchCompanion = 1 << 24, 42 | WiFi = 1 << 25 43 | } 44 | 45 | public static class IPhoneDeviceCapabilitiesExtensions { 46 | public static IPhoneDeviceCapabilities ToDeviceCapability (this string value) 47 | { 48 | switch (value) { 49 | case "accelerometer": return IPhoneDeviceCapabilities.Accelerometer; 50 | case "armv6": return IPhoneDeviceCapabilities.ARMv6; 51 | case "armv7": return IPhoneDeviceCapabilities.ARMv7; 52 | case "arm64": return IPhoneDeviceCapabilities.ARM64; 53 | case "auto-focus-camera": return IPhoneDeviceCapabilities.AutoFocusCamera; 54 | case "bluetooth-le": return IPhoneDeviceCapabilities.BluetoothLE; 55 | case "camera-flash": return IPhoneDeviceCapabilities.CameraFlash; 56 | case "front-facing-camera": return IPhoneDeviceCapabilities.FrontFacingCamera; 57 | case "gamekit": return IPhoneDeviceCapabilities.GameKit; 58 | case "gps": return IPhoneDeviceCapabilities.GPS; 59 | case "gyroscope": return IPhoneDeviceCapabilities.Gyroscope; 60 | case "healthkit": return IPhoneDeviceCapabilities.HealthKit; 61 | case "location-services": return IPhoneDeviceCapabilities.LocationServices; 62 | case "magnetometer": return IPhoneDeviceCapabilities.Magnetometer; 63 | case "metal": return IPhoneDeviceCapabilities.Metal; 64 | case "microphone": return IPhoneDeviceCapabilities.Microphone; 65 | case "opengles-1": return IPhoneDeviceCapabilities.OpenGLES1; 66 | case "opengles-2": return IPhoneDeviceCapabilities.OpenGLES2; 67 | case "opengles-3": return IPhoneDeviceCapabilities.OpenGLES3; 68 | case "peer-peer": return IPhoneDeviceCapabilities.PeerPeer; 69 | case "sms": return IPhoneDeviceCapabilities.SMS; 70 | case "still-camera": return IPhoneDeviceCapabilities.StillCamera; 71 | case "telephony": return IPhoneDeviceCapabilities.Telephony; 72 | case "video-camera": return IPhoneDeviceCapabilities.VideoCamera; 73 | case "wifi": return IPhoneDeviceCapabilities.WiFi; 74 | default: return IPhoneDeviceCapabilities.None; 75 | } 76 | } 77 | } 78 | } 79 | -------------------------------------------------------------------------------- /Xamarin.MacDev/IPhoneDeviceType.cs: -------------------------------------------------------------------------------- 1 | // 2 | // IPhoneDeviceType.cs 3 | // 4 | // Author: Michael Hutchinson 5 | // 6 | // Copyright (c) 2012 Xamarin Inc. (http://www.xamarin.com) 7 | // 8 | // Permission is hereby granted, free of charge, to any person obtaining a copy 9 | // of this software and associated documentation files (the "Software"), to deal 10 | // in the Software without restriction, including without limitation the rights 11 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 12 | // copies of the Software, and to permit persons to whom the Software is 13 | // furnished to do so, subject to the following conditions: 14 | // 15 | // The above copyright notice and this permission notice shall be included in 16 | // all copies or substantial portions of the Software. 17 | // 18 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 19 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 20 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 21 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 22 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 23 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 24 | // THE SOFTWARE. 25 | 26 | using System; 27 | using System.Collections.Generic; 28 | 29 | namespace Xamarin.MacDev { 30 | [Flags] 31 | public enum IPhoneDeviceType { 32 | NotSet = 0, 33 | // Use different values than AppleDeviceFamily to catch incorrect usage earlier. 34 | IPhone = 1 << 10, 35 | IPad = 1 << 11, 36 | IPhoneAndIPad = IPhone | IPad, 37 | Watch = 1 << 12, 38 | TV = 1 << 13, 39 | MacCatalystOptimizedForMac = 1 << 14, 40 | } 41 | 42 | public enum AppleDeviceFamily { 43 | IPhone = 1, 44 | IPad = 2, 45 | TV = 3, 46 | Watch = 4, 47 | IPod = 5, 48 | MacCatalystOptimizedForMac = 6, // Not documented, Xcode sets this value when selecting the "Optimize interface for Mac" option. 49 | } 50 | 51 | public static class IPhoneDeviceTypeExtensions { 52 | public static IList ToDeviceFamily (this IPhoneDeviceType type) 53 | { 54 | var rv = new List (); 55 | 56 | if ((type & IPhoneDeviceType.IPhone) == IPhoneDeviceType.IPhone) 57 | rv.Add (AppleDeviceFamily.IPhone); 58 | 59 | if ((type & IPhoneDeviceType.IPad) == IPhoneDeviceType.IPad) 60 | rv.Add (AppleDeviceFamily.IPad); 61 | 62 | if ((type & IPhoneDeviceType.TV) == IPhoneDeviceType.TV) 63 | rv.Add (AppleDeviceFamily.TV); 64 | 65 | if ((type & IPhoneDeviceType.Watch) == IPhoneDeviceType.Watch) 66 | rv.Add (AppleDeviceFamily.Watch); 67 | 68 | if ((type & IPhoneDeviceType.MacCatalystOptimizedForMac) == IPhoneDeviceType.MacCatalystOptimizedForMac) 69 | rv.Add (AppleDeviceFamily.MacCatalystOptimizedForMac); 70 | 71 | return rv; 72 | } 73 | 74 | public static IPhoneDeviceType ToDeviceType (this IEnumerable families) 75 | { 76 | var rv = IPhoneDeviceType.NotSet; 77 | 78 | foreach (var family in families) 79 | rv |= ToDeviceType (family); 80 | 81 | return rv; 82 | } 83 | 84 | public static IPhoneDeviceType ToDeviceType (this AppleDeviceFamily family) 85 | { 86 | switch (family) { 87 | case AppleDeviceFamily.IPhone: 88 | return IPhoneDeviceType.IPhone; 89 | case AppleDeviceFamily.IPad: 90 | return IPhoneDeviceType.IPad; 91 | case AppleDeviceFamily.TV: 92 | return IPhoneDeviceType.TV; 93 | case AppleDeviceFamily.Watch: 94 | return IPhoneDeviceType.Watch; 95 | case AppleDeviceFamily.MacCatalystOptimizedForMac: 96 | return IPhoneDeviceType.MacCatalystOptimizedForMac; 97 | default: 98 | throw new ArgumentOutOfRangeException (string.Format ("Unknown device family: {0}", family)); 99 | } 100 | } 101 | } 102 | } 103 | -------------------------------------------------------------------------------- /Xamarin.MacDev/IPhoneImageSizes.cs: -------------------------------------------------------------------------------- 1 | // 2 | // IPhoneImageSizes.cs 3 | // 4 | // Authors: Michael Hutchinson 5 | // Jeffrey Stedfast 6 | // 7 | // Copyright (c) 2012 Xamarin Inc. (http://xamarin.com) 8 | // 9 | // Permission is hereby granted, free of charge, to any person obtaining a copy 10 | // of this software and associated documentation files (the "Software"), to deal 11 | // in the Software without restriction, including without limitation the rights 12 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 13 | // copies of the Software, and to permit persons to whom the Software is 14 | // furnished to do so, subject to the following conditions: 15 | // 16 | // The above copyright notice and this permission notice shall be included in 17 | // all copies or substantial portions of the Software. 18 | // 19 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 20 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 21 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 22 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 23 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 24 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 25 | // THE SOFTWARE. 26 | 27 | namespace Xamarin.MacDev { 28 | public struct ImageSize { 29 | public static readonly ImageSize Empty = new ImageSize (0, 0); 30 | public readonly int Width, Height; 31 | 32 | public ImageSize (int width, int height) 33 | { 34 | Width = width; 35 | Height = height; 36 | } 37 | 38 | public bool IsEmpty { 39 | get { return ((Width == 0) && (Height == 0)); } 40 | } 41 | 42 | public static bool operator == (ImageSize sz1, ImageSize sz2) 43 | { 44 | return ((sz1.Width == sz2.Width) && (sz1.Height == sz2.Height)); 45 | } 46 | 47 | public static bool operator != (ImageSize sz1, ImageSize sz2) 48 | { 49 | return ((sz1.Width != sz2.Width) || (sz1.Height != sz2.Height)); 50 | } 51 | 52 | public override bool Equals (object obj) 53 | { 54 | if (!(obj is ImageSize)) 55 | return false; 56 | 57 | return (this == (ImageSize) obj); 58 | } 59 | 60 | public override int GetHashCode () 61 | { 62 | return Width ^ Height; 63 | } 64 | 65 | public override string ToString () 66 | { 67 | return string.Format ("{{Width={0}, Height={1}}}", Width, Height); 68 | } 69 | } 70 | 71 | // http://developer.apple.com/library/ios/#qa/qa1686/_index.html 72 | public static class IPhoneImageSizes { 73 | public static readonly ImageSize Icon = new ImageSize (57, 57); 74 | public static readonly ImageSize RetinaIcon = new ImageSize (114, 114); 75 | 76 | public static readonly ImageSize Settings = new ImageSize (29, 29); 77 | public static readonly ImageSize RetinaSettings = new ImageSize (58, 58); 78 | 79 | public static readonly ImageSize Spotlight = new ImageSize (29, 29); 80 | public static readonly ImageSize RetinaSpotlight = new ImageSize (58, 58); 81 | 82 | public static readonly ImageSize Launch = new ImageSize (320, 480); 83 | public static readonly ImageSize LaunchRetina = new ImageSize (640, 960); 84 | public static readonly ImageSize LaunchRetinaTall = new ImageSize (640, 1136); 85 | 86 | public static readonly ImageSize LaunchRetinaHD47 = new ImageSize (750, 1334); 87 | public static readonly ImageSize LaunchRetinaHD55 = new ImageSize (1242, 2208); 88 | public static readonly ImageSize LaunchRetinaHD55Landscape = new ImageSize (2208, 1242); 89 | 90 | public static readonly ImageSize LaunchRetinaX = new ImageSize (1125, 2436); 91 | public static readonly ImageSize LaunchRetinaXLandscape = new ImageSize (2436, 1125); 92 | 93 | public static readonly ImageSize LaunchRetinaXR = new ImageSize (828, 1792); 94 | public static readonly ImageSize LaunchRetinaXRLandscape = new ImageSize (1792, 828); 95 | 96 | public static readonly ImageSize LaunchRetinaXSMax = new ImageSize (1242, 2688); 97 | public static readonly ImageSize LaunchRetinaXSMaxLandscape = new ImageSize (2688, 1242); 98 | } 99 | 100 | public static class IPadImageSizes { 101 | public static readonly ImageSize Icon = new ImageSize (72, 72); 102 | public static readonly ImageSize RetinaIcon = new ImageSize (144, 144); 103 | public static readonly ImageSize Spotlight = new ImageSize (50, 50); 104 | public static readonly ImageSize RetinaSpotlight = new ImageSize (100, 100); 105 | public static readonly ImageSize Settings = new ImageSize (29, 29); 106 | public static readonly ImageSize RetinaSettings = new ImageSize (58, 58); 107 | 108 | public static readonly ImageSize LaunchPortrait = new ImageSize (768, 1004); 109 | public static readonly ImageSize LaunchLandscape = new ImageSize (1024, 748); 110 | public static readonly ImageSize LaunchPortraitFull = new ImageSize (768, 1024); 111 | public static readonly ImageSize LaunchLandscapeFull = new ImageSize (1024, 768); 112 | 113 | public static readonly ImageSize LaunchRetinaPortrait = new ImageSize (1536, 2008); 114 | public static readonly ImageSize LaunchRetinaLandscape = new ImageSize (2048, 1496); 115 | public static readonly ImageSize LaunchRetinaPortraitFull = new ImageSize (1536, 2048); 116 | public static readonly ImageSize LaunchRetinaLandscapeFull = new ImageSize (2048, 1536); 117 | 118 | public static readonly ImageSize ProLaunchRetinaPortraitFull = new ImageSize (2048, 2732); 119 | public static readonly ImageSize ProLaunchRetinaLandscapeFull = new ImageSize (2732, 2048); 120 | } 121 | 122 | public static class IOS7ImageSizes { 123 | public static readonly ImageSize IPhoneRetinaIcon = new ImageSize (120, 120); 124 | public static readonly ImageSize IPadProRetinaIcon = new ImageSize (167, 167); 125 | public static readonly ImageSize IPadRetinaIcon = new ImageSize (152, 152); 126 | public static readonly ImageSize IPadIcon = new ImageSize (76, 76); 127 | 128 | public static readonly ImageSize RetinaSettings = new ImageSize (58, 58); 129 | public static readonly ImageSize Settings = new ImageSize (29, 29); 130 | 131 | public static readonly ImageSize RetinaSpotlight = new ImageSize (80, 80); 132 | public static readonly ImageSize Spotlight = new ImageSize (40, 40); 133 | 134 | public static readonly ImageSize IPhoneRetinaLaunchImage = new ImageSize (640, 960); 135 | public static readonly ImageSize IPhoneRetinaLaunchImageTall = new ImageSize (640, 1136); 136 | public static readonly ImageSize IPhoneRetinaHD47LaunchImage = new ImageSize (750, 1334); 137 | public static readonly ImageSize IPhoneRetinaHD55LaunchImage = new ImageSize (1242, 2208); 138 | public static readonly ImageSize IPhoneRetinaHD55LaunchImageLandscape = new ImageSize (2208, 1242); 139 | 140 | public static readonly ImageSize IPadLaunchImagePortrait = new ImageSize (768, 1024); 141 | public static readonly ImageSize IPadLaunchImageLandscape = new ImageSize (1024, 768); 142 | 143 | public static readonly ImageSize IPadRetinaLaunchImagePortrait = new ImageSize (1536, 2048); 144 | public static readonly ImageSize IPadRetinaLaunchImageLandscape = new ImageSize (2048, 1536); 145 | 146 | public static readonly ImageSize IPadProRetinaLaunchImagePortrait = new ImageSize (2048, 2732); 147 | public static readonly ImageSize IPadProRetinaLaunchImageLandscape = new ImageSize (2732, 2048); 148 | } 149 | 150 | public static class AppleWatchImageSizes { 151 | public static readonly ImageSize NotificationCenter38mm = new ImageSize (44, 44); 152 | public static readonly ImageSize NotificationCenter42mm = new ImageSize (55, 55); 153 | 154 | public static readonly ImageSize CompanionSettings2x = new ImageSize (58, 58); 155 | public static readonly ImageSize CompanionSettings3x = new ImageSize (88, 88); 156 | 157 | public static readonly ImageSize AppLauncher38mm = new ImageSize (80, 80); 158 | public static readonly ImageSize AppLauncher42mm = new ImageSize (88, 88); 159 | 160 | public static readonly ImageSize QuickLook38mm = new ImageSize (172, 172); 161 | public static readonly ImageSize QuickLook42mm = new ImageSize (196, 196); 162 | 163 | public static readonly ImageSize LaunchImage38mm = new ImageSize (272, 340); 164 | public static readonly ImageSize LaunchImage42mm = new ImageSize (312, 390); 165 | } 166 | 167 | public static class AppleTVSizes { 168 | public static readonly ImageSize FullScreenHD = new ImageSize (1920, 1080); 169 | public static readonly ImageSize FullScreen4K = new ImageSize (3840, 2160); 170 | } 171 | 172 | public static class ITunesArtworkSizes { 173 | public static readonly ImageSize Standard = new ImageSize (512, 512); 174 | public static readonly ImageSize Retina = new ImageSize (1024, 1024); 175 | } 176 | } 177 | -------------------------------------------------------------------------------- /Xamarin.MacDev/IPhoneSdkVersion.cs: -------------------------------------------------------------------------------- 1 | // 2 | // IPhoneSdkVersion.cs 3 | // 4 | // Authors: Michael Hutchinson 5 | // Jeffrey Stedfast 6 | // 7 | // Copyright (c) 2010 Novell, Inc. (http://www.novell.com) 8 | // Copyright (c) 2011-2013 Xamarin Inc. (http://www.xamarin.com) 9 | // 10 | // Permission is hereby granted, free of charge, to any person obtaining a copy 11 | // of this software and associated documentation files (the "Software"), to deal 12 | // in the Software without restriction, including without limitation the rights 13 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 14 | // copies of the Software, and to permit persons to whom the Software is 15 | // furnished to do so, subject to the following conditions: 16 | // 17 | // The above copyright notice and this permission notice shall be included in 18 | // all copies or substantial portions of the Software. 19 | // 20 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 21 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 22 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 23 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 24 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 25 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 26 | // THE SOFTWARE. 27 | 28 | using System; 29 | 30 | namespace Xamarin.MacDev { 31 | [Obsolete ("Use 'AppleSdkVersion' instead.")] 32 | public struct IPhoneSdkVersion : IComparable, IEquatable, IAppleSdkVersion { 33 | int [] version; 34 | 35 | public IPhoneSdkVersion (Version version) 36 | { 37 | if (version == null) 38 | throw new ArgumentNullException (); 39 | 40 | if (version.Build != -1) { 41 | this.version = new int [3]; 42 | this.version [2] = version.Build; 43 | } else { 44 | this.version = new int [2]; 45 | } 46 | 47 | this.version [0] = version.Major; 48 | this.version [1] = version.Minor; 49 | } 50 | 51 | public IPhoneSdkVersion (params int [] version) 52 | { 53 | if (version == null) 54 | throw new ArgumentNullException (); 55 | 56 | this.version = version; 57 | } 58 | 59 | void IAppleSdkVersion.SetVersion (int [] version) 60 | { 61 | this.version = version; 62 | } 63 | 64 | public static IPhoneSdkVersion Parse (string s) 65 | { 66 | return IAppleSdkVersion_Extensions.Parse (s); 67 | } 68 | 69 | public static bool TryParse (string s, out IPhoneSdkVersion result) 70 | { 71 | return IAppleSdkVersion_Extensions.TryParse (s, out result); 72 | } 73 | 74 | public int [] Version { get { return version; } } 75 | 76 | public override string ToString () 77 | { 78 | return IAppleSdkVersion_Extensions.ToString (this); 79 | } 80 | 81 | public int CompareTo (IPhoneSdkVersion other) 82 | { 83 | return IAppleSdkVersion_Extensions.CompareTo (this, other); 84 | } 85 | 86 | public bool Equals (IAppleSdkVersion other) 87 | { 88 | return IAppleSdkVersion_Extensions.Equals (this, other); 89 | } 90 | 91 | public bool Equals (IPhoneSdkVersion other) 92 | { 93 | return IAppleSdkVersion_Extensions.Equals (this, other); 94 | } 95 | 96 | public override bool Equals (object obj) 97 | { 98 | return IAppleSdkVersion_Extensions.Equals (this, obj); 99 | } 100 | 101 | public override int GetHashCode () 102 | { 103 | return IAppleSdkVersion_Extensions.GetHashCode (this); 104 | } 105 | 106 | public static bool operator == (IPhoneSdkVersion a, IPhoneSdkVersion b) 107 | { 108 | return a.Equals (b); 109 | } 110 | 111 | public static bool operator != (IPhoneSdkVersion a, IPhoneSdkVersion b) 112 | { 113 | return !a.Equals (b); 114 | } 115 | 116 | public static bool operator < (IPhoneSdkVersion a, IPhoneSdkVersion b) 117 | { 118 | return a.CompareTo (b) < 0; 119 | } 120 | 121 | public static bool operator > (IPhoneSdkVersion a, IPhoneSdkVersion b) 122 | { 123 | return a.CompareTo (b) > 0; 124 | } 125 | 126 | public static bool operator <= (IPhoneSdkVersion a, IPhoneSdkVersion b) 127 | { 128 | return a.CompareTo (b) <= 0; 129 | } 130 | 131 | public static bool operator >= (IPhoneSdkVersion a, IPhoneSdkVersion b) 132 | { 133 | return a.CompareTo (b) >= 0; 134 | } 135 | 136 | public bool IsUseDefault { 137 | get { return version == null || version.Length == 0; } 138 | } 139 | 140 | IAppleSdkVersion IAppleSdkVersion.GetUseDefault () 141 | { 142 | return UseDefault; 143 | } 144 | 145 | #if !WINDOWS 146 | public IAppleSdkVersion ResolveIfDefault (AppleSdk sdk, bool sim) 147 | { 148 | return IsUseDefault ? GetDefault (sdk, sim) : this; 149 | } 150 | 151 | public static IAppleSdkVersion GetDefault (AppleSdk sdk, bool sim) 152 | { 153 | var v = sdk.GetInstalledSdkVersions (sim); 154 | return v.Count > 0 ? v [v.Count - 1] : (IAppleSdkVersion) UseDefault; 155 | } 156 | #endif 157 | 158 | public static readonly IPhoneSdkVersion UseDefault = new IPhoneSdkVersion (new int [0]); 159 | 160 | public static readonly IPhoneSdkVersion V1_0 = new IPhoneSdkVersion (1, 0); 161 | public static readonly IPhoneSdkVersion V2_0 = new IPhoneSdkVersion (2, 0); 162 | public static readonly IPhoneSdkVersion V2_1 = new IPhoneSdkVersion (2, 1); 163 | public static readonly IPhoneSdkVersion V2_2 = new IPhoneSdkVersion (2, 2); 164 | public static readonly IPhoneSdkVersion V3_0 = new IPhoneSdkVersion (3, 0); 165 | public static readonly IPhoneSdkVersion V3_1 = new IPhoneSdkVersion (3, 1); 166 | public static readonly IPhoneSdkVersion V3_2 = new IPhoneSdkVersion (3, 2); 167 | public static readonly IPhoneSdkVersion V3_99 = new IPhoneSdkVersion (3, 99); 168 | public static readonly IPhoneSdkVersion V4_0 = new IPhoneSdkVersion (4, 0); 169 | public static readonly IPhoneSdkVersion V4_1 = new IPhoneSdkVersion (4, 1); 170 | public static readonly IPhoneSdkVersion V4_2 = new IPhoneSdkVersion (4, 2); 171 | public static readonly IPhoneSdkVersion V4_3 = new IPhoneSdkVersion (4, 3); 172 | public static readonly IPhoneSdkVersion V5_0 = new IPhoneSdkVersion (5, 0); 173 | public static readonly IPhoneSdkVersion V5_1 = new IPhoneSdkVersion (5, 1); 174 | public static readonly IPhoneSdkVersion V5_1_1 = new IPhoneSdkVersion (5, 1, 1); 175 | public static readonly IPhoneSdkVersion V5_2 = new IPhoneSdkVersion (5, 2); 176 | public static readonly IPhoneSdkVersion V6_0 = new IPhoneSdkVersion (6, 0); 177 | public static readonly IPhoneSdkVersion V6_1 = new IPhoneSdkVersion (6, 1); 178 | public static readonly IPhoneSdkVersion V6_2 = new IPhoneSdkVersion (6, 2); 179 | public static readonly IPhoneSdkVersion V7_0 = new IPhoneSdkVersion (7, 0); 180 | public static readonly IPhoneSdkVersion V7_1 = new IPhoneSdkVersion (7, 1); 181 | public static readonly IPhoneSdkVersion V7_2_1 = new IPhoneSdkVersion (7, 2, 1); 182 | public static readonly IPhoneSdkVersion V8_0 = new IPhoneSdkVersion (8, 0); 183 | public static readonly IPhoneSdkVersion V8_1 = new IPhoneSdkVersion (8, 1); 184 | public static readonly IPhoneSdkVersion V8_2 = new IPhoneSdkVersion (8, 2); 185 | public static readonly IPhoneSdkVersion V8_3 = new IPhoneSdkVersion (8, 3); 186 | public static readonly IPhoneSdkVersion V8_4 = new IPhoneSdkVersion (8, 4); 187 | public static readonly IPhoneSdkVersion V9_0 = new IPhoneSdkVersion (9, 0); 188 | public static readonly IPhoneSdkVersion V9_1 = new IPhoneSdkVersion (9, 1); 189 | public static readonly IPhoneSdkVersion V9_2 = new IPhoneSdkVersion (9, 2); 190 | public static readonly IPhoneSdkVersion V9_3 = new IPhoneSdkVersion (9, 3); 191 | public static readonly IPhoneSdkVersion V10_0 = new IPhoneSdkVersion (10, 0); 192 | public static readonly IPhoneSdkVersion V10_1 = new IPhoneSdkVersion (10, 1); 193 | public static readonly IPhoneSdkVersion V10_2 = new IPhoneSdkVersion (10, 2); 194 | public static readonly IPhoneSdkVersion V10_3 = new IPhoneSdkVersion (10, 3); 195 | public static readonly IPhoneSdkVersion V10_4 = new IPhoneSdkVersion (10, 4); 196 | public static readonly IPhoneSdkVersion V11_0 = new IPhoneSdkVersion (11, 0); 197 | } 198 | } 199 | -------------------------------------------------------------------------------- /Xamarin.MacDev/LoggingService.cs: -------------------------------------------------------------------------------- 1 | // 2 | // LoggingService.cs 3 | // 4 | // Author: Jeffrey Stedfast 5 | // 6 | // Copyright (c) 2013 Xamarin Inc. 7 | // 8 | // Permission is hereby granted, free of charge, to any person obtaining a copy 9 | // of this software and associated documentation files (the "Software"), to deal 10 | // in the Software without restriction, including without limitation the rights 11 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 12 | // copies of the Software, and to permit persons to whom the Software is 13 | // furnished to do so, subject to the following conditions: 14 | // 15 | // The above copyright notice and this permission notice shall be included in 16 | // all copies or substantial portions of the Software. 17 | // 18 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 19 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 20 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 21 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 22 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 23 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 24 | // THE SOFTWARE. 25 | 26 | using System; 27 | using System.Diagnostics; 28 | 29 | namespace Xamarin.MacDev { 30 | public static class LoggingService { 31 | static ICustomLogger Logger; 32 | 33 | /// 34 | /// Sets the logger backend 35 | /// 36 | public static void SetCustomLogger (ICustomLogger customLogger) 37 | { 38 | Logger = customLogger; 39 | } 40 | 41 | public static void LogError (string messageFormat, params object [] args) 42 | { 43 | LogError (string.Format (messageFormat, args), (Exception) null); 44 | } 45 | 46 | public static void LogError (string message, Exception ex) 47 | { 48 | if (Logger != null) 49 | Logger.LogError (message, ex); 50 | } 51 | 52 | public static void LogWarning (string messageFormat, params object [] args) 53 | { 54 | if (Logger != null) 55 | Logger.LogWarning (messageFormat, args); 56 | } 57 | 58 | public static void LogInfo (string messageFormat, params object [] args) 59 | { 60 | if (Logger != null) 61 | Logger.LogInfo (messageFormat, args); 62 | } 63 | 64 | [Conditional ("DEBUG")] 65 | public static void LogDebug (string messageFormat, params object [] args) 66 | { 67 | if (Logger != null) 68 | Logger.LogDebug (messageFormat, args); 69 | } 70 | } 71 | 72 | public interface ICustomLogger { 73 | void LogError (string message, Exception ex); 74 | void LogWarning (string messageFormat, params object [] args); 75 | void LogInfo (string messageFormat, object [] args); 76 | void LogDebug (string messageFormat, params object [] args); 77 | } 78 | } 79 | -------------------------------------------------------------------------------- /Xamarin.MacDev/MacCatalystSupport.cs: -------------------------------------------------------------------------------- 1 | // 2 | // MacCatalystSupport.cs 3 | // 4 | // Author: Rolf Kvinge 5 | // 6 | // Copyright (c) 2021 Microsoft Corp. 7 | // 8 | // Permission is hereby granted, free of charge, to any person obtaining a copy 9 | // of this software and associated documentation files (the "Software"), to deal 10 | // in the Software without restriction, including without limitation the rights 11 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 12 | // copies of the Software, and to permit persons to whom the Software is 13 | // furnished to do so, subject to the following conditions: 14 | // 15 | // The above copyright notice and this permission notice shall be included in 16 | // all copies or substantial portions of the Software. 17 | // 18 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 19 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 20 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 21 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 22 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 23 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 24 | // THE SOFTWARE. 25 | 26 | #nullable enable 27 | 28 | using System; 29 | using System.Diagnostics.CodeAnalysis; 30 | using System.Collections.Generic; 31 | using System.IO; 32 | 33 | namespace Xamarin.MacDev { 34 | public static class MacCatalystSupport { 35 | // Versions for Mac Catalyst are complicated. In some cases we have to use the 36 | // corresponding iOS version of the SDK, and in some cases we have to use the 37 | // macOS version that iOS version correspond to. In Xcode, when you select the 38 | // deployment target, you select a macOS version in the UI, but the corresponding 39 | // iOS version is written to the project file. This means that there's a mapping 40 | // between the two, and it turns out Apple stores it in the SDKSettings.plist in 41 | // the macOS SDK. Here we provide a method that loads Apple's mapping from the 42 | // SDKSettings.plist. 43 | public static void LoadVersionMaps (string sdkDirectory, out Dictionary map_ios_to_macos, out Dictionary map_macos_to_ios) 44 | { 45 | map_ios_to_macos = new Dictionary (); 46 | map_macos_to_ios = new Dictionary (); 47 | 48 | var fn = Path.Combine (sdkDirectory, "SDKSettings.plist"); 49 | var plist = PDictionary.FromFile (fn); 50 | #if NET 51 | if (plist?.TryGetValue ("VersionMap", out PDictionary? versionMap) == true) { 52 | #else 53 | // Earlier versions of the C# compiler aren't able to understand the syntax above, and complains about "Use of unassigned local variable 'versionMap'", so do something else here. 54 | if (plist!.TryGetValue ("VersionMap", out PDictionary? versionMap)) { 55 | #endif 56 | if (versionMap.TryGetValue ("iOSMac_macOS", out PDictionary? versionMapiOSToMac)) { 57 | foreach (var kvp in versionMapiOSToMac) 58 | map_ios_to_macos [kvp.Key!] = ((PString) kvp.Value).Value; 59 | } 60 | if (versionMap.TryGetValue ("macOS_iOSMac", out PDictionary? versionMapMacToiOS)) { 61 | foreach (var kvp in versionMapMacToiOS) 62 | map_macos_to_ios [kvp.Key!] = ((PString) kvp.Value).Value; 63 | } 64 | } 65 | } 66 | 67 | public static bool TryGetMacOSVersion (string sdkDirectory, Version iOSVersion, [NotNullWhen (true)] out Version? macOSVersion, out ICollection knowniOSVersions) 68 | { 69 | macOSVersion = null; 70 | 71 | if (!TryGetMacOSVersion (sdkDirectory, iOSVersion.ToString (), out var strValue, out knowniOSVersions)) 72 | return false; 73 | 74 | return Version.TryParse (strValue, out macOSVersion); 75 | } 76 | 77 | public static bool TryGetMacOSVersion (string sdkDirectory, string iOSVersion, [NotNullWhen (true)] out string? macOSVersion, out ICollection knowniOSVersions) 78 | { 79 | LoadVersionMaps (sdkDirectory, out var map, out var _); 80 | 81 | knowniOSVersions = map.Keys; 82 | 83 | return map.TryGetValue (iOSVersion.ToString (), out macOSVersion); 84 | } 85 | 86 | public static bool TryGetiOSVersion (string sdkDirectory, Version macOSVersion, [NotNullWhen (true)] out Version? iOSVersion, out ICollection knownMacOSVersions) 87 | { 88 | iOSVersion = null; 89 | 90 | if (!TryGetiOSVersion (sdkDirectory, macOSVersion.ToString (), out var strValue, out knownMacOSVersions)) 91 | return false; 92 | 93 | return Version.TryParse (strValue, out iOSVersion); 94 | } 95 | 96 | public static bool TryGetiOSVersion (string sdkDirectory, string macOSVersion, [NotNullWhen (true)] out string? iOSVersion, out ICollection knownMacOSVersions) 97 | { 98 | LoadVersionMaps (sdkDirectory, out var _, out var map); 99 | 100 | knownMacOSVersions = map.Keys; 101 | 102 | return map.TryGetValue (macOSVersion.ToString (), out iOSVersion); 103 | } 104 | } 105 | } 106 | -------------------------------------------------------------------------------- /Xamarin.MacDev/MacOSXSdk.cs: -------------------------------------------------------------------------------- 1 | // 2 | // MacOSXSdk.cs 3 | // 4 | // Author: Jeffrey Stedfast 5 | // 6 | // Copyright (c) 2012 Xamarin Inc. 7 | // 8 | // Permission is hereby granted, free of charge, to any person obtaining a copy 9 | // of this software and associated documentation files (the "Software"), to deal 10 | // in the Software without restriction, including without limitation the rights 11 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 12 | // copies of the Software, and to permit persons to whom the Software is 13 | // furnished to do so, subject to the following conditions: 14 | // 15 | // The above copyright notice and this permission notice shall be included in 16 | // all copies or substantial portions of the Software. 17 | // 18 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 19 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 20 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 21 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 22 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 23 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 24 | // THE SOFTWARE. 25 | 26 | using System; 27 | using System.Collections.Generic; 28 | using System.IO; 29 | using System.Linq; 30 | 31 | namespace Xamarin.MacDev { 32 | public class MacOSXSdk : IAppleSdk { 33 | List knownOSVersions = new List { 34 | AppleSdkVersion.V10_7, 35 | AppleSdkVersion.V10_8, 36 | AppleSdkVersion.V10_9, 37 | AppleSdkVersion.V10_10, 38 | AppleSdkVersion.V10_11, 39 | AppleSdkVersion.V10_12, 40 | AppleSdkVersion.V10_13, 41 | AppleSdkVersion.V10_14, 42 | }; 43 | 44 | static readonly Dictionary sdkSettingsCache = new Dictionary (); 45 | static DTSettings dtSettings; 46 | 47 | public string DeveloperRoot { get; private set; } 48 | public string VersionPlist { get; private set; } 49 | public string DesktopPlatform { get; private set; } 50 | public string SdkDeveloperRoot { get; private set; } 51 | 52 | const string PLATFORM_VERSION_PLIST = "version.plist"; 53 | const string SYSTEM_VERSION_PLIST = "/System/Library/CoreServices/SystemVersion.plist"; 54 | 55 | public MacOSXSdk (string developerRoot, string versionPlist) 56 | { 57 | var platformDir = Path.Combine (developerRoot, "Platforms", "MacOSX.platform"); 58 | var sdkDir = Path.Combine (platformDir, "Developer", "SDKs"); 59 | 60 | if (Directory.Exists (sdkDir)) 61 | SdkDeveloperRoot = Path.Combine (platformDir, "Developer"); 62 | else 63 | SdkDeveloperRoot = developerRoot; 64 | 65 | DesktopPlatform = platformDir; 66 | DeveloperRoot = developerRoot; 67 | VersionPlist = versionPlist; 68 | 69 | Init (); 70 | 71 | if (InstalledSdkVersions.Length > 0) { 72 | // Enumerable.Union is there to ensure we add the latest installed sdk to the list (even if it's not in knownOSVersions) 73 | knownOSVersions = knownOSVersions.Where (x => x < InstalledSdkVersions [0]).Union (InstalledSdkVersions).ToList (); 74 | } 75 | } 76 | 77 | void Init () 78 | { 79 | IsInstalled = File.Exists (Path.Combine (DesktopPlatform, "Info.plist")); 80 | if (IsInstalled) { 81 | InstalledSdkVersions = EnumerateSdks (Path.Combine (SdkDeveloperRoot, "SDKs"), "MacOSX"); 82 | } else { 83 | InstalledSdkVersions = new AppleSdkVersion [0]; 84 | } 85 | } 86 | 87 | public bool IsInstalled { get; private set; } 88 | public AppleSdkVersion [] InstalledSdkVersions { get; private set; } 89 | 90 | public IList KnownOSVersions { get { return knownOSVersions; } } 91 | 92 | static AppleSdkVersion [] EnumerateSdks (string sdkDir, string name) 93 | { 94 | if (!Directory.Exists (sdkDir)) 95 | return new AppleSdkVersion [0]; 96 | 97 | var sdks = new List (); 98 | 99 | foreach (var dir in Directory.GetDirectories (sdkDir)) { 100 | string dirName = Path.GetFileName (dir); 101 | if (!dirName.StartsWith (name, StringComparison.Ordinal) || !dirName.EndsWith (".sdk", StringComparison.Ordinal)) 102 | continue; 103 | 104 | if (!File.Exists (Path.Combine (dir, "SDKSettings.plist"))) 105 | continue; 106 | 107 | int verLength = dirName.Length - (name.Length + ".sdk".Length); 108 | if (verLength == 0) 109 | continue; 110 | 111 | dirName = dirName.Substring (name.Length, verLength); 112 | sdks.Add (dirName); 113 | } 114 | 115 | var vs = new List (); 116 | foreach (var s in sdks) { 117 | try { 118 | vs.Add (AppleSdkVersion.Parse (s)); 119 | } catch (Exception ex) { 120 | LoggingService.LogError ("Could not parse {0} SDK version '{1}':\n{2}", name, s, ex); 121 | } 122 | } 123 | 124 | var versions = vs.ToArray (); 125 | Array.Sort (versions); 126 | 127 | return versions; 128 | } 129 | 130 | public string GetPlatformPath () 131 | { 132 | return DesktopPlatform; 133 | } 134 | 135 | string IAppleSdk.GetPlatformPath (bool isSimulator) 136 | { 137 | return GetPlatformPath (); 138 | } 139 | 140 | public string GetSdkPath (AppleSdkVersion version) 141 | { 142 | return GetSdkPath (version.ToString ()); 143 | } 144 | 145 | public string GetSdkPath (string version) 146 | { 147 | return Path.Combine (SdkDeveloperRoot, "SDKs", "MacOSX" + version + ".sdk"); 148 | } 149 | 150 | string IAppleSdk.GetSdkPath (string version, bool isSimulator) 151 | { 152 | return GetSdkPath (version); 153 | } 154 | 155 | public string GetSdkPath (bool isSimulator) 156 | { 157 | return GetSdkPath (string.Empty); 158 | } 159 | 160 | public string GetSdkPath () 161 | { 162 | return GetSdkPath (string.Empty); 163 | } 164 | 165 | string GetSdkPlistFilename (string version) 166 | { 167 | return Path.Combine (GetSdkPath (version), "SDKSettings.plist"); 168 | } 169 | 170 | Dictionary catalyst_version_map_ios_to_macos; 171 | Dictionary catalyst_version_map_macos_to_ios; 172 | 173 | void LoadCatalystVersionMaps (string version) 174 | { 175 | if (catalyst_version_map_ios_to_macos != null && catalyst_version_map_macos_to_ios != null) 176 | return; 177 | 178 | MacCatalystSupport.LoadVersionMaps (GetSdkPath (version), out catalyst_version_map_ios_to_macos, out catalyst_version_map_macos_to_ios); 179 | } 180 | 181 | public Dictionary GetCatalystVersionMap_iOS_to_Mac (string version) 182 | { 183 | LoadCatalystVersionMaps (version); 184 | return catalyst_version_map_ios_to_macos; 185 | } 186 | 187 | public Dictionary GetCatalystVersionMap_Mac_to_iOS (string version) 188 | { 189 | LoadCatalystVersionMaps (version); 190 | return catalyst_version_map_macos_to_ios; 191 | } 192 | 193 | bool IAppleSdk.SdkIsInstalled (IAppleSdkVersion version, bool isSimulator) 194 | { 195 | return SdkIsInstalled ((AppleSdkVersion) version); 196 | } 197 | 198 | public bool SdkIsInstalled (AppleSdkVersion version) 199 | { 200 | foreach (var v in InstalledSdkVersions) { 201 | if (v.Equals (version)) 202 | return true; 203 | } 204 | 205 | return false; 206 | } 207 | 208 | [Obsolete ("Use the 'GetSdkSettings (IAppleSdkVersion)' overload instead.")] 209 | public DTSdkSettings GetSdkSettings (MacOSXSdkVersion sdk) 210 | { 211 | var settings = GetSdkSettings ((IAppleSdkVersion) sdk); 212 | return new DTSdkSettings { 213 | AlternateSDK = settings.AlternateSDK, 214 | CanonicalName = settings.CanonicalName, 215 | DTCompiler = settings.DTCompiler, 216 | DTSDKBuild = settings.DTSDKBuild, 217 | }; 218 | } 219 | 220 | public AppleDTSdkSettings GetSdkSettings (IAppleSdkVersion sdk, bool isSimulator) 221 | { 222 | return GetSdkSettings (sdk); 223 | } 224 | 225 | public AppleDTSdkSettings GetSdkSettings (IAppleSdkVersion sdk) 226 | { 227 | Dictionary cache = sdkSettingsCache; 228 | 229 | if (cache.TryGetValue (sdk.ToString (), out var settings)) 230 | return settings; 231 | 232 | try { 233 | settings = LoadSdkSettings (sdk); 234 | } catch (Exception ex) { 235 | LoggingService.LogError (string.Format ("Error loading settings for SDK MacOSX {0}", sdk), ex); 236 | } 237 | 238 | cache [sdk.ToString ()] = settings; 239 | 240 | return settings; 241 | } 242 | 243 | AppleDTSdkSettings LoadSdkSettings (IAppleSdkVersion sdk) 244 | { 245 | string filename = GetSdkPlistFilename (sdk.ToString ()); 246 | 247 | if (!File.Exists (filename)) 248 | return null; 249 | 250 | var plist = PDictionary.FromFile (filename); 251 | var settings = new AppleDTSdkSettings (); 252 | 253 | settings.CanonicalName = plist.GetString ("CanonicalName").Value; 254 | 255 | var props = plist.Get ("DefaultProperties"); 256 | 257 | PString gcc; 258 | if (!props.TryGetValue ("GCC_VERSION", out gcc)) 259 | settings.DTCompiler = "com.apple.compilers.llvm.clang.1_0"; 260 | else 261 | settings.DTCompiler = gcc.Value; 262 | 263 | var sdkPath = GetSdkPath (sdk.ToString ()); 264 | // Do not do 'Path.Combine (sdkPath, SYSTEM_VERSION_PLIST)', because SYSTEM_VERSION_PLIST starts with a slash, 265 | // and thus Path.Combine wouldn't combine, just return SYSTEM_VERSION_PLIST. 266 | settings.DTSDKBuild = GrabRootString (sdkPath + SYSTEM_VERSION_PLIST, "ProductBuildVersion"); 267 | 268 | return settings; 269 | } 270 | 271 | [Obsolete ("Use GetAppleDTSettings instead")] 272 | public DTSettings GetDTSettings () 273 | { 274 | return GetSettings (); 275 | } 276 | 277 | DTSettings GetSettings () 278 | { 279 | if (dtSettings != null) 280 | return dtSettings; 281 | 282 | var dict = PDictionary.FromFile (Path.Combine (DesktopPlatform, "Info.plist")); 283 | var infos = dict.Get ("AdditionalInfo"); 284 | 285 | return (dtSettings = new DTSettings { 286 | DTPlatformVersion = infos.Get ("DTPlatformVersion").Value, 287 | DTPlatformBuild = GrabRootString (Path.Combine (DesktopPlatform, "version.plist"), "ProductBuildVersion") ?? GrabRootString (VersionPlist, "ProductBuildVersion"), 288 | DTXcodeBuild = GrabRootString (VersionPlist, "ProductBuildVersion"), 289 | BuildMachineOSBuild = GrabRootString (SYSTEM_VERSION_PLIST, "ProductBuildVersion"), 290 | }); 291 | } 292 | 293 | public AppleDTSettings GetAppleDTSettings () 294 | { 295 | var settings = GetSettings (); 296 | return new AppleDTSettings { 297 | DTPlatformBuild = settings.DTPlatformBuild, 298 | DTPlatformVersion = settings.DTPlatformVersion, 299 | BuildMachineOSBuild = settings.BuildMachineOSBuild, 300 | DTXcodeBuild = settings.DTXcodeBuild, 301 | }; 302 | } 303 | 304 | static string GrabRootString (string file, string key) 305 | { 306 | if (!File.Exists (file)) 307 | return null; 308 | 309 | var dict = PDictionary.FromFile (file); 310 | PString value; 311 | 312 | if (dict.TryGetValue (key, out value)) 313 | return value.Value; 314 | 315 | return null; 316 | } 317 | 318 | IAppleSdkVersion IAppleSdk.GetClosestInstalledSdk (IAppleSdkVersion version, bool isSimulator) 319 | { 320 | return GetClosestInstalledSdk ((AppleSdkVersion) version); 321 | } 322 | 323 | public AppleSdkVersion GetClosestInstalledSdk (AppleSdkVersion v) 324 | { 325 | // sorted low to high, so get first that's >= requested version 326 | foreach (var i in GetInstalledSdkVersions ()) { 327 | if (i.CompareTo (v) >= 0) 328 | return i; 329 | } 330 | return AppleSdkVersion.UseDefault; 331 | } 332 | 333 | IList IAppleSdk.GetInstalledSdkVersions (bool isSimulator) 334 | { 335 | return GetInstalledSdkVersions ().Cast ().ToArray (); 336 | } 337 | 338 | public IList GetInstalledSdkVersions () 339 | { 340 | return InstalledSdkVersions; 341 | } 342 | 343 | bool IAppleSdk.TryParseSdkVersion (string value, out IAppleSdkVersion version) 344 | { 345 | return IAppleSdkVersion_Extensions.TryParse (value, out version); 346 | } 347 | 348 | public class DTSettings { 349 | public string DTXcodeBuild { get; set; } 350 | public string DTPlatformVersion { get; set; } 351 | public string DTPlatformBuild { get; set; } 352 | public string BuildMachineOSBuild { get; set; } 353 | } 354 | 355 | public class DTSdkSettings { 356 | public string CanonicalName { get; set; } 357 | public string AlternateSDK { get; set; } 358 | public string DTCompiler { get; set; } 359 | public string DTSDKBuild { get; set; } 360 | } 361 | } 362 | } 363 | -------------------------------------------------------------------------------- /Xamarin.MacDev/MacOSXSdkVersion.cs: -------------------------------------------------------------------------------- 1 | // 2 | // MacOSXSdkVersion.cs 3 | // 4 | // Author: Jeffrey Stedfast 5 | // 6 | // Copyright (c) 2012 Xamarin Inc. 7 | // 8 | // Permission is hereby granted, free of charge, to any person obtaining a copy 9 | // of this software and associated documentation files (the "Software"), to deal 10 | // in the Software without restriction, including without limitation the rights 11 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 12 | // copies of the Software, and to permit persons to whom the Software is 13 | // furnished to do so, subject to the following conditions: 14 | // 15 | // The above copyright notice and this permission notice shall be included in 16 | // all copies or substantial portions of the Software. 17 | // 18 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 19 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 20 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 21 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 22 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 23 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 24 | // THE SOFTWARE. 25 | 26 | using System; 27 | 28 | namespace Xamarin.MacDev { 29 | [Obsolete ("Use 'AppleSdkVersion' instead.")] 30 | public struct MacOSXSdkVersion : IComparable, IEquatable, IAppleSdkVersion { 31 | int [] version; 32 | 33 | public MacOSXSdkVersion (params int [] version) 34 | { 35 | if (version == null) 36 | throw new ArgumentNullException (); 37 | this.version = version; 38 | } 39 | 40 | void IAppleSdkVersion.SetVersion (int [] version) 41 | { 42 | this.version = version; 43 | } 44 | 45 | public MacOSXSdkVersion (Version version) 46 | { 47 | if (version == null) 48 | throw new ArgumentNullException (); 49 | this.version = new [] { version.Major, version.Minor }; 50 | } 51 | 52 | public static MacOSXSdkVersion Parse (string s) 53 | { 54 | return IAppleSdkVersion_Extensions.Parse (s); 55 | } 56 | 57 | public static bool TryParse (string s, out MacOSXSdkVersion result) 58 | { 59 | return IAppleSdkVersion_Extensions.TryParse (s, out result); 60 | } 61 | 62 | public int [] Version { get { return version; } } 63 | 64 | public override string ToString () 65 | { 66 | return IAppleSdkVersion_Extensions.ToString (this); 67 | } 68 | 69 | public int CompareTo (MacOSXSdkVersion other) 70 | { 71 | return IAppleSdkVersion_Extensions.CompareTo (this, other); 72 | } 73 | 74 | public bool Equals (MacOSXSdkVersion other) 75 | { 76 | return IAppleSdkVersion_Extensions.Equals (this, other); 77 | } 78 | 79 | public bool Equals (IAppleSdkVersion other) 80 | { 81 | return IAppleSdkVersion_Extensions.Equals (this, other); 82 | } 83 | 84 | public override bool Equals (object obj) 85 | { 86 | return IAppleSdkVersion_Extensions.Equals (this, obj); 87 | } 88 | 89 | public override int GetHashCode () 90 | { 91 | return IAppleSdkVersion_Extensions.GetHashCode (this); 92 | } 93 | 94 | public static bool operator == (MacOSXSdkVersion a, MacOSXSdkVersion b) 95 | { 96 | return a.Equals (b); 97 | } 98 | 99 | public static bool operator != (MacOSXSdkVersion a, MacOSXSdkVersion b) 100 | { 101 | return !a.Equals (b); 102 | } 103 | 104 | public static bool operator < (MacOSXSdkVersion a, MacOSXSdkVersion b) 105 | { 106 | return a.CompareTo (b) < 0; 107 | } 108 | 109 | public static bool operator > (MacOSXSdkVersion a, MacOSXSdkVersion b) 110 | { 111 | return a.CompareTo (b) > 0; 112 | } 113 | 114 | public static bool operator <= (MacOSXSdkVersion a, MacOSXSdkVersion b) 115 | { 116 | return a.CompareTo (b) <= 0; 117 | } 118 | 119 | public static bool operator >= (MacOSXSdkVersion a, MacOSXSdkVersion b) 120 | { 121 | return a.CompareTo (b) >= 0; 122 | } 123 | 124 | public bool IsUseDefault { 125 | get { 126 | return version == null || version.Length == 0; 127 | } 128 | } 129 | 130 | IAppleSdkVersion IAppleSdkVersion.GetUseDefault () 131 | { 132 | return UseDefault; 133 | } 134 | 135 | public static IAppleSdkVersion GetDefault (IAppleSdk sdk) 136 | { 137 | return GetDefault ((MacOSXSdk) sdk); 138 | } 139 | 140 | public static IAppleSdkVersion GetDefault (MacOSXSdk sdk) 141 | { 142 | var v = sdk.GetInstalledSdkVersions (); 143 | return v.Count > 0 ? v [v.Count - 1] : (IAppleSdkVersion) UseDefault; 144 | } 145 | 146 | public IAppleSdkVersion ResolveIfDefault (MacOSXSdk sdk) 147 | { 148 | return IsUseDefault ? GetDefault (sdk) : this; 149 | } 150 | 151 | public static readonly MacOSXSdkVersion UseDefault = new MacOSXSdkVersion (new int [0]); 152 | 153 | public static readonly MacOSXSdkVersion V10_0 = new MacOSXSdkVersion (10, 0); 154 | public static readonly MacOSXSdkVersion V10_1 = new MacOSXSdkVersion (10, 1); 155 | public static readonly MacOSXSdkVersion V10_2 = new MacOSXSdkVersion (10, 2); 156 | public static readonly MacOSXSdkVersion V10_3 = new MacOSXSdkVersion (10, 3); 157 | public static readonly MacOSXSdkVersion V10_4 = new MacOSXSdkVersion (10, 4); 158 | public static readonly MacOSXSdkVersion V10_5 = new MacOSXSdkVersion (10, 5); 159 | public static readonly MacOSXSdkVersion V10_6 = new MacOSXSdkVersion (10, 6); 160 | public static readonly MacOSXSdkVersion V10_7 = new MacOSXSdkVersion (10, 7); 161 | public static readonly MacOSXSdkVersion V10_8 = new MacOSXSdkVersion (10, 8); 162 | public static readonly MacOSXSdkVersion V10_9 = new MacOSXSdkVersion (10, 9); 163 | public static readonly MacOSXSdkVersion V10_10 = new MacOSXSdkVersion (10, 10); 164 | public static readonly MacOSXSdkVersion V10_11 = new MacOSXSdkVersion (10, 11); 165 | public static readonly MacOSXSdkVersion V10_12 = new MacOSXSdkVersion (10, 12); 166 | public static readonly MacOSXSdkVersion V10_13 = new MacOSXSdkVersion (10, 13); 167 | public static readonly MacOSXSdkVersion V10_14 = new MacOSXSdkVersion (10, 14); 168 | public static readonly MacOSXSdkVersion V10_15 = new MacOSXSdkVersion (10, 15); 169 | 170 | public static readonly MacOSXSdkVersion Cheetah = V10_0; 171 | public static readonly MacOSXSdkVersion Puma = V10_1; 172 | public static readonly MacOSXSdkVersion Jaguar = V10_2; 173 | public static readonly MacOSXSdkVersion Panther = V10_3; 174 | public static readonly MacOSXSdkVersion Tiger = V10_4; 175 | public static readonly MacOSXSdkVersion Leopard = V10_5; 176 | public static readonly MacOSXSdkVersion SnowLeopard = V10_6; 177 | public static readonly MacOSXSdkVersion Lion = V10_7; 178 | public static readonly MacOSXSdkVersion MountainLion = V10_8; 179 | public static readonly MacOSXSdkVersion Mavericks = V10_9; 180 | public static readonly MacOSXSdkVersion Yosemite = V10_10; 181 | public static readonly MacOSXSdkVersion ElCapitan = V10_11; 182 | public static readonly MacOSXSdkVersion Sierra = V10_12; 183 | public static readonly MacOSXSdkVersion HighSierra = V10_13; 184 | public static readonly MacOSXSdkVersion Mojave = V10_14; 185 | public static readonly MacOSXSdkVersion Catalina = V10_15; 186 | 187 | public static string VersionName (MacOSXSdkVersion version) 188 | { 189 | string versionName; 190 | switch (version.ToString ()) { 191 | case "10.0": 192 | versionName = "Cheetah"; 193 | break; 194 | case "10.1": 195 | versionName = "Puma"; 196 | break; 197 | case "10.2": 198 | versionName = "Jaguar"; 199 | break; 200 | case "10.3": 201 | versionName = "Panther"; 202 | break; 203 | case "10.4": 204 | versionName = "Tiger"; 205 | break; 206 | case "10.5": 207 | versionName = "Leopard"; 208 | break; 209 | case "10.6": 210 | versionName = "Snow Leopard"; 211 | break; 212 | case "10.7": 213 | versionName = "Lion"; 214 | break; 215 | case "10.8": 216 | versionName = "Mountain Lion"; 217 | break; 218 | case "10.9": 219 | versionName = "Mavericks"; 220 | break; 221 | case "10.10": 222 | versionName = "Yosemite"; 223 | break; 224 | case "10.11": 225 | versionName = "El Capitan"; 226 | break; 227 | case "10.12": 228 | versionName = "Sierra"; 229 | break; 230 | case "10.13": 231 | versionName = "High Sierra"; 232 | break; 233 | case "10.14": 234 | versionName = "Mojave"; 235 | break; 236 | case "10.15": 237 | versionName = "Catalina"; 238 | break; 239 | default: 240 | versionName = string.Empty; 241 | break; 242 | } 243 | return versionName; 244 | } 245 | } 246 | } 247 | -------------------------------------------------------------------------------- /Xamarin.MacDev/MobileProvision.cs: -------------------------------------------------------------------------------- 1 | // 2 | // MobileProvision.cs 3 | // 4 | // Author: 5 | // Michael Hutchinson 6 | // 7 | // Copyright (c) 2009 Novell, Inc. (http://www.novell.com) 8 | // 9 | // Permission is hereby granted, free of charge, to any person obtaining a copy 10 | // of this software and associated documentation files (the "Software"), to deal 11 | // in the Software without restriction, including without limitation the rights 12 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 13 | // copies of the Software, and to permit persons to whom the Software is 14 | // furnished to do so, subject to the following conditions: 15 | // 16 | // The above copyright notice and this permission notice shall be included in 17 | // all copies or substantial portions of the Software. 18 | // 19 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 20 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 21 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 22 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 23 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 24 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 25 | // THE SOFTWARE. 26 | 27 | using System; 28 | using System.Collections.Generic; 29 | using System.IO; 30 | using System.Linq; 31 | using System.Security.Cryptography.X509Certificates; 32 | 33 | namespace Xamarin.MacDev { 34 | public enum MobileProvisionPlatform { 35 | MacOS, 36 | iOS, 37 | tvOS 38 | } 39 | 40 | [Flags] 41 | public enum MobileProvisionDistributionType { 42 | Any = 0, 43 | Development = 1 << 0, 44 | AdHoc = 1 << 1, 45 | InHouse = 1 << 2, 46 | AppStore = 1 << 3, 47 | } 48 | 49 | public class MobileProvision { 50 | public const string AutomaticAppStore = "Automatic:AppStore"; 51 | public const string AutomaticInHouse = "Automatic:InHouse"; 52 | public const string AutomaticAdHoc = "Automatic:AdHoc"; 53 | public static readonly string [] ProfileDirectories; 54 | 55 | static MobileProvision () 56 | { 57 | if (Environment.OSVersion.Platform == PlatformID.MacOSX 58 | || Environment.OSVersion.Platform == PlatformID.Unix) { 59 | string personal = Environment.GetFolderPath (Environment.SpecialFolder.UserProfile); 60 | 61 | ProfileDirectories = new string [] { 62 | // Xcode >= 16.x uses ~/Library/Developer/Xcode/UserData/Provisioning Profiles 63 | Path.Combine (personal, "Library", "Developer", "Xcode", "UserData", "Provisioning Profiles"), 64 | 65 | // Xcode < 16.x uses ~/Library/MobileDevice/Provisioning Profiles 66 | Path.Combine (personal, "Library", "MobileDevice", "Provisioning Profiles"), 67 | }; 68 | } else { 69 | var appDataLocal = Environment.GetFolderPath (Environment.SpecialFolder.LocalApplicationData); 70 | 71 | ProfileDirectories = new string [] { 72 | Path.Combine (appDataLocal, "maui", "iOS", "Provisioning", "Profiles") 73 | }; 74 | } 75 | } 76 | 77 | public MobileProvisionDistributionType DistributionType { 78 | get { 79 | if (ProvisionedDevices != null) { 80 | PBoolean getTaskAllow; 81 | 82 | // MacOS does not have an AdHoc distribution type 83 | foreach (var platform in Platforms) { 84 | if (platform == MobileProvisionPlatform.MacOS) 85 | return MobileProvisionDistributionType.Development; 86 | } 87 | 88 | if (Entitlements.TryGetValue ("get-task-allow", out getTaskAllow) && getTaskAllow.Value) 89 | return MobileProvisionDistributionType.Development; 90 | 91 | return MobileProvisionDistributionType.AdHoc; 92 | } 93 | 94 | if (ProvisionsAllDevices.HasValue && ProvisionsAllDevices.Value) 95 | return MobileProvisionDistributionType.InHouse; 96 | 97 | return MobileProvisionDistributionType.AppStore; 98 | } 99 | } 100 | 101 | public static string GetFileExtension (MobileProvisionPlatform platform) 102 | { 103 | switch (platform) { 104 | case MobileProvisionPlatform.MacOS: 105 | return ".provisionprofile"; 106 | case MobileProvisionPlatform.tvOS: 107 | case MobileProvisionPlatform.iOS: 108 | default: 109 | return ".mobileprovision"; 110 | } 111 | } 112 | 113 | public static MobileProvision LoadFromFile (string fileName) 114 | { 115 | var data = File.ReadAllBytes (fileName); 116 | var m = new MobileProvision (); 117 | m.Load (PDictionary.FromBinaryXml (data)); 118 | m.Data = data; 119 | 120 | if (m.Platforms == null) { 121 | switch (Path.GetExtension (fileName).ToLowerInvariant ()) { 122 | case ".provisionprofile": 123 | m.Platforms = new MobileProvisionPlatform [1]; 124 | m.Platforms [0] = MobileProvisionPlatform.MacOS; 125 | break; 126 | case ".mobileprovision": 127 | m.Platforms = new MobileProvisionPlatform [1]; 128 | m.Platforms [0] = MobileProvisionPlatform.iOS; 129 | break; 130 | } 131 | } 132 | 133 | LoggingService.LogInfo ($"Loaded provisioning profile from '{fileName}'"); 134 | 135 | return m; 136 | } 137 | 138 | public static MobileProvision LoadFromData (byte [] data) 139 | { 140 | var m = new MobileProvision (); 141 | m.Load (PDictionary.FromBinaryXml (data)); 142 | m.Data = data; 143 | return m; 144 | } 145 | 146 | public static IList GetAllInstalledProvisions (MobileProvisionPlatform platform) 147 | { 148 | return GetAllInstalledProvisions (platform, false); 149 | } 150 | 151 | /// 152 | /// All installed provisioning profiles, sorted by newest first. 153 | /// 154 | public static IList GetAllInstalledProvisions (MobileProvisionPlatform platform, bool includeExpired) 155 | { 156 | var uuids = new Dictionary (); 157 | var list = new List (); 158 | var now = DateTime.Now; 159 | string pattern; 160 | 161 | switch (platform) { 162 | case MobileProvisionPlatform.MacOS: 163 | pattern = "*.provisionprofile"; 164 | break; 165 | case MobileProvisionPlatform.tvOS: 166 | case MobileProvisionPlatform.iOS: 167 | pattern = "*.mobileprovision"; 168 | break; 169 | default: 170 | throw new ArgumentOutOfRangeException (nameof (platform)); 171 | } 172 | 173 | foreach (var profileDir in ProfileDirectories) { 174 | if (!Directory.Exists (profileDir)) 175 | continue; 176 | 177 | foreach (var file in Directory.EnumerateFiles (profileDir, pattern)) { 178 | try { 179 | var data = File.ReadAllBytes (file); 180 | 181 | var m = new MobileProvision (); 182 | m.Load (PDictionary.FromBinaryXml (data)); 183 | m.Data = data; 184 | 185 | if (includeExpired || m.ExpirationDate > now) { 186 | if (uuids.ContainsKey (m.Uuid)) { 187 | // we always want the most recently created/updated provision 188 | if (m.CreationDate > uuids [m.Uuid].CreationDate) { 189 | int index = list.IndexOf (uuids [m.Uuid]); 190 | uuids [m.Uuid] = m; 191 | list [index] = m; 192 | } 193 | } else { 194 | uuids.Add (m.Uuid, m); 195 | list.Add (m); 196 | } 197 | } 198 | } catch (Exception ex) { 199 | LoggingService.LogWarning ("Error reading " + platform + " provision file '" + file + "'", ex); 200 | } 201 | } 202 | } 203 | 204 | // newest first 205 | list.Sort ((x, y) => y.CreationDate.CompareTo (x.CreationDate)); 206 | 207 | return list; 208 | } 209 | 210 | MobileProvision () 211 | { 212 | } 213 | 214 | static IList GetCertificates (PArray array) 215 | { 216 | var list = new List (); 217 | 218 | foreach (var item in array) { 219 | var data = item as PData; 220 | 221 | if (data != null) 222 | list.Add (new X509Certificate2 (data.Value)); 223 | } 224 | 225 | return list; 226 | } 227 | 228 | static IList GetStrings (PArray array) 229 | { 230 | var list = new List (); 231 | 232 | foreach (var item in array) { 233 | var str = item as PString; 234 | 235 | if (str != null) 236 | list.Add (str.Value); 237 | } 238 | 239 | return list; 240 | } 241 | 242 | void Load (PDictionary doc) 243 | { 244 | PArray prefixes; 245 | if (doc.TryGetValue ("ApplicationIdentifierPrefix", out prefixes) && prefixes != null) 246 | ApplicationIdentifierPrefix = GetStrings (prefixes); 247 | 248 | if (doc.TryGetValue ("TeamIdentifier", out prefixes) && prefixes != null) 249 | TeamIdentifierPrefix = GetStrings (prefixes); 250 | 251 | PDate creationDate; 252 | if (doc.TryGetValue ("CreationDate", out creationDate) && creationDate != null) 253 | CreationDate = creationDate.Value; 254 | 255 | PArray devCerts; 256 | if (doc.TryGetValue ("DeveloperCertificates", out devCerts) && devCerts != null) 257 | DeveloperCertificates = GetCertificates (devCerts); 258 | 259 | PDictionary entitlements; 260 | if (doc.TryGetValue ("Entitlements", out entitlements) && entitlements != null) { 261 | // Note: we clone the entitlements so that the runtime can garbage collect the 'doc' dictionary 262 | // (which may be rather huge if it contains a massive list of developer certs, for example) 263 | Entitlements = (PDictionary) entitlements.Clone (); 264 | } 265 | 266 | PDate expirationDate; 267 | if (doc.TryGetValue ("ExpirationDate", out expirationDate) && expirationDate != null) 268 | ExpirationDate = expirationDate.Value; 269 | 270 | PString name; 271 | if (doc.TryGetValue ("Name", out name) && name != null) 272 | Name = name.Value; 273 | 274 | PArray array; 275 | if (doc.TryGetValue ("Platform", out array) && array != null) { 276 | var platforms = new List (); 277 | 278 | foreach (var platform in array.OfType ()) { 279 | switch (platform) { 280 | case "OSX": platforms.Add (MobileProvisionPlatform.MacOS); break; 281 | case "tvOS": platforms.Add (MobileProvisionPlatform.tvOS); break; 282 | case "iOS": platforms.Add (MobileProvisionPlatform.iOS); break; 283 | } 284 | } 285 | 286 | Platforms = platforms.ToArray (); 287 | } 288 | 289 | PArray provDevs; 290 | if (doc.TryGetValue ("ProvisionedDevices", out provDevs) && provDevs != null) 291 | ProvisionedDevices = GetStrings (provDevs); 292 | 293 | PBoolean provisionsAllDevices; 294 | if (doc.TryGetValue ("ProvisionsAllDevices", out provisionsAllDevices) && provisionsAllDevices != null) 295 | ProvisionsAllDevices = provisionsAllDevices.Value; 296 | 297 | PNumber ttl; 298 | if (doc.TryGetValue ("TimeToLive", out ttl) && ttl != null) 299 | TimeToLive = (int) ttl.Value; 300 | 301 | PString uuid; 302 | if (doc.TryGetValue ("UUID", out uuid) && uuid != null) 303 | Uuid = uuid.Value; 304 | 305 | PNumber version; 306 | if (doc.TryGetValue ("Version", out version) && version != null) 307 | Version = (int) version.Value; 308 | } 309 | 310 | public void Save (string path) 311 | { 312 | File.WriteAllBytes (path, Data); 313 | } 314 | 315 | public IList ApplicationIdentifierPrefix { get; private set; } 316 | public IList TeamIdentifierPrefix { get; private set; } 317 | public DateTime CreationDate { get; private set; } 318 | public IList DeveloperCertificates { get; private set; } 319 | public PDictionary Entitlements { get; private set; } 320 | public DateTime ExpirationDate { get; private set; } 321 | public string Name { get; private set; } 322 | public MobileProvisionPlatform [] Platforms { get; private set; } 323 | public IList ProvisionedDevices { get; private set; } 324 | public bool? ProvisionsAllDevices { get; private set; } 325 | public int TimeToLive { get; private set; } 326 | public string Uuid { get; private set; } 327 | public int Version { get; private set; } 328 | public byte [] Data { get; private set; } 329 | 330 | public bool MatchesBundleIdentifier (string bundleIdentifier) 331 | { 332 | PString identifier; 333 | string id; 334 | int dot; 335 | 336 | if (bundleIdentifier == null) 337 | throw new ArgumentNullException (nameof (bundleIdentifier)); 338 | 339 | if (Entitlements.TryGetValue ("com.apple.application-identifier", out identifier)) 340 | id = identifier.Value; 341 | else if (Entitlements.TryGetValue ("application-identifier", out identifier)) 342 | id = identifier.Value; 343 | else 344 | return false; 345 | 346 | // Note: the identifier will be in the form "7V723M9SQ5.com.xamarin.app-name", so we'll need to trim the leading TeamIdentifierPrefix 347 | if ((dot = id.IndexOf ('.')) != -1) 348 | id = id.Substring (dot + 1); 349 | 350 | if (id.Length > 0 && id [id.Length - 1] == '*') { 351 | // Note: this is a wildcard provisioning profile, which means we need to use a substring match 352 | id = id.TrimEnd ('*'); 353 | 354 | if (!bundleIdentifier.StartsWith (id, StringComparison.Ordinal)) 355 | return false; 356 | } else if (id != bundleIdentifier) { 357 | // the CFBundleIdentifier provided by our caller does not match this provisioning profile 358 | return false; 359 | } 360 | 361 | return true; 362 | } 363 | 364 | public bool MatchesDeveloperCertificate (X509Certificate2 certificate) 365 | { 366 | if (certificate == null) 367 | throw new ArgumentNullException (nameof (certificate)); 368 | 369 | for (int i = 0; i < DeveloperCertificates.Count; i++) { 370 | if (DeveloperCertificates [i].Thumbprint == certificate.Thumbprint) 371 | return true; 372 | } 373 | 374 | return false; 375 | } 376 | } 377 | } 378 | -------------------------------------------------------------------------------- /Xamarin.MacDev/MonoMacSdk.cs: -------------------------------------------------------------------------------- 1 | // 2 | // MonoMacSdk.cs 3 | // 4 | // Author: Jeffrey Stedfast 5 | // 6 | // Copyright (c) 2012 Xamarin Inc. 7 | // 8 | // Permission is hereby granted, free of charge, to any person obtaining a copy 9 | // of this software and associated documentation files (the "Software"), to deal 10 | // in the Software without restriction, including without limitation the rights 11 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 12 | // copies of the Software, and to permit persons to whom the Software is 13 | // furnished to do so, subject to the following conditions: 14 | // 15 | // The above copyright notice and this permission notice shall be included in 16 | // all copies or substantial portions of the Software. 17 | // 18 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 19 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 20 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 21 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 22 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 23 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 24 | // THE SOFTWARE. 25 | 26 | using System; 27 | using System.IO; 28 | 29 | namespace Xamarin.MacDev { 30 | public sealed class MonoMacSdk : IMonoMacSdk { 31 | static DateTime lastExeWrite = DateTime.MinValue; 32 | 33 | public string SdkDir { 34 | get; private set; 35 | } 36 | 37 | public string LegacyFrameworkAssembly { 38 | get; private set; 39 | } 40 | 41 | public string LegacyAppLauncherPath { 42 | get; private set; 43 | } 44 | 45 | public MonoMacSdk (string defaultLocation, string legacyFrameworkAssembly, string legacyAppLauncherPath) 46 | { 47 | LegacyFrameworkAssembly = legacyFrameworkAssembly; 48 | LegacyAppLauncherPath = legacyAppLauncherPath; 49 | SdkDir = defaultLocation; 50 | Init (); 51 | } 52 | 53 | void Init () 54 | { 55 | IsInstalled = File.Exists (LegacyFrameworkAssembly); 56 | 57 | if (IsInstalled) { 58 | lastExeWrite = File.GetLastWriteTimeUtc (LegacyFrameworkAssembly); 59 | Version = ReadVersion (); 60 | if (Version.IsUseDefault) 61 | LoggingService.LogInfo ("Found MonoMac."); 62 | else 63 | LoggingService.LogInfo ("Found MonoMac, version {0}.", Version); 64 | } else { 65 | lastExeWrite = DateTime.MinValue; 66 | Version = new AppleSdkVersion (); 67 | LoggingService.LogInfo ("MonoMac not installed. Can't find {0}.", LegacyFrameworkAssembly); 68 | } 69 | } 70 | 71 | AppleSdkVersion ReadVersion () 72 | { 73 | var versionFile = Path.Combine (SdkDir, "Version"); 74 | if (File.Exists (versionFile)) { 75 | try { 76 | return AppleSdkVersion.Parse (File.ReadAllText (versionFile).Trim ()); 77 | } catch (Exception ex) { 78 | LoggingService.LogError ("Failed to read MonoMac version", ex); 79 | } 80 | } 81 | 82 | return new AppleSdkVersion (); 83 | } 84 | 85 | public bool IsInstalled { get; private set; } 86 | public AppleSdkVersion Version { get; private set; } 87 | 88 | public void CheckCaches () 89 | { 90 | DateTime lastWrite = DateTime.MinValue; 91 | try { 92 | lastWrite = File.GetLastWriteTimeUtc (LegacyFrameworkAssembly); 93 | if (lastWrite == lastExeWrite) 94 | return; 95 | } catch (IOException) { 96 | } 97 | 98 | Init (); 99 | } 100 | } 101 | } 102 | -------------------------------------------------------------------------------- /Xamarin.MacDev/MonoTouchSdk.cs: -------------------------------------------------------------------------------- 1 | // 2 | // MonoTouchSdk.cs 3 | // 4 | // Authors: Michael Hutchinson 5 | // Jeffrey Stedfast 6 | // 7 | // Copyright (c) 2011 Xamarin Inc. 8 | // 9 | // Permission is hereby granted, free of charge, to any person obtaining a copy 10 | // of this software and associated documentation files (the "Software"), to deal 11 | // in the Software without restriction, including without limitation the rights 12 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 13 | // copies of the Software, and to permit persons to whom the Software is 14 | // furnished to do so, subject to the following conditions: 15 | // 16 | // The above copyright notice and this permission notice shall be included in 17 | // all copies or substantial portions of the Software. 18 | // 19 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 20 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 21 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 22 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 23 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 24 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 25 | // THE SOFTWARE. 26 | 27 | using System; 28 | using System.Collections.Generic; 29 | using System.IO; 30 | using System.Linq; 31 | 32 | namespace Xamarin.MacDev { 33 | public class MonoTouchSdk { 34 | static readonly AppleSdkVersion [] iOSSdkVersions = { 35 | AppleSdkVersion.V6_0, 36 | AppleSdkVersion.V6_1, 37 | AppleSdkVersion.V7_0, 38 | AppleSdkVersion.V7_1, 39 | AppleSdkVersion.V8_0, 40 | AppleSdkVersion.V8_1, 41 | AppleSdkVersion.V8_2, 42 | AppleSdkVersion.V8_3, 43 | AppleSdkVersion.V8_4, 44 | AppleSdkVersion.V9_0, 45 | AppleSdkVersion.V9_1, 46 | AppleSdkVersion.V9_2, 47 | AppleSdkVersion.V9_3, 48 | AppleSdkVersion.V10_0, 49 | AppleSdkVersion.V10_1 50 | }; 51 | static readonly AppleSdkVersion [] watchOSSdkVersions = { 52 | AppleSdkVersion.V2_0, 53 | AppleSdkVersion.V2_1, 54 | AppleSdkVersion.V2_2, 55 | AppleSdkVersion.V3_0, 56 | AppleSdkVersion.V3_1 57 | }; 58 | static readonly AppleSdkVersion [] tvOSSdkVersions = { 59 | AppleSdkVersion.V9_0, 60 | AppleSdkVersion.V9_1, 61 | AppleSdkVersion.V9_2, 62 | AppleSdkVersion.V10_0 63 | }; 64 | 65 | public static readonly string [] DefaultLocations; 66 | 67 | // Note: We require Xamarin.iOS 10.4 because it is the first version to bundle mlaunch. Prior to that Xamarin Studio would ship it but that is no longer the case. 68 | // (We also need 10.4 for the Versions.plist, although we have a handy fallback if that file is missing) 69 | static AppleSdkVersion requiredXI = AppleSdkVersion.V10_4; 70 | 71 | DateTime lastMTExeWrite = DateTime.MinValue; 72 | PDictionary versions; 73 | string mtouchPath; 74 | 75 | static MonoTouchSdk () 76 | { 77 | var locations = new List (); 78 | var env = Environment.GetEnvironmentVariable ("MD_MTOUCH_SDK_ROOT"); 79 | if (!string.IsNullOrEmpty (env)) 80 | locations.Add (env); 81 | locations.Add ("/Library/Frameworks/Xamarin.iOS.framework/Versions/Current"); 82 | DefaultLocations = locations.ToArray (); 83 | } 84 | 85 | public MonoTouchSdk (string sdkDir) 86 | { 87 | SdkDir = sdkDir; 88 | Init (); 89 | } 90 | 91 | public string SdkDir { get; private set; } 92 | 93 | public string BinDir { 94 | get { 95 | // mtouch is in the bin dir 96 | return Path.GetDirectoryName (mtouchPath); 97 | } 98 | } 99 | 100 | public string LibDir { 101 | get { 102 | // the lib dir is next to the bin dir 103 | return Path.Combine (Path.GetDirectoryName (BinDir), "lib"); 104 | } 105 | } 106 | 107 | public string SdkNotInstalledReason { get; private set; } 108 | 109 | public event EventHandler Changed; 110 | 111 | static PArray CreateKnownSdkVersionsArray (IList versions) 112 | { 113 | var array = new PArray (); 114 | 115 | for (int i = 0; i < versions.Count; i++) 116 | array.Add (new PString (versions [i].ToString ())); 117 | 118 | return array; 119 | } 120 | 121 | static PDictionary CreateKnownVersions () 122 | { 123 | var knownVersions = new PDictionary (); 124 | 125 | knownVersions.Add ("iOS", CreateKnownSdkVersionsArray (iOSSdkVersions)); 126 | knownVersions.Add ("tvOS", CreateKnownSdkVersionsArray (tvOSSdkVersions)); 127 | knownVersions.Add ("watchOS", CreateKnownSdkVersionsArray (watchOSSdkVersions)); 128 | 129 | return knownVersions; 130 | } 131 | 132 | static PDictionary CreateMinExtensionVersions () 133 | { 134 | var minExtensionVersions = new PDictionary (); 135 | var watchos = new PDictionary (); 136 | var tvos = new PDictionary (); 137 | var ios = new PDictionary (); 138 | 139 | ios.Add ("com.apple.ui-services", new PString ("8.0")); 140 | ios.Add ("com.apple.services", new PString ("8.0")); 141 | ios.Add ("com.apple.keyboard-service", new PString ("8.0")); 142 | ios.Add ("com.apple.fileprovider-ui", new PString ("8.0")); 143 | ios.Add ("com.apple.fileprovider-nonui", new PString ("8.0")); 144 | ios.Add ("com.apple.photo-editing", new PString ("8.0")); 145 | ios.Add ("com.apple.share-services", new PString ("8.0")); 146 | ios.Add ("com.apple.widget-extension", new PString ("8.0")); 147 | ios.Add ("com.apple.watchkit", new PString ("8.0")); 148 | ios.Add ("com.apple.AudioUnit-UI", new PString ("8.0")); 149 | ios.Add ("com.apple.Safari.content-blocker", new PString ("9.0")); 150 | ios.Add ("com.apple.Safari.sharedlinks-service", new PString ("9.0")); 151 | ios.Add ("com.apple.spotlight.index", new PString ("9.0")); 152 | ios.Add ("com.apple.callkit.call-directory", new PString ("10.0")); 153 | ios.Add ("com.apple.intents-service", new PString ("10.0")); 154 | ios.Add ("com.apple.intents-ui-service", new PString ("10.0")); 155 | ios.Add ("com.apple.message-payload-provider", new PString ("10.0")); 156 | ios.Add ("com.apple.usernotifications.content-extension", new PString ("10.0")); 157 | ios.Add ("com.apple.usernotifications.service", new PString ("10.0")); 158 | ios.Add ("com.apple.authentication-services-credential-provider-ui", new PString ("12.0")); 159 | 160 | tvos.Add ("com.apple.broadcast-services", new PString ("10.0")); 161 | tvos.Add ("com.apple.tv-services", new PString ("9.0")); 162 | 163 | minExtensionVersions.Add ("iOS", ios); 164 | minExtensionVersions.Add ("tvOS", tvos); 165 | minExtensionVersions.Add ("watchOS", watchos); 166 | 167 | return minExtensionVersions; 168 | } 169 | 170 | static PDictionary CreateDefaultVersionsPlist () 171 | { 172 | var versions = new PDictionary (); 173 | 174 | versions.Add ("KnownVersions", CreateKnownVersions ()); 175 | versions.Add ("RecommendedXcodeVersion", new PString ("8.0")); 176 | versions.Add ("MinExtensionVersion", CreateMinExtensionVersions ()); 177 | 178 | return versions; 179 | } 180 | 181 | void Init () 182 | { 183 | string currentLocation = IsInstalled ? mtouchPath : null; 184 | 185 | IsInstalled = false; 186 | versions = null; 187 | 188 | if (string.IsNullOrEmpty (SdkDir)) { 189 | foreach (var loc in DefaultLocations) { 190 | if (IsInstalled = ValidateSdkLocation (loc, out mtouchPath)) { 191 | SdkDir = loc; 192 | break; 193 | } 194 | } 195 | } else { 196 | IsInstalled = ValidateSdkLocation (SdkDir, out mtouchPath); 197 | } 198 | 199 | if (IsInstalled) { 200 | lastMTExeWrite = File.GetLastWriteTimeUtc (mtouchPath); 201 | Version = ReadVersion (); 202 | 203 | if (Version.CompareTo (requiredXI) >= 0) { 204 | LoggingService.LogInfo ("Found Xamarin.iOS, version {0}.", Version); 205 | 206 | var path = Path.Combine (SdkDir, "Versions.plist"); 207 | if (File.Exists (path)) { 208 | try { 209 | versions = PDictionary.FromFile (path); 210 | } catch { 211 | LoggingService.LogWarning ("Xamarin.iOS installation is corrupt: invalid Versions.plist at {0}.", path); 212 | } 213 | } 214 | 215 | if (versions == null) 216 | versions = CreateDefaultVersionsPlist (); 217 | } else { 218 | SdkNotInstalledReason = string.Format ("Found unsupported Xamarin.iOS, version {0}.\nYou need Xamarin.iOS {1} or above.", Version, requiredXI.ToString ()); 219 | LoggingService.LogWarning (SdkNotInstalledReason); 220 | Version = new AppleSdkVersion (); 221 | versions = new PDictionary (); 222 | IsInstalled = false; 223 | } 224 | 225 | AnalyticsService.ReportSdkVersion ("XS.Core.SDK.iOS.Version", Version.ToString ()); 226 | } else { 227 | lastMTExeWrite = DateTime.MinValue; 228 | Version = new AppleSdkVersion (); 229 | versions = new PDictionary (); 230 | 231 | SdkNotInstalledReason = string.Format ("Xamarin.iOS not installed.\nCan't find mtouch or the Version file at {0}.", SdkDir); 232 | LoggingService.LogInfo (SdkNotInstalledReason); 233 | 234 | AnalyticsService.ReportSdkVersion ("XS.Core.SDK.iOS.Version", string.Empty); 235 | } 236 | 237 | if (Changed != null && currentLocation != mtouchPath) 238 | Changed (this, EventArgs.Empty); 239 | } 240 | 241 | AppleSdkVersion ReadVersion () 242 | { 243 | var versionFile = Path.Combine (SdkDir, "Version"); 244 | 245 | if (File.Exists (versionFile)) { 246 | try { 247 | return AppleSdkVersion.Parse (File.ReadAllText (versionFile).Trim ()); 248 | } catch (Exception ex) { 249 | LoggingService.LogError ("Failed to read Xamarin.iOS version", ex); 250 | } 251 | } 252 | 253 | return new AppleSdkVersion (); 254 | } 255 | 256 | public static bool ValidateSdkLocation (string sdkDir) 257 | { 258 | return ValidateSdkLocation (sdkDir, out string _); 259 | } 260 | 261 | public static bool ValidateSdkLocation (string sdkDir, out bool hasUsrSubdir) 262 | { 263 | hasUsrSubdir = false; 264 | return ValidateSdkLocation (sdkDir, out string _); 265 | } 266 | 267 | public static bool ValidateSdkLocation (string sdkDir, out string mtouchPath) 268 | { 269 | mtouchPath = null; 270 | 271 | if (!File.Exists (Path.Combine (sdkDir, "Version"))) 272 | return false; 273 | 274 | var path = Path.Combine (sdkDir, "bin", "mtouch"); 275 | if (File.Exists (path)) { 276 | mtouchPath = path; 277 | return true; 278 | } 279 | 280 | path = Path.Combine (sdkDir, "tools", "bin", "mtouch"); 281 | if (File.Exists (path)) { 282 | mtouchPath = path; 283 | return true; 284 | } 285 | 286 | return false; 287 | } 288 | 289 | public bool IsInstalled { get; private set; } 290 | public AppleSdkVersion Version { get; private set; } 291 | 292 | ExtendedVersion extended_version; 293 | public ExtendedVersion ExtendedVersion { 294 | get { 295 | if (extended_version == null) { 296 | extended_version = ExtendedVersion.Read (Path.Combine (SdkDir, "buildinfo")); 297 | if (extended_version == null) { 298 | // 'buildinfo' doesn't work in a nuget package because of https://github.com/NuGet/Home/issues/8810, so use 'tools/buildinfo' instead. 299 | extended_version = ExtendedVersion.Read (Path.Combine (SdkDir, "tools", "buildinfo")); 300 | } 301 | } 302 | return extended_version; 303 | } 304 | } 305 | 306 | static string GetPlatformKey (PlatformName platform) 307 | { 308 | switch (platform) { 309 | case PlatformName.iOS: return "iOS"; 310 | case PlatformName.WatchOS: return "watchOS"; 311 | case PlatformName.TvOS: return "tvOS"; 312 | case PlatformName.MacOSX: return "MacCatalyst"; 313 | default: throw new ArgumentOutOfRangeException (nameof (platform)); 314 | } 315 | } 316 | 317 | public Version RecommendedXcodeVersion { 318 | get { 319 | Version version; 320 | PString value; 321 | 322 | if (!versions.TryGetValue ("RecommendedXcodeVersion", out value) || !System.Version.TryParse (value.Value, out version)) 323 | return new Version (8, 0); 324 | 325 | return version; 326 | } 327 | } 328 | 329 | public IList GetKnownSdkVersions (PlatformName platform) 330 | { 331 | var list = new List (); 332 | var key = GetPlatformKey (platform); 333 | PDictionary knownVersions; 334 | 335 | if (versions.TryGetValue ("KnownVersions", out knownVersions)) { 336 | PArray array; 337 | 338 | if (knownVersions.TryGetValue (key, out array)) { 339 | versions.TryGetValue ("MacCatalystVersionMap", out PDictionary macCatalystVersionMap); 340 | 341 | foreach (var knownVersion in array.OfType ()) { 342 | string versionValue = knownVersion.Value; 343 | 344 | // For MacCatalyst we need to convert the versions to supported versions using the map 345 | if (platform == PlatformName.MacOSX) { 346 | if (macCatalystVersionMap != null) { 347 | if (macCatalystVersionMap.TryGetValue (knownVersion, out PString value)) 348 | versionValue = value.Value; 349 | } 350 | } 351 | 352 | if (AppleSdkVersion.TryParse (versionValue, out var version)) 353 | list.Add (version); 354 | } 355 | } 356 | } 357 | 358 | return list; 359 | } 360 | 361 | public AppleSdkVersion GetMinimumExtensionVersion (PlatformName platform, string extension) 362 | { 363 | var key = GetPlatformKey (platform); 364 | PDictionary minExtensionVersions; 365 | 366 | if (versions.TryGetValue ("MinExtensionVersion", out minExtensionVersions)) { 367 | PDictionary extensions; 368 | 369 | if (minExtensionVersions.TryGetValue (key, out extensions)) { 370 | PString value; 371 | 372 | if (extensions.TryGetValue (extension, out value)) { 373 | if (AppleSdkVersion.TryParse (value.Value, out var version)) 374 | return version; 375 | } 376 | } 377 | } 378 | 379 | return AppleSdkVersion.V8_0; 380 | } 381 | 382 | public void CheckCaches () 383 | { 384 | if (IsInstalled) { 385 | try { 386 | var lastWrite = File.GetLastWriteTimeUtc (mtouchPath); 387 | if (lastWrite == lastMTExeWrite) 388 | return; 389 | } catch (IOException) { 390 | } 391 | } 392 | 393 | Init (); 394 | } 395 | 396 | public bool SupportsFeature (string feature) 397 | { 398 | PArray features; 399 | 400 | if (!versions.TryGetValue ("Features", out features)) 401 | return false; 402 | 403 | foreach (var item in features.OfType ().Select (x => x.Value)) { 404 | if (feature == item) 405 | return true; 406 | } 407 | 408 | return false; 409 | } 410 | 411 | public bool SupportsSGenConcurrentGC { 412 | get { return SupportsFeature ("sgen-concurrent-gc"); } 413 | } 414 | 415 | public bool SupportsLaunchDeviceBundleId { 416 | get { return SupportsFeature ("mlaunch-launchdevbundleid"); } 417 | } 418 | 419 | public bool SupportsObserveExtension { 420 | get { return SupportsFeature ("mlaunch-observe-extension"); } 421 | } 422 | 423 | public bool SupportsLaunchSimulator { 424 | get { return SupportsFeature ("mlaunch-launch-simulator"); } 425 | } 426 | 427 | public bool SupportsInstallProgress { 428 | get { return SupportsFeature ("mlaunch-install-progress"); } 429 | } 430 | 431 | public bool SupportsLaunchWatchOSComplications { 432 | get { return SupportsFeature ("mlaunch-watchos-complications"); } 433 | } 434 | 435 | public bool SupportsWirelessDevices { 436 | get { return SupportsFeature ("mlaunch-wireless-devices"); } 437 | } 438 | 439 | public bool SupportsSiriIntents { 440 | get { return SupportsFeature ("siri-intents"); } 441 | } 442 | 443 | public bool SupportsArm64_32 { 444 | get { return SupportsFeature ("arm64_32"); } 445 | } 446 | 447 | public bool SupportsAltool { 448 | get { return SupportsFeature ("altool"); } 449 | } 450 | } 451 | } 452 | -------------------------------------------------------------------------------- /Xamarin.MacDev/NullableAttributes.cs: -------------------------------------------------------------------------------- 1 | // 2 | // NullableAttributes.cs 3 | // 4 | // Author: Rolf Kvinge 5 | // 6 | // Copyright (c) 2023 Microsoft Corp. 7 | // 8 | // Permission is hereby granted, free of charge, to any person obtaining a copy 9 | // of this software and associated documentation files (the "Software"), to deal 10 | // in the Software without restriction, including without limitation the rights 11 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 12 | // copies of the Software, and to permit persons to whom the Software is 13 | // furnished to do so, subject to the following conditions: 14 | // 15 | // The above copyright notice and this permission notice shall be included in 16 | // all copies or substantial portions of the Software. 17 | // 18 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 19 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 20 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 21 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 22 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 23 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 24 | // THE SOFTWARE. 25 | 26 | #nullable enable 27 | 28 | using System; 29 | 30 | #if !NET 31 | namespace System.Diagnostics.CodeAnalysis { 32 | // from: https://github.com/dotnet/runtime/blob/main/src/libraries/System.Private.CoreLib/src/System/Diagnostics/CodeAnalysis/NullableAttributes.cs 33 | [AttributeUsage (AttributeTargets.Parameter, Inherited = false)] 34 | internal sealed class NotNullWhenAttribute : Attribute { 35 | public NotNullWhenAttribute (bool returnValue) => ReturnValue = returnValue; 36 | public bool ReturnValue { get; } 37 | } 38 | [AttributeUsage (AttributeTargets.Parameter | AttributeTargets.Property | AttributeTargets.ReturnValue, AllowMultiple=true, Inherited=false)] 39 | internal sealed class NotNullIfNotNullAttribute : Attribute { 40 | public NotNullIfNotNullAttribute (string parameterName) => ParameterName = parameterName; 41 | public string ParameterName { get; } 42 | } 43 | } 44 | #endif // !NET 45 | -------------------------------------------------------------------------------- /Xamarin.MacDev/PlatformAvailability.cs: -------------------------------------------------------------------------------- 1 | // 2 | // PlatformAvailability.cs 3 | // 4 | // Data structures for mapping Xamarin.iOS and Xamarin.Mac's 5 | // AvailabilityAttribute and its subclasses. 6 | // 7 | // Keep in sync with src/ObjCRuntime/PlatformAvailability.cs 8 | // in xamarin/maccore. 9 | // 10 | // Author: 11 | // Aaron Bockover 12 | // 13 | // Copyright 2014 Xamarin Inc. 14 | // 15 | 16 | using System; 17 | using System.Collections; 18 | using System.Collections.Generic; 19 | using System.Linq; 20 | using System.Text; 21 | 22 | namespace Xamarin.MacDev { 23 | [Flags] 24 | public enum PlatformArchitecture : byte { 25 | None = 0x00, 26 | Arch32 = 0x01, 27 | Arch64 = 0x02, 28 | All = 0xff 29 | } 30 | 31 | public enum PlatformName : byte { 32 | None, 33 | MacOSX, 34 | iOS, 35 | WatchOS, 36 | TvOS 37 | } 38 | 39 | public enum AvailabilityKind { 40 | Introduced, 41 | Deprecated, 42 | Obsoleted, 43 | Unavailable 44 | } 45 | 46 | public class Platform { 47 | internal uint value; 48 | 49 | public PlatformName Name { get; set; } 50 | 51 | public PlatformArchitecture Architecture { 52 | get { 53 | var arch = (byte) (value >> 24); 54 | if (arch == 0) 55 | return PlatformArchitecture.All; 56 | return (PlatformArchitecture) arch; 57 | } 58 | 59 | set { this.value = (this.value & 0x00ffffff) | (uint) (byte) value << 24; } 60 | } 61 | 62 | public byte Major { 63 | get { return (byte) (value >> 16); } 64 | set { this.value = (this.value & 0xff00ffff) | (uint) (byte) value << 16; } 65 | } 66 | 67 | public byte Minor { 68 | get { return (byte) (value >> 8); } 69 | set { this.value = (this.value & 0xffff00ff) | (uint) (byte) value << 8; } 70 | } 71 | 72 | public byte Subminor { 73 | get { return (byte) value; } 74 | set { this.value = (this.value & 0xffffff00) | (uint) (byte) value; } 75 | } 76 | 77 | static string ToNiceName (PlatformName name) 78 | { 79 | switch (name) { 80 | case PlatformName.None: 81 | return "None"; 82 | case PlatformName.MacOSX: 83 | return "Mac OS X"; 84 | case PlatformName.iOS: 85 | return "iOS"; 86 | case PlatformName.WatchOS: 87 | return "watchOS"; 88 | case PlatformName.TvOS: 89 | return "tvOS"; 90 | default: 91 | throw new ArgumentOutOfRangeException (); 92 | } 93 | } 94 | 95 | public string FullName { 96 | get { 97 | var name = ToNiceName (Name); 98 | 99 | // when a version is specified, use that; all bits set mean 100 | // the attribute applies to all versions, so ignore that 101 | if (Major > 0 && Major != 0xff) 102 | return String.Format ("{0} {1}.{2}", name, Major, Minor); 103 | 104 | // otherwise note the architecture 105 | if (Architecture == PlatformArchitecture.Arch32) 106 | return String.Format ("{0} 32-bit", name); 107 | 108 | if (Architecture == PlatformArchitecture.Arch64) 109 | return String.Format ("{0} 64-bit", name); 110 | 111 | // unless it applies to a combination or lack 112 | // of architectures, then just use the name 113 | return name; 114 | } 115 | } 116 | 117 | public bool HasValue { get; set; } 118 | 119 | public bool IsSpecified { 120 | get { return value != 0; } 121 | } 122 | 123 | internal Platform (PlatformName name, uint value) 124 | { 125 | Name = name; 126 | this.value = value; 127 | } 128 | 129 | public Platform (PlatformName name, 130 | PlatformArchitecture architecture = PlatformArchitecture.All, 131 | byte major = 0, byte minor = 0, byte subminor = 0) 132 | { 133 | Name = name; 134 | Architecture = architecture; 135 | Major = major; 136 | Minor = minor; 137 | Subminor = subminor; 138 | } 139 | 140 | public int VersionCompare (Platform value) 141 | { 142 | if (value == null) 143 | return 1; 144 | 145 | if (Major > value.Major) 146 | return 1; 147 | if (Major < value.Major) 148 | return -1; 149 | 150 | if (Minor > value.Minor) 151 | return 1; 152 | if (Minor < value.Minor) 153 | return -1; 154 | 155 | if (Subminor > value.Subminor) 156 | return 1; 157 | if (Subminor < value.Subminor) 158 | return -1; 159 | 160 | return 0; 161 | } 162 | 163 | public override string ToString () 164 | { 165 | if (!IsSpecified) 166 | return String.Empty; 167 | 168 | var name = ToNiceName (Name); 169 | string s = null; 170 | 171 | if (Major > 0) { 172 | s = String.Format ("Platform.{0}_{1}_{2}", name, Major, Minor); 173 | if (Subminor > 0) 174 | s += String.Format ("_{0}", Subminor); 175 | } 176 | 177 | if (Architecture != PlatformArchitecture.All) { 178 | if (!String.IsNullOrEmpty (s)) 179 | s += " | "; 180 | s += Architecture.ToString ().Replace ("Any", "Platform." + name + "_Arch"); 181 | } 182 | 183 | return s; 184 | } 185 | } 186 | 187 | public class PlatformSet : IEnumerable { 188 | // Analysis disable once InconsistentNaming 189 | public Platform iOS { get; private set; } 190 | public Platform MacOSX { get; private set; } 191 | public Platform WatchOS { get; private set; } 192 | public Platform TvOS { get; private set; } 193 | 194 | public bool IsSpecified { 195 | get { return this.Any (p => p.IsSpecified); } 196 | } 197 | 198 | public PlatformSet () 199 | { 200 | iOS = new Platform (PlatformName.iOS, PlatformArchitecture.None); 201 | MacOSX = new Platform (PlatformName.MacOSX, PlatformArchitecture.None); 202 | WatchOS = new Platform (PlatformName.WatchOS, PlatformArchitecture.None); 203 | TvOS = new Platform (PlatformName.TvOS, PlatformArchitecture.None); 204 | } 205 | 206 | /// 207 | /// Initialize a struct with 208 | /// version information encoded as a value of 209 | /// enum. For example (ulong)(Platform.iOS_8_0 | Platform.Mac_10_10). 210 | /// 211 | /// Should have the bit format AAJJNNSSAAJJNNSS, where 212 | /// AA are the supported architecture flags, JJ is the maJor version, NN 213 | /// is the miNor version, and SS is the Subminor version. The high AAJJNNSS 214 | /// bytes indicate Mac version information and the low AAJJNNSS bytes 215 | /// indicate iOS version information. Only Major and Minor version components 216 | /// are parsed from the version. 217 | public PlatformSet (ulong platformEncoding) 218 | { 219 | //This constructor is only useful in XAMCORE_2 or older, since it only supports iOS and OSX, keep it for backward compatibility 220 | iOS = new Platform (PlatformName.iOS, (uint) platformEncoding); 221 | MacOSX = new Platform (PlatformName.MacOSX, (uint) (platformEncoding >> 32)); 222 | WatchOS = new Platform (PlatformName.WatchOS, PlatformArchitecture.None); 223 | TvOS = new Platform (PlatformName.TvOS, PlatformArchitecture.None); 224 | } 225 | 226 | public static PlatformSet operator | (PlatformSet a, PlatformSet b) 227 | { 228 | if (a == null && b == null) 229 | return null; 230 | 231 | var result = new PlatformSet (); 232 | 233 | if (a == null) { 234 | result.MacOSX.value = b.MacOSX.value; 235 | result.iOS.value = b.iOS.value; 236 | result.WatchOS.value = b.WatchOS.value; 237 | result.TvOS.value = b.TvOS.value; 238 | } else if (b == null) { 239 | result.MacOSX.value = a.MacOSX.value; 240 | result.iOS.value = a.iOS.value; 241 | result.WatchOS.value = a.WatchOS.value; 242 | result.TvOS.value = a.TvOS.value; 243 | } else { 244 | result.MacOSX.value = a.MacOSX.value | b.MacOSX.value; 245 | result.iOS.value = a.iOS.value | b.iOS.value; 246 | result.WatchOS.value = a.WatchOS.value | b.WatchOS.value; 247 | result.TvOS.value = a.TvOS.value | b.TvOS.value; 248 | } 249 | 250 | return result; 251 | } 252 | 253 | public IEnumerator GetEnumerator () 254 | { 255 | yield return iOS; 256 | yield return MacOSX; 257 | yield return WatchOS; 258 | yield return TvOS; 259 | } 260 | 261 | IEnumerator IEnumerable.GetEnumerator () 262 | { 263 | return GetEnumerator (); 264 | } 265 | 266 | public override string ToString () 267 | { 268 | string s = null; 269 | 270 | foreach (var platform in this) { 271 | var platformString = platform.ToString (); 272 | if (!String.IsNullOrEmpty (platformString)) { 273 | if (!String.IsNullOrEmpty (s)) 274 | s += " | "; 275 | s += platformString; 276 | } 277 | } 278 | 279 | return s; 280 | } 281 | } 282 | 283 | public class PlatformAvailability { 284 | public PlatformSet Introduced { get; set; } 285 | public PlatformSet Deprecated { get; set; } 286 | public PlatformSet Obsoleted { get; set; } 287 | public PlatformSet Unavailable { get; set; } 288 | public string Message { get; set; } 289 | 290 | public bool IsSpecified { 291 | get { 292 | return 293 | (Introduced != null && Introduced.IsSpecified) || 294 | (Deprecated != null && Deprecated.IsSpecified) || 295 | (Obsoleted != null && Obsoleted.IsSpecified) || 296 | (Unavailable != null && Unavailable.IsSpecified) || 297 | Message != null; 298 | } 299 | } 300 | 301 | public Platform GetIntroduced (Platform platform) 302 | { 303 | return GetIntroduced (platform.Name); 304 | } 305 | 306 | public Platform GetIntroduced (PlatformName name) 307 | { 308 | if (Introduced == null) 309 | return null; 310 | switch (name) { 311 | case PlatformName.iOS: 312 | return Introduced.iOS; 313 | case PlatformName.WatchOS: 314 | return Introduced.WatchOS; 315 | case PlatformName.TvOS: 316 | return Introduced.TvOS; 317 | } 318 | return Introduced.MacOSX; 319 | } 320 | 321 | public Platform GetDeprecated (Platform platform) 322 | { 323 | return GetDeprecated (platform.Name); 324 | } 325 | 326 | public Platform GetDeprecated (PlatformName name) 327 | { 328 | if (Deprecated == null) 329 | return null; 330 | switch (name) { 331 | case PlatformName.iOS: 332 | return Deprecated.iOS; 333 | case PlatformName.WatchOS: 334 | return Deprecated.WatchOS; 335 | case PlatformName.TvOS: 336 | return Deprecated.TvOS; 337 | } 338 | return Deprecated.MacOSX; 339 | } 340 | 341 | public Platform GetObsoleted (Platform platform) 342 | { 343 | return GetObsoleted (platform.Name); 344 | } 345 | 346 | public Platform GetObsoleted (PlatformName name) 347 | { 348 | if (Obsoleted == null) 349 | return null; 350 | switch (name) { 351 | case PlatformName.iOS: 352 | return Obsoleted.iOS; 353 | case PlatformName.WatchOS: 354 | return Obsoleted.WatchOS; 355 | case PlatformName.TvOS: 356 | return Obsoleted.TvOS; 357 | } 358 | return Obsoleted.MacOSX; 359 | } 360 | 361 | public Platform GetUnavailable (Platform platform) 362 | { 363 | return GetUnavailable (platform.Name); 364 | } 365 | 366 | public Platform GetUnavailable (PlatformName name) 367 | { 368 | if (Unavailable == null) 369 | return null; 370 | switch (name) { 371 | case PlatformName.iOS: 372 | return Unavailable.iOS; 373 | case PlatformName.WatchOS: 374 | return Unavailable.WatchOS; 375 | case PlatformName.TvOS: 376 | return Unavailable.TvOS; 377 | } 378 | return Unavailable.MacOSX; 379 | } 380 | 381 | public override string ToString () 382 | { 383 | var s = new StringBuilder (); 384 | 385 | if (Introduced != null && Introduced.IsSpecified) 386 | s.AppendFormat ("Introduced = {0}, ", Introduced); 387 | 388 | if (Deprecated != null && Deprecated.IsSpecified) 389 | s.AppendFormat ("Deprecated = {0}, ", Deprecated); 390 | 391 | if (Obsoleted != null && Obsoleted.IsSpecified) 392 | s.AppendFormat ("Obsoleted = {0}, ", Obsoleted); 393 | 394 | if (Unavailable != null && Unavailable.IsSpecified) 395 | s.AppendFormat ("Unavailable = {0}, ", Unavailable); 396 | 397 | if (!String.IsNullOrEmpty (Message)) 398 | s.AppendFormat ("Message = \"{0}\", ", Message.Replace ("\"", "\\\"")); 399 | 400 | if (s.Length < 2) 401 | return "[Availability]"; 402 | 403 | s.Length -= 2; 404 | 405 | return String.Format ("[Availability ({0})]", s); 406 | } 407 | } 408 | } 409 | -------------------------------------------------------------------------------- /Xamarin.MacDev/ProcessArgumentBuilder.cs: -------------------------------------------------------------------------------- 1 | // 2 | // ProcessArgumentBuilder.cs 3 | // 4 | // Author: 5 | // Michael Hutchinson 6 | // 7 | // Copyright (c) 2010 Novell, Inc. 8 | // 9 | // Permission is hereby granted, free of charge, to any person obtaining a copy 10 | // of this software and associated documentation files (the "Software"), to deal 11 | // in the Software without restriction, including without limitation the rights 12 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 13 | // copies of the Software, and to permit persons to whom the Software is 14 | // furnished to do so, subject to the following conditions: 15 | // 16 | // The above copyright notice and this permission notice shall be included in 17 | // all copies or substantial portions of the Software. 18 | // 19 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 20 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 21 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 22 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 23 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 24 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 25 | // THE SOFTWARE. 26 | 27 | using System; 28 | using System.Collections.Generic; 29 | using System.Text; 30 | 31 | namespace Xamarin.MacDev { 32 | /// 33 | /// Builds a process argument string. 34 | /// 35 | class ProcessArgumentBuilder { 36 | StringBuilder sb = new StringBuilder (); 37 | 38 | public string ProcessPath { 39 | get; private set; 40 | } 41 | 42 | // .NET doesn't allow escaping chars other than " and \ inside " quotes 43 | const string escapeDoubleQuoteCharsStr = "\\\""; 44 | 45 | public ProcessArgumentBuilder () 46 | { 47 | 48 | } 49 | 50 | public ProcessArgumentBuilder (string processPath) 51 | { 52 | ProcessPath = processPath; 53 | } 54 | 55 | /// 56 | /// Adds an argument without escaping or quoting. 57 | /// 58 | public void Add (string argument) 59 | { 60 | if (sb.Length > 0) 61 | sb.Append (' '); 62 | sb.Append (argument); 63 | } 64 | 65 | /// 66 | /// Adds multiple arguments without escaping or quoting. 67 | /// 68 | public void Add (params string [] args) 69 | { 70 | foreach (var a in args) 71 | Add (a); 72 | } 73 | 74 | /// 75 | /// Adds a formatted argument, quoting and escaping as necessary. 76 | /// 77 | public void AddQuotedFormat (string argumentFormat, params object [] values) 78 | { 79 | AddQuoted (string.Format (argumentFormat, values)); 80 | } 81 | 82 | public void AddQuotedFormat (string argumentFormat, object val0) 83 | { 84 | AddQuoted (string.Format (argumentFormat, val0)); 85 | } 86 | 87 | /// Adds an argument, quoting and escaping as necessary. 88 | /// The .NET process class does not support escaped 89 | /// arguments, only quoted arguments with escaped quotes. 90 | public void AddQuoted (string argument) 91 | { 92 | if (argument == null) 93 | return; 94 | if (sb.Length > 0) 95 | sb.Append (' '); 96 | 97 | sb.Append ('"'); 98 | AppendEscaped (sb, escapeDoubleQuoteCharsStr, argument); 99 | sb.Append ('"'); 100 | } 101 | 102 | /// 103 | /// Adds multiple arguments, quoting and escaping each as necessary. 104 | /// 105 | public void AddQuoted (params string [] args) 106 | { 107 | foreach (var a in args) 108 | AddQuoted (a); 109 | } 110 | 111 | /// Quotes a string, escaping if necessary. 112 | /// The .NET process class does not support escaped 113 | /// arguments, only quoted arguments with escaped quotes. 114 | public static string Quote (string s) 115 | { 116 | var sb = new StringBuilder (); 117 | sb.Append ('"'); 118 | AppendEscaped (sb, escapeDoubleQuoteCharsStr, s); 119 | sb.Append ('"'); 120 | return sb.ToString (); 121 | } 122 | 123 | public override string ToString () 124 | { 125 | return sb.ToString (); 126 | } 127 | 128 | static void AppendEscaped (StringBuilder sb, string escapeChars, string s) 129 | { 130 | for (int i = 0; i < s.Length; i++) { 131 | char c = s [i]; 132 | if (escapeChars.IndexOf (c) > -1) 133 | sb.Append ('\\'); 134 | sb.Append (c); 135 | } 136 | } 137 | 138 | static string GetArgument (StringBuilder builder, string buf, int startIndex, out int endIndex, out Exception ex) 139 | { 140 | bool escaped = false; 141 | char qchar, c = '\0'; 142 | int i = startIndex; 143 | 144 | builder.Clear (); 145 | switch (buf [startIndex]) { 146 | case '\'': qchar = '\''; i++; break; 147 | case '"': qchar = '"'; i++; break; 148 | default: qchar = '\0'; break; 149 | } 150 | 151 | while (i < buf.Length) { 152 | c = buf [i]; 153 | 154 | if (c == qchar && !escaped) { 155 | // unescaped qchar means we've reached the end of the argument 156 | i++; 157 | break; 158 | } 159 | 160 | if (c == '\\') { 161 | escaped = true; 162 | } else if (escaped) { 163 | builder.Append (c); 164 | escaped = false; 165 | } else if (qchar == '\0' && (c == ' ' || c == '\t')) { 166 | break; 167 | } else if (qchar == '\0' && (c == '\'' || c == '"')) { 168 | string sofar = builder.ToString (); 169 | string embedded; 170 | 171 | if ((embedded = GetArgument (builder, buf, i, out endIndex, out ex)) == null) 172 | return null; 173 | 174 | i = endIndex; 175 | builder.Clear (); 176 | builder.Append (sofar); 177 | builder.Append (embedded); 178 | continue; 179 | } else { 180 | builder.Append (c); 181 | } 182 | 183 | i++; 184 | } 185 | 186 | if (escaped || (qchar != '\0' && c != qchar)) { 187 | ex = new FormatException (escaped ? "Incomplete escape sequence." : "No matching quote found."); 188 | endIndex = -1; 189 | return null; 190 | } 191 | 192 | endIndex = i; 193 | ex = null; 194 | 195 | return builder.ToString (); 196 | } 197 | 198 | static bool TryParse (string commandline, out string [] argv, out Exception ex) 199 | { 200 | var builder = new StringBuilder (); 201 | var args = new List (); 202 | string argument; 203 | int i = 0, j; 204 | char c; 205 | 206 | while (i < commandline.Length) { 207 | c = commandline [i]; 208 | if (c != ' ' && c != '\t') { 209 | if ((argument = GetArgument (builder, commandline, i, out j, out ex)) == null) { 210 | argv = null; 211 | return false; 212 | } 213 | 214 | args.Add (argument); 215 | i = j; 216 | } 217 | 218 | i++; 219 | } 220 | 221 | argv = args.ToArray (); 222 | ex = null; 223 | 224 | return true; 225 | } 226 | 227 | public static bool TryParse (string commandline, out string [] argv) 228 | { 229 | Exception ex; 230 | 231 | return TryParse (commandline, out argv, out ex); 232 | } 233 | 234 | public static string [] Parse (string commandline) 235 | { 236 | string [] argv; 237 | Exception ex; 238 | 239 | if (!TryParse (commandline, out argv, out ex)) 240 | throw ex; 241 | 242 | return argv; 243 | } 244 | } 245 | } 246 | -------------------------------------------------------------------------------- /Xamarin.MacDev/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | // 2 | // AssemblyInfo.cs 3 | // 4 | // Author: Jeffrey Stedfast 5 | // 6 | // Copyright (c) 2013 Xamarin Inc. 7 | // 8 | // Permission is hereby granted, free of charge, to any person obtaining a copy 9 | // of this software and associated documentation files (the "Software"), to deal 10 | // in the Software without restriction, including without limitation the rights 11 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 12 | // copies of the Software, and to permit persons to whom the Software is 13 | // furnished to do so, subject to the following conditions: 14 | // 15 | // The above copyright notice and this permission notice shall be included in 16 | // all copies or substantial portions of the Software. 17 | // 18 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 19 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 20 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 21 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 22 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 23 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 24 | // THE SOFTWARE. 25 | 26 | using System.Reflection; 27 | using System.Runtime.CompilerServices; 28 | 29 | // Information about this assembly is defined by the following attributes. 30 | // Change them to the values specific to your project. 31 | [assembly: AssemblyTitle ("Xamarin.MacDev")] 32 | [assembly: AssemblyDescription ("")] 33 | [assembly: AssemblyConfiguration ("")] 34 | [assembly: AssemblyCompany ("Xamarin Inc.")] 35 | [assembly: AssemblyProduct ("")] 36 | [assembly: AssemblyCopyright ("Xamarin Inc.")] 37 | [assembly: AssemblyTrademark ("Xamarin Inc.")] 38 | [assembly: AssemblyCulture ("")] 39 | // The assembly version has the format "{Major}.{Minor}.{Build}.{Revision}". 40 | // The form "{Major}.{Minor}.*" will automatically update the build and revision, 41 | // and "{Major}.{Minor}.{Build}.*" will update just the revision. 42 | [assembly: AssemblyVersion ("1.0.0.0")] 43 | // The following attributes are used to specify the signing key for the assembly, 44 | // if desired. See the Mono documentation for more information about signing. 45 | //[assembly: AssemblyDelaySign(false)] 46 | //[assembly: AssemblyKeyFile("")] 47 | -------------------------------------------------------------------------------- /Xamarin.MacDev/XamMacSdk.cs: -------------------------------------------------------------------------------- 1 | // 2 | // XamMacSdk.cs 3 | // 4 | // Authors: 5 | // Aaron Bockover 6 | // Jeffrey Stedfast 7 | // 8 | // Copyright 2012-2014 Xamarin Inc. 9 | 10 | using System; 11 | using System.Collections.Generic; 12 | using System.IO; 13 | using System.Linq; 14 | 15 | namespace Xamarin.MacDev { 16 | public sealed class XamMacSdk : IMonoMacSdk { 17 | static readonly AppleSdkVersion [] MacOSXSdkVersions = { 18 | AppleSdkVersion.V10_7, 19 | AppleSdkVersion.V10_8, 20 | AppleSdkVersion.V10_9, 21 | AppleSdkVersion.V10_10, 22 | AppleSdkVersion.V10_11, 23 | AppleSdkVersion.V10_12 24 | }; 25 | 26 | readonly Dictionary lastWriteTimes = new Dictionary (); 27 | 28 | string monoMacAppLauncherPath; 29 | PDictionary versions; 30 | ExtendedVersion extended_version; 31 | 32 | public bool IsInstalled { get; private set; } 33 | 34 | public AppleSdkVersion Version { get; private set; } 35 | public string SdkNotInstalledReason { get; private set; } 36 | 37 | public string FrameworkDirectory { get; private set; } 38 | public string MmpPath { get; private set; } 39 | public string BmacPath { get; private set; } 40 | public string UnifiedFullProfileFrameworkAssembly { get; private set; } 41 | 42 | #region Compat paths 43 | 44 | public string LegacyFrameworkAssembly { get; private set; } 45 | public string LegacyAppLauncherPath { get; private set; } 46 | 47 | #endregion 48 | 49 | public XamMacSdk (string monoMacAppLauncherPath) 50 | { 51 | this.monoMacAppLauncherPath = monoMacAppLauncherPath; 52 | Init (); 53 | } 54 | 55 | public event EventHandler Changed; 56 | 57 | static PArray CreateKnownSdkVersionsArray (IList versions) 58 | { 59 | var array = new PArray (); 60 | 61 | for (int i = 0; i < versions.Count; i++) 62 | array.Add (new PString (versions [i].ToString ())); 63 | 64 | return array; 65 | } 66 | 67 | static PDictionary CreateKnownVersions () 68 | { 69 | var knownVersions = new PDictionary (); 70 | 71 | knownVersions.Add ("macOS", CreateKnownSdkVersionsArray (MacOSXSdkVersions)); 72 | 73 | return knownVersions; 74 | } 75 | 76 | static PDictionary CreateMinExtensionVersions () 77 | { 78 | var minExtensionVersions = new PDictionary (); 79 | var mac = new PDictionary (); 80 | 81 | mac.Add ("com.apple.FinderSync", new PString ("10.10")); 82 | mac.Add ("com.apple.share-services", new PString ("10.10")); 83 | mac.Add ("com.apple.widget-extension", new PString ("10.10")); 84 | mac.Add ("com.apple.networkextension.packet-tunnel", new PString ("10.11")); 85 | 86 | minExtensionVersions.Add ("macOS", mac); 87 | 88 | return minExtensionVersions; 89 | } 90 | 91 | static PArray CreateDefaultFeatures (AppleSdkVersion version) 92 | { 93 | var features = new PArray (); 94 | 95 | if (version >= new AppleSdkVersion (1, 9, 0)) 96 | features.Add (new PString ("activation")); 97 | if (version >= new AppleSdkVersion (1, 11, 0) && version < new AppleSdkVersion (2, 5, 0)) 98 | features.Add (new PString ("ref-counting")); 99 | if (version >= new AppleSdkVersion (2, 5, 0)) 100 | features.Add (new PString ("modern-http-client")); 101 | if (version >= new AppleSdkVersion (2, 10, 0)) 102 | features.Add (new PString ("mono-symbol-archive")); 103 | 104 | return features; 105 | } 106 | 107 | static PDictionary CreateDefaultVersionsPlist (AppleSdkVersion version) 108 | { 109 | var versions = new PDictionary (); 110 | 111 | versions.Add ("KnownVersions", CreateKnownVersions ()); 112 | versions.Add ("RecommendedXcodeVersion", new PString ("8.0")); 113 | versions.Add ("MinExtensionVersion", CreateMinExtensionVersions ()); 114 | versions.Add ("Features", CreateDefaultFeatures (version)); 115 | 116 | return versions; 117 | } 118 | 119 | void Init () 120 | { 121 | string currentLocation = IsInstalled ? MmpPath : null; 122 | 123 | IsInstalled = false; 124 | versions = null; 125 | 126 | FrameworkDirectory = "/Library/Frameworks/Xamarin.Mac.framework/Versions/Current"; 127 | var envFrameworkDir = Environment.GetEnvironmentVariable ("XAMMAC_FRAMEWORK_PATH"); 128 | if (envFrameworkDir != null && Directory.Exists (envFrameworkDir)) 129 | FrameworkDirectory = envFrameworkDir; 130 | 131 | var versionPath = Path.Combine (FrameworkDirectory, "Version"); 132 | if (File.Exists (versionPath)) { 133 | Version = ReadVersion (versionPath); 134 | lastWriteTimes [versionPath] = File.GetLastWriteTimeUtc (versionPath); 135 | 136 | var path = Path.Combine (FrameworkDirectory, "Versions.plist"); 137 | if (File.Exists (path)) { 138 | try { 139 | versions = PDictionary.FromFile (path); 140 | } catch { 141 | LoggingService.LogWarning ("Xamarin.Mac installation is corrupt: invalid Versions.plist at {0}.", path); 142 | } 143 | } 144 | 145 | if (versions == null) 146 | versions = CreateDefaultVersionsPlist (Version); 147 | } else { 148 | NotInstalled (versionPath, error: false); 149 | AnalyticsService.ReportSdkVersion ("XS.Core.SDK.Mac.Version", string.Empty); 150 | return; 151 | } 152 | 153 | var paths = Version >= new AppleSdkVersion (1, 9, 0) 154 | ? Detect2x () 155 | : Detect1x (); 156 | 157 | foreach (var path in paths) { 158 | if (!File.Exists (path)) { 159 | NotInstalled (path); 160 | return; 161 | } 162 | 163 | lastWriteTimes [path] = File.GetLastWriteTimeUtc (path); 164 | } 165 | 166 | IsInstalled = true; 167 | LoggingService.LogInfo ("Found Xamarin.Mac, version {0}.", Version); 168 | AnalyticsService.ReportSdkVersion ("XS.Core.SDK.Mac.Version", Version.ToString ()); 169 | 170 | if (Changed != null && currentLocation != MmpPath) 171 | Changed (this, EventArgs.Empty); 172 | } 173 | 174 | IEnumerable Detect2x () 175 | { 176 | yield return MmpPath = Path.Combine (FrameworkDirectory, "bin", "mmp"); 177 | yield return BmacPath = Path.Combine (FrameworkDirectory, "bin", "bmac"); 178 | yield return LegacyFrameworkAssembly = Path.Combine (FrameworkDirectory, "lib", "mono", "XamMac.dll"); 179 | yield return LegacyAppLauncherPath = Path.Combine (FrameworkDirectory, "lib", "XamMacLauncher"); 180 | yield return UnifiedFullProfileFrameworkAssembly = Path.Combine (FrameworkDirectory, "lib", "reference", "full", "Xamarin.Mac.dll"); 181 | 182 | SupportsFullProfile = 183 | File.Exists (UnifiedFullProfileFrameworkAssembly) && 184 | Version >= new AppleSdkVersion (1, 11, 2, 3); 185 | } 186 | 187 | IEnumerable Detect1x () 188 | { 189 | var usrPrefix = string.Empty; 190 | var appDriverPath = monoMacAppLauncherPath; 191 | 192 | // 1.2.13 began bundling its own launcher 193 | if (Version >= new AppleSdkVersion (1, 2, 13)) 194 | appDriverPath = Path.Combine (FrameworkDirectory, "lib", "mono", "XamMacLauncher"); 195 | 196 | if (Version < new AppleSdkVersion (1, 4, 0)) 197 | usrPrefix = "usr"; 198 | 199 | yield return MmpPath = Path.Combine (FrameworkDirectory, usrPrefix, "bin", "mmp"); 200 | yield return BmacPath = Path.Combine (FrameworkDirectory, usrPrefix, "bin", "bmac"); 201 | yield return LegacyFrameworkAssembly = Path.Combine (FrameworkDirectory, usrPrefix, "lib", "mono", "XamMac.dll"); 202 | LegacyAppLauncherPath = appDriverPath; 203 | 204 | if (LegacyAppLauncherPath != null) 205 | yield return LegacyAppLauncherPath; 206 | 207 | yield break; 208 | } 209 | 210 | void NotInstalled (string pathMissing, bool error = true) 211 | { 212 | versions = new PDictionary (); 213 | lastWriteTimes.Clear (); 214 | IsInstalled = false; 215 | Version = new AppleSdkVersion (); 216 | 217 | SdkNotInstalledReason = string.Format ("Xamarin.Mac not installed. Can't find {0}.", pathMissing); 218 | 219 | if (error) 220 | LoggingService.LogError (SdkNotInstalledReason); 221 | else 222 | LoggingService.LogInfo (SdkNotInstalledReason); 223 | } 224 | 225 | AppleSdkVersion ReadVersion (string versionPath) 226 | { 227 | try { 228 | return AppleSdkVersion.Parse (File.ReadAllText (versionPath).Trim ()); 229 | } catch (Exception ex) { 230 | LoggingService.LogError ("Failed to read Xamarin.Mac version", ex); 231 | return new AppleSdkVersion (); 232 | } 233 | } 234 | 235 | public void CheckCaches () 236 | { 237 | try { 238 | foreach (var path in lastWriteTimes) { 239 | if (File.GetLastWriteTimeUtc (path.Key) != path.Value) { 240 | Init (); 241 | return; 242 | } 243 | } 244 | } catch (IOException) { 245 | Init (); 246 | } 247 | } 248 | 249 | bool CheckSupportsFeature (string feature) 250 | { 251 | PArray features; 252 | 253 | if (!versions.TryGetValue ("Features", out features)) { 254 | features = CreateDefaultFeatures (Version); 255 | versions.Add ("Features", features); 256 | } 257 | 258 | foreach (var item in features.OfType ().Select (x => x.Value)) { 259 | if (feature == item) 260 | return true; 261 | } 262 | 263 | return false; 264 | } 265 | 266 | public bool SupportsMSBuild { 267 | get { return Version >= new AppleSdkVersion (1, 9, 0); } 268 | } 269 | 270 | public bool SupportsV2Features { 271 | get { return Version >= new AppleSdkVersion (1, 9, 0); } 272 | } 273 | 274 | public bool SupportsNewStyleActivation { 275 | get { return Version >= new AppleSdkVersion (1, 9, 0); } 276 | } 277 | 278 | public bool SupportsFullProfile { get; private set; } 279 | 280 | public bool SupportsSGenConcurrentGC { 281 | get { return CheckSupportsFeature ("sgen-concurrent-gc"); } 282 | } 283 | 284 | public bool SupportsRefCounting { 285 | get { return CheckSupportsFeature ("ref-counting"); } 286 | } 287 | 288 | public bool SupportsHttpClientHandlers { 289 | get { return CheckSupportsFeature ("http-client-handlers"); } 290 | } 291 | 292 | public bool SupportsMonoSymbolArchive { 293 | get { return CheckSupportsFeature ("mono-symbol-archive"); } 294 | } 295 | 296 | public bool SupportsLinkPlatform { 297 | get { return CheckSupportsFeature ("link-platform"); } 298 | } 299 | 300 | public bool SupportsHybridAOT { 301 | get { return CheckSupportsFeature ("hybrid-aot"); } 302 | } 303 | 304 | public bool SupportsSiriIntents { 305 | get { return CheckSupportsFeature ("siri-intents"); } 306 | } 307 | 308 | public ExtendedVersion ExtendedVersion { 309 | get { 310 | if (extended_version == null) { 311 | extended_version = ExtendedVersion.Read (Path.Combine (FrameworkDirectory, "buildinfo")); 312 | } 313 | return extended_version; 314 | } 315 | } 316 | } 317 | } 318 | -------------------------------------------------------------------------------- /Xamarin.MacDev/Xamarin.MacDev.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | netstandard2.0 5 | true 6 | false 7 | latest 8 | 9 | 10 | 11 | runtime; build; native; contentfiles; analyzers 12 | all 13 | 14 | 15 | 16 | 17 | Microsoft400 18 | 19 | 20 | 21 | --------------------------------------------------------------------------------