2条留言

显示一辆带有出租车条纹的黄色大众巴士的Wall-E前方

我很喜欢 极好 -Xamarin.Forms的包装,使您可以使用F#编写功能性UI。初次查看项目时,我注意到它是建立在 AppVeyor 特拉维斯 。我问自己:为什么要使用两个CI系统来编译一个项目?经过进一步的挖掘,我发现AppVeyor上没有托管的macOS代理。另一方面,Travis确实提供了适用于Windows和macOS的代理,但没有在代理上安装Xamarin工具链。每次运行都安装Xamarin工具链会导致30分钟以上的构建时间。以来 Azure开发运营 支持在Windows和macOS上进行构建我想我会尝试一下并设置管道来构建Fabulous-我的意思是这有多难?很难写一篇博客文章来总结克服陷阱的步骤

TLDR:如何在Azure DevOps上运行FAKE脚本

神话般的用途 执行构建,测试和创建NuGet包。 假 是用于编写构建脚本的功能强大的完整工具。假也是 .Net Core CLI工具 该工具专为从命令行安装和执行而设计,因此非常适合在任何构建服务器上运行。

安装假

Azure开发运营 构建代理不预装有FAKE。由于FAKE是.Net Core CLI工具,因此这没有问题。以下命令应解决此问题:

dotnet tool install fake-cli -g

不幸的是,安装后执行FAKE失败。这是因为Azure DevOps构建代理上的安装目录不同于.Net Core的标准安装位置-为什么?您问,那么给出的答案就是安全性。在Windows上,我们可以通过将FAKE安装到Workspace目录中来避免这一情况:

dotnet tool install fake-cli --tool-path .

在macOS(和Linux)下,这种方法仍然会失败。的 建议的解决方案 is to set DOTNET_ROOT. I ended up with the following lines to be executed on the 苹果系统 agent:

export DOTNET_ROOT=$HOME/.dotnet/
export PATH=$PATH:$HOME/.dotnet/tools:/Library/Frameworks/Mono.framework/Versions/Current/Commands
dotnet tool install fake-cli -g

在Linux上,该方法不得不再次采用-实在是很重要。我结束了这些行:

export PATH=$PATH:$HOME/.dotnet/tools:/Library/Frameworks/Mono.framework/Versions/Current/Commands
dotnet tool install fake-cli -g

现在您应该可以在Azure DevOps上运行FAKE脚本

使用NuGetFallbackDirectory

This part is not directly related to 假 but is something I stumbled over while running on Azure开发运营 . One test script was referencing the NuGet packages via the global NuGetFallbackDirectory 和 was looking for them under the default location. Under 苹果系统 the location is in the users home directory, so adopting the path as follows did the trick:

let tfsEnvironment = Environment.GetEnvironmentVariable("TF_BUILD")
if (String.IsNullOrEmpty(tfsEnvironment)) then
    "/usr/local/share/dotnet/sdk/NuGetFallbackFolder"
else
    let homepath = Environment.GetEnvironmentVariable("HOME")
    Path.Combine(homepath, ".dotnet/sdk/NuGetFallbackFolder")

Note that the variable TF_BUILD is expected to only be set on TFS/VSTS/Azure DevOps. This will allow the script to fall back to the default location should it be executed on a developers machine.

但是,为什么还要打扰呢?

从工作中的CI迁移到另一个CI的动机是什么?您是否在做,因为您是Microsoft MVP?

这些是与同事谈论我在Azure DevOps上构建Fabulous的工作时遇到的问题。我认为AppVeyor和Travis是很棒的工具,它们表明他们有能力完成任务和测试Fabulous。除了因为我好奇它的难易程度外,我还想从两个方面尝试将生成版本迁移到Azure DevOps:

  1. 合并构建,让两个地方做一件事情总是伴随着开销。
  2. 另一个人正在看到无需安装Xamarin可以减少多少构建时间。

因此,这是之前和之后的构建时间之间的比较:

CI平台 代理操作系统 建立 测试 时间(分钟)
特拉维斯 苹果系统 ~30-32
Azure开发运营 苹果系统 ~13-14
AppVeyor 视窗 ~4
Azure开发运营 视窗 ~6

现在要记住,在macOS和Windows上的构建是并行运行的。因此,对于AppVeyor和Travis而言,生成时间为30-32分钟。借助Azure DevOps,这可以减少到13-14分钟。

我认为将两个构建脚本合并为一个并将构建时间减少大约一半是一个很好的理由,说明为什么Azure DevOps似乎更适合Fabulous。再说一次,运行.Net CLI工具时会遇到一些麻烦,我希望Azure DevOps团队将来会解决-由同一家公司和所有 咳嗽

另一个方面是将来在Linux上进行构建,因为Fabulous自0.30开始支持GTK,因此也可以在Linux上编译它。在撰写本文时,Fabulous的构建过程中仍然存在一些问题,但是将来没有什么不能解决的。

谢谢

谢谢 蒂莫西·拉里维耶(TimothéLarivière) 斯图尔特·朗 对于沿途的所有提示和提示

1条评论

显示工厂的标题图像

Azure开发运营 (以前简称为Visual Studio团队服务或VSTS)使您可以为所有不同类型的项目创建自动发布管道。一件好事是,您可以获得免费的开源项目构建时间。那么,为什么不试一下,看看我是否可以为我的开源项目设置构建管道 PureLayout .Net。 PureLayout .Net库是对 PureLayout 用Objective-C编写的iOS库,可让您快速在代码中布局UI。因此,它与标准Xamarin项目有所不同,因为它涉及以下步骤:构建项目,创建与C#的绑定,然后将所有内容打包到NuGet包中。由于这是一个仅限iOS的项目,因此我们当然必须在Mac上进行构建。

选择构建代理

太好了,您Azure DevOps(将来我们都可以同意ADO吗?)提供了一个托管在Azure上的Mac构建代理。现在剩下的问题是,托管的Mac是否可以提供我们需要的所有工具?如果没有,我们将不得不选择创建自己的Mac构建代理,即从第三方租用它。对于PureLayout.Net,我们需要安装以下工具:

幸运的是 的GitHub 列出了代理程序OS和工具。因此,我们看到了Xamarin工具链和XCode。不幸的是,没有安装objective-sharpie,虽然有点退缩,但我们在托管的macOS代理上看到的安装是 自制 .

Homebrew

Homebrew是macOS的软件包管理器,它允许开源项目将其工具作为软件包提供。在互联网上快速搜索表明,有一个小桶可以说是客观的夏普-是的,他们一直在酝酿类比。因此,我们可以在运行构建之前安装该工具。因此,让我们继续,并使用ADO托管的macOS代理设置构建。

托管与设置Build Agent: 在自己设置代理与选择代理之间进行选择时,需要考虑一些事项 寄存器 ADO还是选择托管的构建代理。虽然这始终取决于您的情况。一般来说,设置构建代理可以使您更好地控制设置和安装的工具。您可以决定何时进行更新,并可以选择预先设置数据库/文件等,以便重新使用。另一方面,您必须维护您的代理,尽管起初这可能行得通。考虑必须维护多个代理。您如何确保所有代理均设置相同?设置中的微小差异可能会导致构建基础架构不稳定,这是没人想要的。如果您没有阻止您使用托管代理的任何要求,我建议您走简单的路线并使用托管代理。托管代理具有附加的优势,能够根据您的工作量调整代理数量-如果您是咨询公司,这可能是一笔巨大的收获,因为项目/构建负载可能会不时变化。

配置构建

如今,ADO已将其称为浏览器,用于设置构建配置或管道。尽管ADO确实为特定版本(例如Xamarin.Android)提供了模板,但Xamarin.iOS包装项目没有模板-除了空白模板。第一步是连接存储库(如果PureLayout.Net在GitHub上)。第一次,必须遵循以下步骤将GitHub与ADO帐户关联起来 指示 .

手动构建PureLayout.Net时。以下步骤创建一个新版本的PureLayout.Net:

  1. 执行制作
  2. 建立解决方案
  3. 将文物包装到NuGet包中
  4. 享受新的NuGet包

The Makefile creates the native binary (and generate the required wrapping code). To create the wrapper, we require objective sharpie which we can install via Homebrew. To execute all the required commands in ADO a Command Line build step with the following 指示 is used:

echo install objective sharpie
brew cask install objectivesharpie
echo Performing make
make

如果您想深入了解创建包装项目的麻烦之处。一定要看看这个 文章 通过 山姆·德布吕因 -当然看完这篇帖子。

Next up is building the solution of the wrapper project, which can be done with an MSBuild step 和 defining the path to the csproj file: PureLayout .Binding/PureLayout.Binding/PureLayout.Net.csproj - there is even a handy repo browser. Under Configuration, you can set the build configuration to Release, but instead of hard coding it, consider using the environment variable $(BuildConfiguration). More about environment variables in a bit.

ADOVisualBuildConfiguration

Next up is packing the compiled output into a NuGet package. By adding a NuGet build step, setting the Command to pack, the path to the csproj file 和 the output folder to the ADO environment variable $(Build.ArtifactStagingDirectory).

最后一步是发布人工制品,即NuGet包。这里又有一个标准的构建步骤,称为 发布构建工件.

您是否还在想上面的那些环境变量以及它们如何组合在一起?环境变量是减少构建步骤中重复的书面配置的好方法。您可以定义两种环境变量 你自己 还有那些 预定义的 .

出于创建目的或正在探索ADO必须提供的Web UI,这是一个不错的选择。但是,如果您与成年的DevOps工程师交谈,他们通常会对可维护性或缺乏共享的可配置定义表示担忧。解决这些问题的方法之一是在YAML文件中定义整个构建步骤。

使用YAML配置构建

YAML不是标记语言,简称YAML,是ADO支持的用于将构建配置与代码一起存储的文件格式。每当用户在UI中更改构建步骤时,ADO也会完成版本控制。 YAML定义还允许您为其他类似项目创建模板-可以节省时间。

选择构建代理时,我们可以查看通过Web UI定义的构建步骤之外生成的YAML。

YamlExtract

In the projects root folder, we can now create a file, e.g. builddefinition.yaml which we can then check in to Git. Once the Git Repo contains the YAML build configuration, we can create a new pipeline based on the build config. Unfortunately, there is currently no way to use the visual designer 和 YAML configuration in the same pipeline.

尽管未自动导出,但构建触发器也可以在YAML文件中设置。根据文档-其中包括一些启发性示例,这是PureLayout.Net的结果块:

trigger:
  batch: true
  branches:
    include:
    - master
  paths:
    exclude:
    - README.md
pr:
  branches:
    include:
    - master
  paths:
    exclude:
    - README.md

The above configuration ensures that all pushes to master are triggering a build. The pr section is in regards to Pull Requests. Note the neat trick you can do with paths which allows you to prevent triggering a build should only the README.md or similar change.

学习到教训了: 关于git的任何配置更改,您仍然必须在可视设计器中进行。对于PureLayout.Net,它可以确保检出git子模块。

YAML是否比基于Web的可视ADO更好?这要看情况。如果您刚刚开始设置自动管道,则可视化编辑器可提供更快的结果。当发现ADO上可用的内容时,它还会提供更好的体验。但是,如果您正在寻找一种共享配置的方法,请将构建定义与代码一起存储,并知道要完成的工作。 YAML可能是您更好的解决方案。

您可以在上看到PureLayout.Net的完整YAML配置。 这里 .

做完了吗

当我最初开始自动化PureLayout.Net的构建时,这是因为我想减少对我的麻烦,以确保提交或PR不会破坏任何内容。完成上述步骤后,剩下的手动步骤将测试NuGet包,并根据需要调整一些元数据,然后将其部署到NuGet.org。由于它是一个视觉库,因此我手动进行“测试”结果感到很自在-这意味着要看屏幕并亲自检查布局。手动发布步骤对我来说也很好。

但是,您可以实现更多自动化。例如,将工件自动推到Azure工件或其他位置,调整挂起各种参数上的发布元数据,或动态设置版本号。自动化的另一个可能领域是测试方和and...。对我来说,我把它留在这里了,不完全是,我仍然将构建状态发布到GitHub-这个博客:

 建立状态

3条留言

00_TitleImage

我最近将开发人员机器从Surface Pro 3升级到Surface Book2。我已经使用了一个月,希望写下自己的经验以及它如何处理日常任务,我将其记为主要是移动开发人员。那是在办公室和休闲时间。

免责声明: 我没有从Microsoft收到任何写这篇文章的钱,也没有要求他们这样做。我这样做的唯一目的是,当我在寻找新的开发设备时,找不到关于SB2的移动开发文章。

现在,在寻找新计算机时,它总是取决于您活跃的领域。在作为(移动)开发人员,团队负责人,偶尔的演讲者和人类的角色下,我倾向于以多种不同方式使用设备。此外,我一直幻想拥有一台可以处理各种不同工作负载的设备,因此虽然Surface Book可能不是理想的平板电脑,但它可以是一款平板电脑,应该省却了另外一台平板电脑的需求。 iPad或新的Surface Go。但是稍后会更多。

我使用的版本是13.5“型号,配备i7、16 GB RAM,512 GB SSD和NVIDIA GeForce GTX1050。虽然价格不便宜,但它的市场宣传是成为最终的笔记本电脑。

总体印象

13.5英寸英寸的型号配备了精美的屏幕。3000x 2000(267 PPI)的分辨率非常出色,并且显示屏明亮,这意味着您也可以在外面工作。我喜欢的3:2屏幕分辨率对于开发,写作和提高生产力非常有用。

键盘非常好打字。它的感觉很好,键的间距也很好,键的行程也很不错,而且我并没有像某些MacBook Pro使用者购买他们的clackidiclack键盘那样凝视。这里唯一困扰我的是按键的背景照明。这是我对机器最大的不满。一个按键的光线不均匀,对于这种价格的设备来说这很奇怪。此外,它没有用于打开或关闭它的自动传感器。您可以将其手动设置为3个亮度等级(或关闭)。到目前为止,我可以接受,但是令我感到恼火的是,在某些照明环境中,很难打开背景照明来读取按键,因为它们似乎开始与按键的镁银颜色匹配。到目前为止,我从未在其他笔记本电脑上遇到过这个问题,但这可能是因为到目前为止我只有黑键吗?无论如何,如果键盘背光在您的机器上是最糟糕的事情,那么您知道您已经开始老化了

触控板还可以。它是玻璃触控板,可让您到达屏幕上想要的位置。总的来说,我仍然认为MacBook Pro具有更好的触控板,但是当我在笔记本电脑模式下使用该机器时,我从不觉得需要鼠标。因此,您不必担心。

续航时间长达16小时,并配备了专用的GPU电源,Surface Book 2的重量比其他设备重达1.642千克(对帝国主义者而言为3.62磅)。特别是与Surface Pro相比。但是13.5英寸仍然是便携式计算机,您可以将其携带在手提袋中并附带一块大电池,这确实意味着您可以将笨重的充电器留在家里。充电器的确带有方便的USB-A端口,可让您为您的手机/智能手表/智能手表等充电,而无需携带其他充电器。

adapter

将其用作我的日常开发机器

成为二合一设备很棒,但是到最后,我主要将其用作笔记本电脑和开发机。在Noser Engineering的日常工作中,我主要从事移动解决方案(主要是前端)和.Net空间中的其他项目的工作。因此,日常负载通常涉及Visual Studio,某些浏览器(Firefox或Edge),PowerShell(通过UI进行Git感觉很不正确-这是在迫使您的大脑学习命令之后),Outlook,团队以及最后但并非最不重要的Spotify或Groove音乐(当我感觉有些音乐需要编码时,第二个)。

在移动项目上工作时,我经常使用Android模拟器。该仿真器倾向于使用大量的RAM,并且在我的旧设备上,我经常在努力获得不错的性能。但是在Surface Book 2上一切都很好。带有两个USB-A端口,这意味着我在插入任何加密狗或附件(例如LAN适配器,Presenter摇杆等)时都不必担心。

使用模拟器时,拥有触摸屏是一种奖励,因为您可以用手指按需使用该应用程序。再加上用鼠标做手势很麻烦。

在某些项目中,我还必须为某些任务启动虚拟机。虽然16 GB的RAM可以满足一定的要求,但我知道许多需要更多功能的后端开发人员和C ++开发人员。因此,请记住这一点,因为您无法升级Surface Book 2的任何硬件,至少iFixit将此剪辑说服了我。

如果您喜欢游戏或机器学习,拥有专用的GPU是一件好事。自从我开始玩机器学习,这使我可以随时随地玩ML。这很好,Surface Pro也无法提供。

在你的桌子旁

尽管我确实需要不时出差,但我也在办公室做很多工作。在工作中,我有一台27英寸和24英寸的戴尔显示器(菊花链式连接),并且只需将扩展坞连接到我的地面即可。该扩展坞可与Surface Book 2完美配合。我还通过USB-C端口将其与Dell扩展坞配合使用,该扩展坞也可以按预期工作。但是由于我已经有了Surface Dock,所以我很少使用USB-C扩展坞,这也意味着充电时间变慢。

我的显示器没有任何问题(以前我的Surface Pro 3有时在显示器上会出现怪异的停电),因此我可以全力推荐它作为高效的设置。

做会议歌舞uki

没有偶然的聚会,办公室的生活是不完整的,对吗?那么,Surface Book 2在涉及此办公领域时表现如何?很好,键盘非常适合做笔记,如果您决定添加表面笔,则可以在会议中涂鸦erm做笔记。我有提到人脸ID吗?使用Face ID,您可以用自己的脸解锁Surface Book 2-赌您没有看到那本书来了!否,但是认真地,人脸ID可以快速工作,但要延迟1-2秒。因此,当我的设备在闲置了几分钟后在会议中点头时,我曾经不得不输入密码。延迟时间花了很长时间,以至于我放弃了用水笔做笔记的感觉。但是使用Face ID,几乎就像是平板电脑的即时启动。这使笔和OneNote成为会议上做笔记的理想组合。

这些天,很多会议都很遥远。我非常支持在通话时使用摄像头,因为非语言交流是一回事。我很高兴看到Surface Book 2配备5 MP前置摄像头,能够播放1080p高清视频。

将Surface Book 2连接到外部显示器效果很好。您很可能需要一个适配器,我使用USB-C转VGA,HDMI和DVI可以解决大多数问题- 手指交叉。唯一要记住的是3:2的宽高比。由于大多数演示者和监视器都是16:9,因此在复制显示内容时,您将有很多空白。扩展解决了问题,但如果您正面对人们而不是辅助屏幕,则可能会成为问题。我可以和黑酒吧一起过得很好。

在Surface Pro 3上,连接到第二台显示器时,风扇始终处于打开状态。开启相机并共享屏幕后,您便可以聆听风扇从无声到准备起飞的声音。 表面 Book 2保持良好且安静的状态,也就是说,如果您不训练任何神经网络。在这种情况下,您将获得 你又在做什么 你配偶的目光

在旅途中

表面 Book 2一直是很棒的旅行伴侣。我倾向于乘火车旅行,很少乘飞机旅行。无论哪种情况,我都喜欢利用空闲时间来完成一些工作。包括编写电子邮件,博客,演示文稿,通​​常还编写代码。 表面 Book 2从未让我失望过这些任务。唯一要记住的是,它可能比其他笔记本电脑要重一些。但是对我来说,这不是问题。支点铰链可以舒适地将其握在手中。

长达16小时的电池续航时间意味着您即使在进行繁重的工作时也可以保持至少半天的生产力。

停机时间

在停机期间,我倾向于在平板电脑模式或查看模式下更多地使用Surface Book 2,这非常适合在做一些家务活的同时播放电影。这款平板电脑很轻巧,但除了NVIDIA GPU之外,它仍然具有其他功能,因此您手中握有一副完整的PC。平板电脑中的电池不如底座中的电池大。但是,您可以将平板电脑部件直接连接到充电器/底座接口。

04_ViewMode

您很快就会注意到,Windows 10上没有许多设计良好的应用程序可用于平板电脑。 (PDF)阅读器,Netflix,OneNote等都有不错的阅读器,但是与iOS和Android相比,仍然存在一些经过深思熟虑和已实现的应用程序的空间。真是可惜,因为它可以制造出出色的平板电脑,并且具有Face ID,可以立即获得感觉。

底线

我对Surface Book 2感到满意。它可以完成我所有的工作,并且可以作为平板电脑很好地工作,因此我不需要购买另一台用于沙发冲浪和观看电视剧的设备。

我会推荐给朋友并重新购买。从我的角度来看,最明显的负面影响是键盘的背光和价格标签。再一次,我认为您的金钱确实物有所值。

2条留言

显示图书馆的标题图片

当涉及到文件处理和Xamarin表单时,您可以在官方文档中找到所需的全部内容。但是,关于数据的存储位置,文档留有一些空白。而且,亲爱的我说,这甚至可能导致您在App Store中的拒绝...

