niedziela, 21 sierpnia 2016

Xamarin.iOS kontra Swift odc.4 (ustawienia aplikacji, sockety)

Xamarin kontra Swift, witam serdecznie. Dziś upamiętnimy odcinki o iOS z czasów DSP nr. 7 i 8. To sprawadza w zasadzie aplikację w C# do poziomu funkcjonalności w Swift, jaką osiągnąłem na koniec maja (i DSP).

IMG_0049  

Zacznijmy od ustawień. Taki efekt jak na powyższym screenie osiągniemy jak wgramy aplikację skompilowaną jako Release, w Debug Xamarin dodatkowo dodaje swoją sekcję w ustawieniach. W Visual Studio nie ma takiego kreatora do ustawień jak w Xcode, pliki trzeba tworzyć ręcznie w folderze Settings.bundle (ja je skopiowałem z projektu Xcode):

image

W AppDelegate stworzyłem odpowiedniki metod do wczytywania domyślnych wartości:

        private void PopulateRegistrationDomain()
        {
            var appDefaults = LoadDefaultsFromSettingsPage();

            var defaults = NSUserDefaults.StandardUserDefaults;
            defaults.RegisterDefaults(appDefaults);
            defaults.Synchronize();
        }

        private NSDictionary LoadDefaultsFromSettingsPage()
        {
            var settingsDict = new NSDictionary(NSBundle.MainBundle.PathForResource("Settings.bundle/Root.plist", null));

            var prefSpecifierArray = settingsDict["PreferenceSpecifiers"] as NSArray;

            if (prefSpecifierArray == null)
                return null;

            var keyValuePairs = new NSMutableDictionary();

            foreach (var prefItem in NSArray.FromArray<NSDictionary>(prefSpecifierArray))
            {
                var prefItemType = prefItem["Type"] as NSString;
                var prefItemKey = prefItem["Key"] as NSString;
                var prefItemDefaultValue = prefItem["DefaultValue"] as NSString;

                if (prefItemType.ToString() == "PSChildPaneSpecifier")
                {
                   
                }
                else if (prefItemKey != null && prefItemDefaultValue != null)
                {
                    keyValuePairs[prefItemKey] = prefItemDefaultValue;
                }
            }

            return keyValuePairs;
        }

Jest dużo podobieństwa, choć są też pewne różnice np. w metodzie ładującej zasoby.

Największą niespodzianką był jednak fakt, że metoda ViewWillAppear w ViewController nie jest w ogóle wywoływana! (przynajmniej na fizycznym urządzeniu). Patrzyłem w necie i jest całkiem sporo tego typu zgłoszeń, w tym na forum Xamarin. Nasłuchiwanie zmian w konfiguracji umieściłem więc w metodzie ViewDidLoad, podobnie jak w przykładzie od Xamarin, a także innych notyfikacji w mojej aplikacji.

NSObject notificationToken3;

        public override void ViewDidLoad()
        {

              …
              notificationToken3 = notificationCenter.AddObserver(NSUserDefaults.DidChangeNotification, DefaultsChanged);

              …
        }  

        public override void DidReceiveMemoryWarning()
        {
               …

               notificationToken3.Dispose();
        }

        private async void DefaultsChanged(NSNotification notification)
        {
            try
            {
                var defaults = NSUserDefaults.StandardUserDefaults;
                var useRemoteDevice = defaults.BoolForKey("use_remote_device_preference");

                if (remoteController != null)
                    await ReleaseRemoteController();

                if (useRemoteDevice)
                {
                    await CreateNewRemoteController(defaults);                  
                }

             }
            catch (Exception)
            {
               
            }
        }

Kod w ostatniej zaprezentowanej tu metodzie skłania do przejścia do drugiego zagadnienia tego odcinka, a mianowicie socketów. W kontrolerze ViewController wykorzystałem klasę LightsRemoteController z projektu LightOrganApp.Shared używaną już wcześniej przez aplikację w Xamarin.Android. To właśnie jest przykład na siłę i moc Xamarina, jaką jest współdzielenie kodu między platformami. Komunikacja z Raspberry Pi działa bez problemu:

IMG_20160821_120331

I tym sprzętowym akcentem zakończymy ten odcinek Winking smile

Brak komentarzy: