{"id":18361793,"url":"https://github.com/rubo/missinkit","last_synced_at":"2025-10-27T09:02:48.714Z","repository":{"id":147344453,"uuid":"59704369","full_name":"rubo/missinkit","owner":"rubo","description":"Some missing stuff for Xamarin.iOS","archived":false,"fork":false,"pushed_at":"2019-03-18T22:17:56.000Z","size":51,"stargazers_count":2,"open_issues_count":1,"forks_count":0,"subscribers_count":2,"default_branch":"develop","last_synced_at":"2025-02-15T19:16:42.867Z","etag":null,"topics":["localization","reachability","stringsdict","utilities","xamarin"],"latest_commit_sha":null,"homepage":"","language":"C#","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/rubo.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2016-05-25T23:23:20.000Z","updated_at":"2022-05-19T21:55:12.000Z","dependencies_parsed_at":"2023-07-03T19:33:12.894Z","dependency_job_id":null,"html_url":"https://github.com/rubo/missinkit","commit_stats":null,"previous_names":[],"tags_count":6,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rubo%2Fmissinkit","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rubo%2Fmissinkit/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rubo%2Fmissinkit/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rubo%2Fmissinkit/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/rubo","download_url":"https://codeload.github.com/rubo/missinkit/tar.gz/refs/heads/develop","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248157358,"owners_count":21056996,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["localization","reachability","stringsdict","utilities","xamarin"],"created_at":"2024-11-05T22:35:29.272Z","updated_at":"2025-10-27T09:02:48.623Z","avatar_url":"https://github.com/rubo.png","language":"C#","funding_links":[],"categories":[],"sub_categories":[],"readme":"# MissinKit\n[![NuGet](https://img.shields.io/nuget/v/MissinKit.svg)](https://www.nuget.org/packages/MissinKit)\n\n## License\nThe code is released under the [MIT License](https://opensource.org/licenses/MIT).\n\n## What's Inside?\n#### iOS Native Pluralization\nAs Xamarin's current `NSString.LocalizedFormat()` method is useless,\nthere's no way to use iOS native pluralization. To turn this very important feature on,\nthere's the `NSStringUtility.LocalizedFormat()` method to replace Xamarin's counterpart:\n```csharp\nNSStringUtility.LocalizedFormat(NSBundle.MainBundle.GetLocalizedString(\"%d file(s) remaining\"), 2)\n```\nIf key is found, it formats the string accordinig to the .stringsdict file. Otherwise, it falls back and prints \"2 file(s) remaining\".\n\nWARNING! The `NSStringUtility.LocalizedFormat()` method does not work on 64-bit simulators.\n\nInstead of using the `NSStringUtility.LocalizedFormat()` or `NSBundle.GetLocalizedString()` methods directly,\nuse the convenient extension methods which are more than enough for the vast majority of cases:\n```csharp\n// instead of\nstr = NSBundle.MainBundle.GetLocalizedString(\"key\");\n// use\nstr = \"key\".Localize();\n\n// instead of\nstr = string.format(NSBundle.MainBundle.GetLocalizedString(\"key\"), 2, \"text\");\n// use\nstr = \"key\".Localize(2, \"text\");\n\n// instead of\nstr = NSStringUtility.LocalizedFormat(NSBundle.MainBundle.GetLocalizedString(\"key\"), 3);\n// use\nstr = \"key\".Localize(3);\n```\nThese methods work with both .strings and .stringsdict files.\n\n#### Network Reachability\nThe `Reachability` class is a port of Apple's Reachability sample app to monitor the network state of an iOS device.\n```csharp\nvar r = new Reachability(\"apple.com\");\nr.ReachabilityChanged += (s, e) =\u003e Debug.WriteLine($\"Network Status: {r.Status}\");\n```\n\n#### Date Utilities\nThere are two extension methods providing a quick way to convert `DateTime` to `NSDate` and vice-versa.\n```csharp\nNSDate nsdate = DateTime.Now.ToNSDate();\nDateTime datetime = nsdate.ToDateTime();\n```\nNot a big deal, but convenient.\n\n#### Changing Current Locale on the Fly\nSince iOS doesn't provide an easy way to change `NSLocale.CurrentLocale` programmatically,\nthere's a utility to help with that.\n```csharp\nvar date = new DateTime(2018, 1, 1).ToNSDate();\nvar formatter = new NSDateFormatter() { DateFormat = \"EEEE\" };\n\nL10n.OverrideCurrentLocale(\"es_MX\");\n\nformatter.Locale = NSLocale.CurrentLocale;\nDebug.WriteLine(formatter.StringFor(date)); // outputs 'lunes'\n\nL10n.RestoreCurrentLocale();\n\nformatter.Locale = NSLocale.CurrentLocale;\nDebug.WriteLine(formatter.StringFor(date)); // outputs 'Monday'\n```\nOverriding or restoring the current locale triggers `NSCurrentLocaleDidChangeNotification`.\n\n#### iOS 11 Fallback\nSince iOS 11 introduced some breaking changes to UIView layout handling,\nthere are a few fallback extension methods to reduce boilerplate code required to handle those changes.\n\nThe `SafeAreaLayoutGuide()` method returns the `UIVIew.SafeAreaLayoutGuide` for iOS 11 and later\nand falls back to a layout guide based on the frame rectangle of the current view for older systems.\n```csharp\nvar insets = view.SafeAreaLayoutGuide();\n```\nThe `SafeAreaLayoutGuide()` method uses the frame layout guide as a fallback.\nThe frame layout guide is a layout guide anchors of which simply return its owning view's anchors.\nThe frame layout guide is created using the `FrameLayoutGuide()` extension method\nwhich is especially helpful for the scenarios like this:\n```csharp\nvar isIos11OrLater = UIDevice.CurrentDevice.CheckSystemVersion(11, 0);\nvar widthAnchor = isIos11OrLater ? view.SafeAreaLayoutGuide.WidthAnchor : view.WidthAnchor;\nvar heightAnchor = isIos11OrLater ? view.SafeAreaLayoutGuide.HeightAnchor : view.HeightAnchor;\n// more checks here...\n```\nTo avoid checking for all anchors of the view you need, simple use the frame layout guide:\n```csharp\nvar layoutGuide = isIos11OrLater ? view.SafeAreaLayoutGuide : view.FrameLayoutGuide();\n```\nThis is exactly what the `SafeAreaLayoutGuide()` method does so you don't even need to check the system version.\nBut you can use the `FrameLayoutGuide()` method as a fallback for other layout guides introduced in iOS 11 if needed.\n\nThe initial call of the `FrameLayoutGuide()` method adds the returned layout guide to the view's layout guides,\nso all subsequent calls return the already existing instance instead of creating a new one every time.\n\nNote that the `FrameLayoutGuide()` method returns the `FrameLayoutGuide` property for `UIScrollView`.\n\nThe `SafeAreaInsets()` method returns the `UIVIew.SafeAreaInsets` for iOS 11 and later\nand falls back to UIEdgeInsets.Zero for older systems.\n```csharp\nvar insets = view.SafeAreaInsets();\n```\nThe `AdjustedContentInset()` method returns the `UIScrollView.AdjustedContentInset` for iOS 11 and later\nand falls back to `UIScrollView.ContentInset` for older systems.\n```csharp\nvar insets = scrollView.AdjustedContentInset();\n```\n\n#### Update Watcher\nThis is a simple utility for a quick check for app updates in App Store.\n```csharp\nvar updateWatcher = new UpdateWatcher(3); // Checks every 3 days\nvar updateAvailable = await updateWatcher.CheckForUpdateAsync();\n\nif (updateAvailable)\n    // Notify user\n```\n\n#### Machine Epsilon\nAs on some ARM devices both `float.Epsilon` and `double.Epsilon` equate to zero, the constants `MachineEpsilon.Single` and `MachineEpsilon.Double` are recommended to be used instead.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frubo%2Fmissinkit","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Frubo%2Fmissinkit","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frubo%2Fmissinkit/lists"}