MAC上でVS2022でbuildできなくなった件

前回記事にて、MAC OS14 / Xcode 15 / Visual Studio 2022 for MAC で、iOS17対応でXamarinアプリのBuild / TestFlight までできることを確認しました。’24.4月の事です。

しかし諸事情で MAC を再初期化しました。その後、iOSプラットフォームで以下のように現在’24.7月 Build が通らなくなりました。

エラーは、The type or namespace naname interface名 could not be found (a you missging a using directive or un asssmbly reference? ) (CS00246)

Xamarinで 各固有処理を作る場合、プラットフォーム共通部で interface を定義し、各OS固有部側で interface名で、固有部処理クラスを継承します。その interface 名 が未定義だと言われてます。どう見ても合っています。同じコードでVS2019 for MACでは通ります。Xcode側の影響でしょうか??? VS2022 For MAC のサポート終了直前で手間の掛かりすぎるApple対応で心が砕けてしまったのでしょうか?

解決策は、VS2022 Windows でビルトすることでした。

しかし、TestFlight も Windows側で、buildする必要があります。以下のポイントがありました。VS2019から大分進化しているようです。

先に MAC に iPhone を接続して双方で「信頼」し、その後、VS側でMAC接続します。そうしないとVS側で iPhone を認識しない場合があります。 未認識では 「Keyがnullです」みたいなbuildエラーが出てしまいます。

ビルトがずっと終わらないのでMAC側をみてみると、パスワード入力待ちになってました。これを入力するとすすみます。パスワードはMAC本体の方です。

デプロイ メニューで行います。

TesFlight 用にBuildするには、MAC側の証明書、プロビショニングプロファイル が必要です。MAC側の証明書をExportします。その手順はこちら。ここでExport時には必ずパスワードをかけます。これはVS2022側が必ずパスワードを要求してくるためです。

VS2022から [ツール] -> {オプション] -> [Xamarin] -> [Appleアカウント} を開き。チーム一覧から自分のチームを選んで[詳細の表示] を選びます。以下のように詳細画面から[証明書のインポート]を選びます。尚、コントロールパネルの証明書からimportしても効かなかったです。 いちおう[すべてのプロファイルをダウンロード]も実施しておきます。

プロビショニングプロファイルは、注意が2点ありました。

  • Windows用VS2022の特有機能と思われる「自動プロビショニング」は、既にMAC側でプロビショニングプロファイルを作っていた場合は使いません。
  • adHoc用のプロビショニングプロファイルを作っていると自動認識でそちらが優先されてしまうようです。adHoc用はApple Developr WEBページから削除しておく。

iOSプロジェクトのプロパティの[iOSハンドル署名]の設定例は以下の通りです。ただし以下問題発生1の事象が発生した場合は、署名IDプロビショニングプロファイル は任意に選択にします。

TestFlight の IPA を生成するには、[ビルド] -> [アーカイブ]を選びます。後は以下のような流れです。

MAC側で、MAC側のパスワードを入力。’24.11月時点では以下問題発生2を注意です。

しかし App Store へのuploadは失敗しました。

IPAファイルはWindows側に生成させるので、IPAをMAC Book にコピーして、Transfar アプリ で upload は Ok でした。 オチはありますが、操作性最悪MACを触る量が減ったのでヨカッタです。

‘24.11月 VS2022からapple developer に接続できない事象が発生しています。apple developer のWEBページはログインできます。

これだと新しい証明書のダウンロードができないです。MSのページに以下の個別のアカウントのほうで可能との情報あり。

こちらは、発行者ID、キーID、秘密キー が必要です。その発行のために App Store Connect に行くと、手順説明にある「キータブ」がありません。他WEB記事をみると昔はあったみたいです。

Apple Deceloper側に「キー」という項目があり、こちらて発行してみくましたがエラーになってしまいます。こっちに移ったわけではないみたいです。

XcodeはApple Developerへアクセスできるので、Apple側でVisual Studioからの接続が禁止されてしまったのでしょうか? 継続調査中です。

アプリ固有のパスワードは、Apple Developer のパスワードでは通らなくなりました。アプリ用パスワードを別途発行する必要がありました。Apple Accountの設定からログインし、以下のように発行します。アプリ単位で発行するというわけではないようですので、アプリの設定を探しても機能が見つかりません。