同样,在使用.Net Standard编写跨平台代码时,它的确取决于要在其上执行应用程序的操作系统(OS)以及存储数据的位置。因此,让我们深入了解Xamarin Forms主要支持的平台。

Xamarin .Essentials

最舒适的方法是使用Xamarin.Essentials。目前仍处于预览状态,并且需要Android 7.1或更高版本。但是,如果这样不能让您眨眼,则可以使用以下选项:

  • 本地存储也已备份。
  • 缓存存储非常适合缓存文件,但更多用于非永久性方面。
  • 与应用程序捆绑在一起的文件,即只读文件。

您可以按以下方式访问文件夹路径:

var rootDirectory = FileSystem.AppDataDirectory;

目前Xamarin.Essentials支持Android,iOS和UWP。因此,如果您的应用程序需要的所有平台均已命名,则您不需要任何其他位置。一定要签出 Xamarin .Essentials 并检查 文件资料 更多细节。

自己做

在大多数情况下,Xamarin.Essentials提供的文件夹就足够了,但是如果您需要其他文件夹(即iOS下的document文件夹),则始终可以自行设置路径。因此,让我们看一下如何实现这一目标。

安卓

现在谈到Android时,您可以按照Microsoft的文档进行操作,并使用以下路径存储文件:

_rootDirectory = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments);

Looking to cache some files, then we can take the path 和 with Path.Combine set the path to the cache folder:

_cacheDirectory = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments), "..", "cache");

如果要将文件存储到SD卡,即Android下的外部存储。您必须将路径从平台项目传递到.Net Standard项目,或使用多目标实现此目标。您可以按照以下方式获取路径:

var sdCardPath = Environment.ExternalStorageDirectory.AbsolutePath;

Note that the Environment 这里 is 安卓 .OS.Environment 和 not System.Environment. So if 安卓 is this easy how hard can 的iOS be?

的iOS

在iOS下存储文件时,需要阅读更多文档。原因是Apple在Sandbox容器中使用了多个子文件夹。以下是对文件存储很重要的文件:

  • 文件: 在此文件夹中,仅应存储用户创建的文件。不应将任何应用程序数据(包括您应用程序的JSON文件)存储在此处。该文件夹将自动备份。

  • 图书馆: 您不希望用户直接访问的任何应用程序数据的理想位置。该文件夹将自动备份。

    • 库/首选项: 您不应该直接访问的子目录。更好地使用 Xamarin .Essentials 用于存储任何键/值数据的库。此数据将自动备份。
    • 库/缓存: 这是存储可以轻松重新创建的数据的绝佳场所。不备份此数据。
  • tmp: 适用于临时文件,不再使用时应将其删除。

有关更详细的列表,请查看 docs 。因此,在存储文件时,您在iOS下,此代码将指向Documents文件夹:

_rootDirectory = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments);

如果打算将信息存储到“库”文件夹中,则可以如下更改目录:

_rootDirectory = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments), "..", "Library");

同样,您可以将路径更改为上述其他位置之一。

超人

超人 apps usually also store their data in a sandbox. Only if in the app's metadata the permission is set 和 a good reason was given, which Microsofts validates on submission to the store, can the app access other file locations outside of the sandbox. 超人 apps also live in a sandbox. The ApplicationData offers to store data locally, roaming or in a temporary location. The local folder can be accessed as follows:

_rootDirectory = Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData);

类似地,可以访问其他位置,例如漫游文件夹(在所有不同设备之间自动同步):

_rootDirectory = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData), "..", "RoamingState");

超人 应用程序沙箱中包含以下目录:

 超人 容器文件夹:AC,AppData,LocalCache,LocalState,RoamingState,设置,SystemAppData,TempState

但是,如果我瞄准其他平台怎么办?

由于Xamarin Forms不再局限于Android,iOS和UWP,因此您可能会发现自己想要在另一个系统(例如Tizen)上写入文件。最好的解决方案是检查应存储数据的给定平台的文档,然后在平台上运行以下代码:

class Gnabber 
{ 
    // ... 
    private IEnumerable<DirectoryDesc> DirectoryDescriptions() 
    { 
        var specialFolders = Enum.GetValues(typeof(Environment.SpecialFolder)).Cast<Environment.SpecialFolder>(); 
        return specialFolders.Select(s => new DirectoryDesc(s.ToString(), Environment.GetFolderPath(s))).Where(d => !string.IsNullOrEmpty(d.Path)); 
    } 
    // ... 
} 
 
