夏が始まってしまい暑くなって参りましたが、皆さんいかがお過ごしでしょうか。
自分は悲しきかな既に夏バテ気味でおります。
暑さで体力を奪われると体調を崩したり活動に支障を来したりで困るので、
早く涼しくなって欲しいものです。
皆さんは夏バテに負けずに元気に過ごされることを祈っております。
夏が始まってしまい暑くなって参りましたが、皆さんいかがお過ごしでしょうか。
自分は悲しきかな既に夏バテ気味でおります。
暑さで体力を奪われると体調を崩したり活動に支障を来したりで困るので、
早く涼しくなって欲しいものです。
皆さんは夏バテに負けずに元気に過ごされることを祈っております。
こんにちはmtjです
海外の人に電車の切符の取り方を聞かれた時に 明らかに在来線の切符売場では買えない範囲の切符だった時に無人機ではそういった状況には対応できないなと感じてしまいました。
京都の地下から有人のみどりの窓口が消えてしまってのでその時は新幹線の売り場まで案内しましたが
その人達はどんだけ頑張ってもあの場所で新幹線の切符は取れなかったんだろうなと思ってしました。
自動機は目的の物が売っている前提で買うなら優秀ですし 早いのですが
目的の物が無い物を買おうとする時がどうしても弱い
人であれば目的の物がなければ その場所を伝えてくれたり
そもそも近辺では売ってないという事を伝えられますが 自動機相手の場合は売ってない事自体も自力で調べないといけないので何も知らない状態で行動するには不向きだなと感じました。
それこそAIが発展しても 何を聞けばいいかわからないというような状態の人にはAIもかなり厳しいと感じます
AIも操作する人が質問等を行って初めて使うことができるので 順を追ってやりたい事を聞き出せる人にはなかなか敵わないだろうなと感じました。
C#でusing文やusing変数宣言(C#8.0~)のオブジェクトに対して、
オブジェクト初期化子を使用すると警告がでます。
以下の画像で、zipFile2の方はnewの部分が波線で警告されているのが分かります。
これはオブジェクト初期化子の処理中で例外が発生した場合に、
オブジェクトが正しく Dispose されないことが原因です。
Low-level なコードで表すと、オブジェクト初期化処理はtry文の外にあり、
この場合はコンストラクタで例外が発生した場合と同様に、
Dispose が呼ばれないことが確認できます。
オブジェクトの初期化に関しては、
一般的にオブジェクト初期化子を利用するのが良いと言われています。
ただし、using文ではその限りではないことが分かりました。
また IDisposable を継承するクラスに関しても、
プロパティ設定で例外が発生するような設計は避けるべきです。
ただ設計によっては record型の値オブジェクト等のコンストラクタでは、
例外を出すことも珍しくない為、usingのオブジェクト初期化子には注意が必要です。
先日、MAUIのAndroidアプリにてプッシュ通知を実現するため、
Firebase Cloud Messagingを用いる方法を調査していました。
その際に詰まったことがあったので共有します。
Firebaseから取得した設定ファイル google-services.json をプロジェクトに含める必要があるのですが、
含めた後にプロパティからビルドアクションをGoogleServicesJsonに変更しないと
Firebaseの処理が動作しません。
しかしビルドアクションの選択肢にGoogleServicesJsonが出てきませんでした。
これは定番の困りごとのようで、調べてみると解決策がいくつか出てきたのですが
自分の環境ではどれも上手く行かず、ようやく上手く行ったのは以下の手順による方法でした。
1. nugetで以下のパッケージをインストール
※1つずつ試してはないので不要なもの含まれている可能性有
Xamarin.Firebase.Common
Xamarin.Firebase.Config
Xamarin.Firebase.Iid
Xamarin.GooglePlayServices.Base
Xamarin.GooglePlayServices.Basement
Xamarin.GooglePlayServices.Tasks
2. .csprojに以下を直接記述して、対象のパッケージの.targetファイルをインポート
<Import Project="C:\Users\<my user>\;.nuget\packages\xamarin.googleplayservices.basement\118.3.0.1\buildTransitive\net7.0-android33.0\Xamarin.GooglePlayServices.Basement.targets" Condition="Exists('C:\Users\<my user>\.nuget\packages\xamarin.googleplayservices.basement\118.3.0.1\buildTransitive\net7.0-android33.0\Xamarin.GooglePlayServices.Basement.targets')" />
3. 2の記述にてnugetフォルダパスが個人のローカルパスになっているため、マクロに置き換え
※個人プロジェクトなら不要です
C:\Users\<my user>\.nuget\packages\ → $(NuGetPackageRoot)
↓
<Import Project="$(NuGetPackageRoot)xamarin.googleplayservices.basement\118.3.0.1\buildTransitive\net7.0-android33.0\Xamarin.GooglePlayServices.Basement.targets" Condition="Exists('$(NuGetPackageRoot)xamarin.googleplayservices.basement\118.3.0.1\buildTransitive\net7.0-android33.0\Xamarin.GooglePlayServices.Basement.targets')" />
これで無事ビルドアクションの選択肢にGoogleServicesJsonが出て来て、
Firebaseのプッシュ通知を動作させることができました。
以下のページにより解決に辿り着けました。感謝します。
xamarin – Can't set Build Action to GoogleServiceJson – Stack Overflow
先日、iPhoneアプリのGUIを「ASP.NET Core MVC」に置き換える仕事を行いました。
今まで苦手であったWEB(HTML+CSS)の開発が人並みには出来るようになったと思います。
最近は工場向けの案件でもスマホでIoT見える化を行い、設備の稼働状態表示やエラー通知を行うなどのニーズなどがあるので、弊社のような制御系ソフト会社でもWEBアプリの知識が必要になってきています。
いくつか今後の開発のためにメモを残しておこうと思います。
今までWEBでのUI要素の配置が思うようにいかず、デスクトップアプリより柔軟性がないと思っていましたが、flexを使用するとほぼデスクトップアプリと同じ間隔で配置できるようになりました。
まずはflexを使用し、うまくいかない場合だけ他の方法を使用するのがよさそうです。
クライアントからサブミットしてサーバに一旦戻して再描画するとスクロール位置が上に戻ってしまいます。
これはサブミット前にスクロール位置をinputタグに格納し、再描画時に同じスクロール位置に戻せば解決します。
これを各ページで行うのではなく、全てのページで共通実装にするのが良いです。
アイコンライブラリを使用して簡単にアイコンが表示できます。
https://icons.getbootstrap.jp/
以下のBootstrapの目次を見た感じだと、スピナー、トースト、ツールチップあたりは導入しやすくすぐに役立ちそうです。
https://bootstrap-guide.com/outline
こんにちはmtjです。
ソフト開発の費用について。
ソフトの費用というと機能である程度平滑化できるように思われますが 実際は同じ金額で全く同じソフトができるわけでは有りません。
同じ人が作ればある程度は平均化ができますが別な人、会社が作ればUIの作り、処理の作り等により金額もばらばらです。
UIのアニメーション、綺麗さ等に凝れば金額は上がります
処理も1秒も待たせたくないという仕様であれば金額は上がります
そこで大事になっていくのが営業の手腕だと思います。
アニメーションが必要無い箇所で凝ったアニメーションを作る必要はないですし
処理も別に時間がかかってもいいような物であれば即終わるような仕組みを作らなくてもいいです。
相手にとってどの部分が重要かを判断し提案できるかが技術者の腕だと思いました。
オフィスではデスクトップPCを使って開発を行っています。
先日、約4年間使用したPCを更新しました。
好きなPCを選んで良いとのことでしたので、Intel Core i9-14900 の高性能なPCにし、
開発がとても快適になりました。
4年前の前回の更新時はCPUにAMD Ryzenを選び、
SSDはそれまでのPCで使用していたHDDをクローンして使用しました。
今回はSSDのクローンが上手くいかなかった為、OSのインストールから行いました。
開発用PCには、新旧様々な開発環境やアプリケーションとその設定、ドライバーなどが入っており、
新規にインストールして開発環境を一から構築するのは骨の折れる作業です。
特に古い開発環境は素直にインストールできなかったりする場合もあります。
ただその甲斐もあって、CPU, SSD, メモリなどの世代が新しくなった事や、
OSクリーンインストールを行ったことで、全体的にきびきび動作するようになり、快適です。
開発中のソフトウェアのビルド時間も大幅に短縮され、効率的にもなりました。
気分も一新して、開発に挑みたいと思います。
今月とうとうXamarinのサポートが終了しましたね。
後継のクロスプラットフレームワークである.NET MAUI[1]に移行するため、
調査や準備を進めています。
現行のアプリのUIを1から新規プラットフォームで構築し直すのは大変です。
しかし、今回は以下の理由などにより、カメラなどネイティブの機能が必要ない箇所を除いて、
WebViewにhtmlを表示するWebアプリ化を行うことになりました。
・サーバーと通信するアプリである
・Webアプリの構築基盤が既に存在する
このWebアプリ化を移行前に行うことにより、MAUIへの移行もスムーズに行えると思われます。
MAUIに関しては、3月に手が空いていたので業務時間内に調査・勉強して、
実機でアプリを実行できるところまで進んでいます。
WPFと同様xamlでUIを記述する形式なため、WPF開発者ならスムーズに開発できる印象を受けました。
VisualStudioをMacとペアリングすることで、開発まではWindows上で行えるのも便利で良いですね。
MAUIの開発が進みましたらまた何か書こうと思います。
以上です。
[1].NET Multi-platform App UI. 2022年に正式リリース。
WEBからダウンロードしたファイルはセキュリティブロックされており、「Microsoft Defender SmartScreen」の確認画面が表示されたりします。
このセキュリティブロックを解除するには、代替データストリームのZone.Identifierを削除する必要があります。
C#で解除する拡張メソッドを作成しました。
以下のUnblockメソッドを実行すると解除できます。
[DllImport("kernel32", CharSet = CharSet.Unicode, SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
private static extern bool DeleteFile(string name);
public static void Unblock(this FileInfo file) {
file.IsReadOnly = false;
DeleteFile(file.FullName + ":Zone.Identifier");
}