TestFlightが届かないとき

前記事はこちら

TestFlight はどうも気まぐれです。ユーザさんから「招待が届かない」とクレームが沢山です。単純確立は1/5程度です。なんででしょう??? 注意点と対策です。

必ず別メールにて、招待した旨のメールをだしましょう。


この場合は、高い確率でTestFlightの招待が失敗する傾向があります。具体的な事象は、

開発者側から招待は成功し、「招待済み」の表示になるのですが、テスト者に招待が届かない

です。たたWEBページ低応答と同事象が常用的に発生してしてただけかもしれません。


再招待のボタンがあったので使ってみました。この時は効果はなかったです。


以下のようにパブリックリンクを有効にして、制限人数を設定し、URLコピーをテスト者にお送りします。こちらは有効な手段です。ただApple 審査が終わっていないとテストはできないため、Apple側の問題で招待がとどいていない場合のみ対策となります。

テスト者にコピーしたURLをメールで送る。


弊方では効果不明でした。

MAC操作性で困ってしまうとこ

MACは操作は人間工学に反しています。日本にあってません。もともとMACは急がすゆったり使う人用なのかもしれません。 日本社会では仕事用はWindowsなので、MACから切替えると業務支障をきたします。取引先がMACの場合も把握しておく必要がありそうです。その覚え書きです。随時更新中

ALT +ESC」に相当するものがない。Windowの切り替えランチャーみたいなものがありますが、選びたいんじゃなくて、とにかく考えずにめくってマウスを使わず次に操作するWindowに移りたいんです。いちいちクリックしてたら操作時間と考える時間を余計に消費します。


他PCでは「ESC」の位置なので習慣的に押しやすい、いろんなとこに予期せず「1」が入ってしまいますい、後で取り除かないといけません。「1」を沢山押すような社会的業務的要件は思いつきません。ブランクキーにでもしとけばいいのに… 邪魔すぎです。


キーボードに手を置くと、左下隅は小指の付け根あたりが当たりやすいです。他PCだと「Ctrl」なので単体で押す分には害はないです。しかし、MACはCAPS単体で CAPS ONになります。他PCでは、Shiftと同時に押さないと CAPS ON になりません。CAPS無効にはできるのですが、ディスクトップ機でApple純正無線キーボードを使った場合は効きません。「大文字小文字違いがそんなに重要?」と思われるかもしれませんが、Vi 使いにとっては非常に重要です。大文字小文字でコマンドが違うんです。意図せすCAPS ONになると、書いていたコードがぐちゃぐちゃになってしまいます。


いうまでもありません。古いMAC OSでは、Google日本語変換が使えていましたが、最新MAC OSではインストールしてもGoogleに切替えできなくなりました。


役にたたない「かっこいいでしょ」といわんばかりのアクション(「ソフトウェア芸」と呼びます)が、意図せず発動するとびっくりしますし本来したい操作の邪魔です。例えば、背景をクリックするとWindowが四方に散らばります。Windowが沢山のときディスクトップ上の何かが見たいとき一理ありるようにおもえますが、見たいWindowあるので強引です。Window移動のためタイトルバーをクリックして上にちょいスライドさせると縮小モードになりますが、何の意味もありません。


世界標準はGoole MAPでしょう。目標物などがMACのMAPは少ないようです。MACユーザがら送られていたMAPをみて、待ち合わせ場所に行こうとすると間違えてしまいました。周囲のコンビニが、Goole MAPでは2つ、MACでは1つでした。MACユーザがら送られていたMAPは信用せず、番地を聞いてGoole MAPで特定しておく必要があります。


リモートワークで欠かせないWIndowsのリモートディスクトップ。MACでも画面共有はありますが、画面だけなので、キーボート操作が変わってしまいます。特に日本語切替がリモート側でなく、ホスト側のみになってしまいます。


MACからWindows PCに戻るととても作業がはかどります。キーボートの応答性がわるいんですかね。


MACは、FreeBSDがベースだとか。CRオンリーのようです。基本UNIXマシンなんですね。昔HPや日立UNIXマシンもそうでした。MACユーザとtxtファイル交換時は要注意です。