class DirectoryDesc 
{ 
    public DirectoryDesc(string key, string path) 
    { 
        Key = key; 
 
        Path = path == null 
            ? "" 
            : string.Join(System.IO.Path.DirectorySeparatorChar.ToString(), path.Split(System.IO.Path.DirectorySeparatorChar).Select(s => s.Length > 18 ? s.Substring(0, 5) + "..." + s.Substring(s.Length - 8, 8) : s)); 
    } 
 
    public string Key { get; set; } 
    public string Path { get; set; } 
}

The code above lists all used folders from the System.Environment.SpecialFolder for the given environment, 和 also provides you with the absolute path. If none of the special folders is the target location, you desired. Try using Path.Combine 和 a path nearby to get to your desired location.

结论

Storing files is not tricky but put some thought into where to store your applications data can go a long way. Xamarin .Essentials may provide all the functionality you need, but if not you usually use the System.Environment.SpecialFolders 和 the System.Environment.GetFolderPath to get access to different folders offered 通过 the platform you are on.

4条留言

显示带有图形的笔记本电脑的图片-看起来很漂亮...

Did you know that with Visual Studio 2017 there was an update in the target project files of your Xamarin Projects? They no longer contain a packages.config file but contain the NuGet references directly in the csproj. Using NuGet references instead of the packages.config file has numerous benefits ranging from performance improvements to only showing your top-level dependencies (no longer will you have a scajilion 包装参考s ).

他们还修复了部分迁移到.Net Standard之后我遇到的讨厌的错误。在Xamarin世界中,迁移到.Net Standard并不是什么新鲜事物。那里有许多博客文章,它们将指导您完成如何将可移植类库(PCL)迁移到.Net Standard的过程。我个人最喜欢的是我第一次阅读的方法 James Montemagnos博客,这非常简单,可以让您保留版本历史记录。

但是根据您创建项目的时间而定,迁移告诉您在输出文件夹中找不到仅在.Net Standard项目中引用的NuGet中的dll,这会在迁移后开始出现编译错误。我在此博客文章中创建的示例应用程序就是这种情况:

显示在应用程序输出文件夹中找不到ReactiveUI dll的编译错误

在示例项目中,我们引用了 ReactiveUI NuGet only in our .Net Standard code 和 therefore do not have a direct NuGet reference in our platform projects. When looking closely at the platform projects we can see that the 安卓 和 的iOS project are using a packages.config file to reference their NuGet packages.

在互联网上可以找到的一种解决方案是将这些NuGet包添加到目标项目中。虽然这样做有效,但是却给人一种令人讨厌的感觉。此外,这可能会导致相当大的膨胀,因为某些项目带有子依赖项,这些子依赖项将全部显示在您的NuGet软件包管理器中。但是有一种更简单的方法,它也减少了恶心

Migrating to the newer Package Reference style can be done 通过 simply right clicking on your packages.config 和 selecting Migrate packages.config to PackageReference...:

Visual Studio对话框显示“迁移到PackageReference”

This action will change the csproj from this:

<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" DefaultTargets=" 建立 " xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
  <Import Project="..\..\packages\Xamarin.Forms.3.1.0.637273\build\netstandard2.0\Xamarin.Forms.props" Condition="Exists('..\..\packages\Xamarin.Forms.3.1.0.637273\build\netstandard2.0\Xamarin.Forms.props')" />
  <!-- File includes  和  that stuff -->
  <ItemGroup>
    <Reference Include="System" />
    <Reference Include="System.Xml" />
    <Reference Include="System.Core" />
    <Reference Include="  Xamarin 表格 .Core, Version=2.0.0.0, Culture=neutral, processorArchitecture=MSIL">
      <HintPath>..\..\packages\Xamarin.Forms.3.1.0.637273\lib\Xamarin.iOS10\Xamarin.Forms.Core.dll</HintPath>
    </Reference>
    <Reference Include="  Xamarin 表格 .Platform, Version=1.0.0.0, Culture=neutral, processorArchitecture=MSIL">
      <HintPath>..\..\packages\Xamarin.Forms.3.1.0.637273\lib\Xamarin.iOS10\Xamarin.Forms.Platform.dll</HintPath>
    </Reference>
    <Reference Include="  Xamarin 表格 .Platform.iOS, Version=2.0.0.0, Culture=neutral, processorArchitecture=MSIL">
      <HintPath>..\..\packages\Xamarin.Forms.3.1.0.637273\lib\Xamarin.iOS10\Xamarin.Forms.Platform.iOS.dll</HintPath>
    </Reference>
    <Reference Include="  Xamarin 表格 .Xaml, Version=2.0.0.0, Culture=neutral, processorArchitecture=MSIL">
      <HintPath>..\..\packages\Xamarin.Forms.3.1.0.637273\lib\Xamarin.iOS10\Xamarin.Forms.Xaml.dll</HintPath>
    </Reference>
    <Reference Include=" Xamarin .iOS" />
  </ItemGroup>
  <ItemGroup>
    <ProjectReference Include="..\HelloReactiveUI\HelloNetStandard.csproj">
      <Project>{984433BA-6DB2-4606-8AB1-E5E070C60D44}</Project>
      <Name>HelloNetStandard</Name>
    </ProjectReference>
  </ItemGroup>
  <Import Project="$(MSBuildExtensionsPath)\Xamarin\iOS\Xamarin.iOS.CSharp.targets" />
  <Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
    <PropertyGroup>
      <ErrorText>This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them.  For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.</ErrorText>
    </PropertyGroup>
    <Error Condition="!Exists('..\..\packages\Xamarin.Forms.3.1.0.637273\build\netstandard2.0\Xamarin.Forms.props')" Text="$([System.String]::Format('$(ErrorText)', '..\..\packages\Xamarin.Forms.3.1.0.637273\build\netstandard2.0\Xamarin.Forms.props'))" />
    <Error Condition="!Exists('..\..\packages\Xamarin.Forms.3.1.0.637273\build\netstandard2.0\Xamarin.Forms.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\..\packages\Xamarin.Forms.3.1.0.637273\build\netstandard2.0\Xamarin.Forms.targets'))" />
  </Target>
  <Import Project="..\..\packages\Xamarin.Forms.3.1.0.637273\build\netstandard2.0\Xamarin.Forms.targets" Condition="Exists('..\..\packages\Xamarin.Forms.3.1.0.637273\build\netstandard2.0\Xamarin.Forms.targets')" />
</Project>

对此:

<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" DefaultTargets=" 建立 " xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
  <!-- File includes  和  that stuff -->
  <ItemGroup>
    <Reference Include="System" />
    <Reference Include="System.Xml" />
    <Reference Include="System.Core" />
    <Reference Include=" Xamarin .iOS" />
  </ItemGroup>
  <ItemGroup>
    <ProjectReference Include="..\HelloReactiveUI\HelloNetStandard.csproj">
      <Project>{984433BA-6DB2-4606-8AB1-E5E070C60D44}</Project>
      <Name>HelloNetStandard</Name>
    </ProjectReference>
  </ItemGroup>
  <ItemGroup>
    <PackageReference Include="  Xamarin 表格 ">
      <Version>3.1.0.637273</Version>
    </PackageReference>
  </ItemGroup>
  <Import Project="$(MSBuildExtensionsPath)\Xamarin\iOS\Xamarin.iOS.CSharp.targets" />
</Project>

其中仅引用顶级程序包。进一步,package.config文件将被删除。由于此方法仍在开发中,因此您可能会遇到一些麻烦。因此,请务必检查 局限性 这可能适用于您当前正在使用的软件包。如果是这种情况,请确保 让团队知道。但是,一旦迁移,您将能够使用您的项目而不会出现编译问题以及使用带来的所有好处 Nuget包参考.

结论

In this post, you saw how to migrate your Xamarin Projects to use 包装参考s. Using 包装参考s is intended to be the new adding NuGet 包装参考s directly to your csproj. With this migration, an error introduced when migrating your PCL projects to .Net Standard will also be solved. So be sure to check out this option when updating your Xamarin apps that have been out in the wild for a while.

注意: 使用Visual Studio 2017创建的所有新项目将自动使用包引用方法。

要完整查看示例应用程序,可以在GitHub上检出它们 packages.config包装参考.

T 谢谢你 皮尔斯·博根 他为我指出了正确的方向,以解决此问题。