Ошибка после обновления до Azure Mobile Services 1.3.1

У меня есть проект Xamarin.iOS, и я недавно обновил его, а также мой проект PCL, чтобы иметь Windows Azure Mobile Services SDK 1.3.1.

Однако теперь я получаю сообщение об ошибке, когда он пытается создать новый MobileServiceClient.

{System.NullReferenceException: Object reference not set to an instance     an object
at Microsoft.WindowsAzure.MobileServices.MobileServiceHttpClient.GetUserAgentHeader () [0x0002e] in d:\jw\ZumoSDKBuild_Dev\source\sdk\Managed\src\Microsoft.WindowsAzure.MobileServices\Http\MobileServiceHttpClient.cs:683 
at Microsoft.WindowsAzure.MobileServices.MobileServiceHttpClient..ctor (IEnumerable`1 handlers, System.Uri applicationUri, System.String installationId, System.String applicationKey) [0x0004e] in d:\jw\ZumoSDKBuild_Dev\source\sdk\Managed\src\Microsoft.WindowsAzure.MobileServices\Http\MobileServiceHttpClient.cs:138 
at Microsoft.WindowsAzure.MobileServices.MobileServiceClient..ctor (System.Uri applicationUri, System.String applicationKey, System.Net.Http.HttpMessageHandler[] handlers) [0x00040] in d:\jw\ZumoSDKBuild_Dev\source\sdk\Managed\src\Microsoft.WindowsAzure.MobileServices\MobileServiceClient.cs:199 
at Microsoft.WindowsAzure.MobileServices.MobileServiceClient..ctor (System.Uri applicationUri, System.String applicationKey) [0x00000] in d:\jw\ZumoSDKBuild_Dev\source\sdk\Managed\src\Microsoft.WindowsAzure.MobileServices\MobileServiceClient.cs:150 
at Microsoft.WindowsAzure.MobileServices.MobileServiceClient..ctor (System.String applicationUrl, System.String applicationKey) [0x00000] in d:\jw\ZumoSDKBuild_Dev\source\sdk\Managed\src\Microsoft.WindowsAzure.MobileServices\MobileServiceClient.cs:135 
at MyApp.App..ctor () [0x00009] in c:\Users\adam\Documents\Visual Studio 2013\Projects\MyApp\App.cs:30 }

Глядя на исходный код MobileServiceClient, вот функция, в которой он не работает.

            private string GetUserAgentHeader() 
678         { 
679             AssemblyFileVersionAttribute fileVersionAttribute = typeof(MobileServiceClient).GetTypeInfo().Assembly 
680                                                                         .GetCustomAttributes(typeof(AssemblyFileVersionAttribute)) 
681                                                                         .Cast<AssemblyFileVersionAttribute>() 
682                                                                         .FirstOrDefault(); 
683             string fileVersion = fileVersionAttribute.Version; 
684             string sdkVersion = string.Join(".", fileVersion.Split('.').Take(2)); // Get just the major and minor versions 
685 

686             IPlatformInformation platformInformation = Platform.Instance.PlatformInformation; 
687             return string.Format( 
688                 CultureInfo.InvariantCulture, 
689                 "ZUMO/{0} (lang={1}; os={2}; os_version={3}; arch={4}; version={5})", 
690                 sdkVersion, 
691                 "Managed", 
692                 platformInformation.OperatingSystemName, 
693                 platformInformation.OperatingSystemVersion, 
694                 platformInformation.OperatingSystemArchitecture, 
695                 fileVersion); 
696         } 

Я понятия не имею, что конкретно вызывает ошибку. Любая помощь приветствуется.

Обновить

Если я запускаю следующий код прямо в своем приложении, прежде чем пытаться инициализировать MobileServiceClient

AssemblyFileVersionAttribute fileVersionAttribute = typeof(MobileServiceClient).GetTypeInfo().Assembly 
                                                                        .GetCustomAttributes(typeof(AssemblyFileVersionAttribute)) 
                                                                        .Cast<AssemblyFileVersionAttribute>() 
                                                                         .FirstOrDefault(); 
             string fileVersion = fileVersionAttribute.Version; 

С Don't Link все работает отлично. Если я запускаю его с помощью Link SDK или Link All, тогда сборка равна нулю.

Куда идти отсюда, я пока не уверен.


person Adam    schedule 18.02.2015    source источник


Ответы (3)


Наконец-то я нашел способ предотвратить связывание библиотеки Azure Mobile Services, не отключая связывание для всего остального.

Можете добавить

--linkskip=Microsoft.WindowsAzure.Mobile --linkskip=Microsoft.WindowsAzure.Mobile.Ext

to Дополнительные аргументы mtouch в параметрах сборки iOS в настройках проекта для проекта iOS.

Это пропустит компоновщик для лазурных сборок, но не для остальных. Дополнительные сведения о компоновщике можно найти по адресу http://developer.xamarin.com/guides/ios/advanced_topics/linker/#Skipping_Assemblies

person Dimse    schedule 15.04.2015
comment
Я пытался найти команды компоновщика, чтобы сделать это, однако документация компоновщика настолько скудна. Определенно лучший способ сделать это, однако мой снова начал работать над сборками Link SDK по какой-то совершенно неизвестной причине. - person Adam; 15.04.2015

Целью связывания является уменьшение общего размера приложения за счет исключения неиспользуемых пространств имен, классов и членов. Связывание большинства приложений потребует ручного итеративного процесса:

  1. Включите полное связывание для любой конфигурации сборки, которая вас интересует.
  2. Очистите и соберите приложение.
  3. Запустите приложение и посмотрите, какие исключения во время выполнения возникают в результате отсутствия типов и методов (включая конструкторы).
  4. Добавьте правила либо в аргументы команды mtouch, либо в XML-файл описания ссылки, чтобы пропустить ссылки на пространства имен, типы и классы, которые, по вашему мнению, вызывают исключения.

Чтобы связать приложение, использующее PCL клиента мобильных служб Azure, следует использовать тот же итеративный процесс, о котором я только что говорил.

Я предпочитаю стратегию сохранения ссылок в файле конфигурации на основе XML: https://developer.xamarin.com/guides/cross-platform/advanced/custom_linking/

Файл XML широко известен как файл определения ссылки. Это позволяет вам управлять компоновщиком декларативным образом, не добавляя атрибуты [Preserve] повсюду в ваш код; и для сторонних библиотек, не запутывая аргументы mtouch проектов Xamarin.iOS или файл csproj проектов Xamarin.Android. Его можно назвать как угодно, если вы правильно сообщите об этом в своем проекте платформы.

Соответствующая конфигурация может выглядеть так:

<?xml version="1.0" encoding="UTF-8" ?>
<linker>
    <assembly fullname="Microsoft.WindowsAzure.Mobile">
        <type fullname="Microsoft*" />
    </assembly>
    <assembly fullname="Microsoft.WindowsAzure.Mobile.Ext">
        <type fullname="Microsoft*" />
    </assembly>
</linker>

В каждом узле сборки вы описываете типы или элементы, которые хотите сохранить. Для простоты здесь я использовал подстановочный знак для включения всех типов, начинающихся с «Microsoft». Это соответствует полному имени, включая пространство имен.

Однако, как уже говорилось, вы столкнетесь с проблемой выполнения метода GetUserAgentHeader() в классе MobileServiceHttpClient: введите здесь описание изображения

К счастью, исходный код доступен. Итак, я вытащил источник и сослался на него в своем проекте. Исключение возникает в строке 699, где делается попытка получить свойство Version переменной fileVersionAttribute. Но fileVersionAttribute равно null!... когда связано. Оператор LINQ, который начинается в строке 695 возвращает значение null, если включено связывание. Он действительно возвращает допустимое значение, если не связан; значение "1.0.0.0".

ЗАЧЕМ? Я еще не совсем уверен. Но это основная причина исключения.

В любом случае, на данный момент мне придется включить источник мобильной службы Azure в свой проект и искусственно установить для этого значения значение "1.0.0.0"... что грязно, и я не доволен этим.

string fileVersion = fileVersionAttribute?.Version ?? "1.0.0.0";

ИЗМЕНИТЬ:

Проблема, поднятая на github: https://github.com/Azure/azure-mobile-services/issues/855

person NovaJoe    schedule 18.11.2015

мне нужно было добавить

CurrentPlatform.Init(); 

в AppDelegate в FinishedLaunching

Во-вторых, в проекте iOS мне нужно было перейти к

Properties > iOS Build > Linker Behavior and set it to "Don't link"

Я до сих пор не считаю это ответом, на данный момент это просто плохая работа.

person Adam    schedule 19.02.2015
comment
Вызов CurrentPlatform.Init() был добавлен в качестве требования несколько версий назад, поэтому, если вы обновлялись с очень старой версии, ожидалось, что это необходимо. Однако уверены ли вы, что вариант «не связываться» — это единственный вариант ссылки, который вам подходит? - person Paul Batum; 25.02.2015
comment
Да, в противном случае он каждый раз вылетает, и я действительно хочу найти способ обойти это, потому что это резко увеличивает размер моего файла, так что после того, как Apple обработает его, он также превысит ограничение в 100 МБ. - person Adam; 26.02.2015
comment
Я буду больше разбираться, почему это происходит на следующей неделе или около того, и я опубликую здесь любые выводы или решение, если я его найду. - person Adam; 26.02.2015