MACがサーバ機になることはないでしょうから、ログインなしでshutdownさせてもいいんいでは? いちいち面倒すぎる。


「ALT+ESC」の件も含めて、マウスがないと何んも出来ない。MAC-miniをWindows Xamarinからbuildエンジンとして使うだけのとき、マウス繋いでないのでいちいちマウス接続を要してしまう。

Swift-UIでTable内容をリアルタイム更新する

Swift-UIでは 一画面のGUI最大表示数は 20個くらいです。それを超える情報を表示するには Table object を使うしかない。 そこで Table object に初期値を表示するWEB記事は多数ありましたが、リアルタイム更新する事例が見受けられませんでした。もしかして出来ない??? と思い試した覚書です。Xcode 14.1 です。

結論からいうと @State変数 を割当てれば普通に使えました。例では Foreground と Background でサーバとの通信の統計を表示する例です。

まず表示値を格納する@State変数を宣言します。

 	// 内部用の表示項目
 	@State private var	recvCnt 	 : [Int32]	= [0,0]
 	@State private var	recvErr 	 : [Int32]	= [0,0]
 	@State private var	sendCnt 	 : [Int32]	= [0,0]
 	@State private var	sendErr 	 : [Int32]	= [0,0]

Tableの列定義は、リアルタイム表示したい列は@State変数を定義します。

	// 統計コード列
	struct TokeiColums: Identifiable {
		let id = UUID()
		let name: String
		@State var value1: Int32
		@State var value2: Int32
		@State var value3: Int32
		@State var value4: Int32
	}

表示データの定義は、各列に表示値の@State変数を割当てます。

		// 統計行定義
		let TokeiInfo: [2] = [
			TokeiColums(name: "Server受信",
				value1: recvCnt[0], value2: recvErr[0], value3: recvCnt[1], value4: recvErr[1] ),
			TokeiColums(name: "Server送信",
			  value1: sendCnt[0], value2: sendErr[0], value3: recvCnt[1], value4: recvErr[1] ),	]

Table object の定義コードは以下です。縦余裕がないとさり気なく下から表示されなくなるため、一行余裕のある高さを指定おくのががベターです。

				/* 稼働統計 */
				Table(TokeiInfo) {
					TableColumn("項目") { locationColums in
						Text(locationColums.name)
					}
					TableColumn("OK件数-FG") { locationColums in
						Text("\(locationColums.value1)")
					}
					TableColumn("NG件数-FG") { locationColums in
						Text("\(locationColums.value2)")
					}
					TableColumn("OK件数-BG") { locationColums in
						Text("\(locationColums.value3)")
					}
					
					TableColumn("NG件数-BG") { locationColums in
						Text("\(locationColums.value4)")
					}
				}
			}

リアルタイム値の更新はタイマーで周期的に行います。

		.onAppear {
		   // タイマで3秒周期に更新
        updateDataTmr = Timer.scheduledTimer(withTimeInterval: 3,
							 repeats: true){ _ in
							 
					 		recvCnt[0] 	= 変更したい値
		          recvErr[0] 	= 変更したい値
		          sendCnt[0] 	= 変更したい値
		          sendErr[0] 	= 変更したい値
					 		recvCnt[1] 	= 変更したい値
		          recvErr[1] 	= 変更したい値
		          sendCnt[1] 	= 変更したい値
		          sendErr[1] 	= 変更したい値
				}
		}

表示例は以下のとおりです。

iPadでは特に問題はなかったのですが、iPhone では表示が真っ白でした。これは table object そのものの課題なのかもしれません。またタイマーは View をCloseしても生きています。必ず解放します。さもない View 再表示毎にタイマーが溜まってヤバイことになります。他言語ではVewとともに解放されますが、、、自分で停止するタイマを作る場合、インスタンスをGlobal定義し、invalidateで停止させないと効きません。タイマloop内で return も flg 値==falseでも脱出でできません。以下コード例です。

var    updateDataTmr:Timer? = nil     // 位置情報更新タイマ

struct ビュー名: View {
        :
       中略
        :
    var body: some View {
        :
       中略
        :
    }
    .onDisappear {
       if updateDataTmr != nil {
            updateDataTmr?.invalidate()     // タイマ停止
            updateDataTmr = nil
        }
    }

iOSでbackground定周期処理の実際のところ【’24.7月編】

iOS で background ( 端末画面が非表示のとき ) 処理を定期実行させることは鬼門のようです。Appleの情報、ネット記事、有識者の情報 どれも幾分違っていて真実が分かりません。iOSではバッテリ節約が最優先され、background 処理時間に制限が厳しいと言われているようです。 ’24年7月に実装した結果を報告します。

OSiPadOS 17.6
端末iPad 6th
Xcode実機TEST 15.1 、シュミレータTEST 14.2
言語Swift UI

基本 background は「アプリが前面に表示されていないが動作しているとき」ですが、完全なbackground状態にするには以下の配慮が必要なようです。

  • iOS系は 画面スリープ無し に設定できますが、これは有効にしないこと。
  • USBで電源供給したままにしない。
  • Xcodeと接続しない。

またプログラムに、

  • トレースログが取得できる仕組みを作成しておく。

取り掛かりとしてApp の onChange(of:scenePhase) イベント で background と foreground の切替りを検出してました。そのbackground のifスコープにで タイマーをつっこみました。(以下赤字部) これが一番シンプルかなと…カンで組んでみました。

一見動作しているように見えたのですが、途中でお亡くなりになるようです。background に移行してから動作可能な時間制限があるとのことですが、正確にどのくらいか色々試してもよく分かりませんでした。 UIApplication.shared.beginBackgroundTask ~endBackgroundTask を使って時間制限を検出しリカバリする方法も試しましたが、なんだか効果なしです。BGTaskScheduler というのもありますが有識者によると、「定周期background 処理は基本的ニ出来ない」とのことで試さずじまいです。

iOSで background 処理を定期的に行う手法として、GPSによる中心座標からの半径範囲(リージョン)への出入りを検出する方法が、いろいろと紹介されています。これは XamarinのiOS Background処理の説明ページにも記載されています。概念図は以下の通りです。

もちろんこれが適用されるのは、端末がある程度の時間経過とともに移動するシステムに限ります。その検出部のコードは以下のような感じです。

ポイントとしては、

  • 移動しないとBackground実行できません。
  • 定周期でBackground実行する場合は、移動量と時間のCONVERTが必要です。
  • 半径5mに指定しても、イベント発生させるには50~100mくらい移動を要します。
  • UIApplicationDelegateAdaptor を Appクラスで絡めるコード例もありますが、シンプルに CLLocationManager だけで構築できます。

リージョン出入り検出」は、秒、分単位の定周期処理とすると不向きのようです。通常、リアルタイム緯度経度の検出で使用しているCLLocationManager のイベントも、よく観察するとBackground時でも動作していることに気付きました。リアルタイム緯度経度検出 と Background処理を一緒に行えば、もっと早い周期でBackground処理が可能となります。その検出部のコードは以下のような感じです。

ポイントとしては、

  • 移動しないとBackground実行できません。
  • 定周期でBackground実行する場合は、移動量と時間のCONVERTが必要です。
  • 移動距離をもっと小さくすると、秒周期でBackground内でイベント発生させることも可能。(iPadではGセンサも併用している模様)
  • 日中での電池の持ち、iPadなら電池の持ちは心配ない感じ。iPhoneは厳しい感じ。
  • 移動イベント中に、新しい移動イベントが発生した場合、新しい移動イベントは保留される。(保留最大数は未知)
  • リージョン出入り検出と同居可能。

Background内である程度の周期で動作できるようになったら、何秒くらい動作可能か情報が必要です。これも色々な説があるようです。以下のBackground処理ダミーコードで調べてみました。下記コード中の printLog はローカルtxtファイルへの出力付きの print 関数の自作ラッパーです。5秒置きにlogを残すことでどこまで動けるか確認しました。

結果としては、

  • 最小で45秒までは動けてはいた。公称値が30秒とのウワサ。
  • 最大120秒程度まで伸びる場合あり。CPU使用時間が影響しているのかもしれない。
  • 許容時間超過後、TASKは休止状態となり、Foregroud移行後に動き出す。
  • 製品コードでのBackground処理はScokect通信です。これはうまくいきました。