0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

個人開発で得られたWidgetアプリでできないこと

Last updated at Posted at 2025-04-22

2025年に入って、ウィジェットメインで使用するアプリを3つリリースしました。
本記事の最後にアプリを紹介しています。

本記事では、Widgetの実装で得られた知見について纏めてみました。

1. Widgetでできないこと

Widgetの開発を行っていると、開発する前に「知っておきたかった。」ことや「え〜、それできないんだ。」という発見が結構ありました。
そういった経験を紹介できればと思います。

1.1 Widgetは15分に1度の更新のみ

  • 現状だと、Widgetは15分に1度の更新のみということです。
    リアルタイム性のあるものだと勝手に想像していました。
    どのくらいの頻度でWidgetを更新するかはgetTimelineの中で指定します。

    getTimelineのコード例
        func getTimeline(in context: Context, completion: @escaping (Timeline<MarketEntry>) -> Void) {
    
            // entriesを生成する処理
            
            // タイムラインを更新
            let nextUpdateDate = Calendar.current.date(byAdding: .minute, value: 15, to: Date())!
            let timeline = Timeline(entries: entries, policy: .after(nextUpdateDate))
    
            completion(timeline)
        }
    

  • リアルタイム性の求められるアプリを開発していて、当初は更新頻度1分間隔くらいで実装しようと呑気に考えていました…

1.2 WidgetはUIPasteboardにアクセスできない(コピペが使用できない)

  • Widgetでテキストをコピーできたら便利だなと考え、実装してみました。

    WidgetでUIPasteboardにアクセスできないのであれば、「はい、そうですか。」で終わりなのですが、シミュレーターで動作確認するとUIPasteboardにアクセスすることができるため、無事コピーできると勘違いしてしまうのです。

    そして実機で確認すると全く動作しません。
    どうにかコピーできないかと試行錯誤してみますが、動作はしません。

    調べてみると同じようなことを言っている人がいます。
    https://stackoverflow.com/questions/78670089/cant-use-uipasteboard-on-widget-swift-on-real-device


  • この件について、解消方法が存在するのであれば教えていただきたいです。
    また、この罠に引っ掛かる人が減れば幸いです。

1.3 WidgetではUserDefaults.standardからのデータを参照できない

  • アプリ側でUserDefaults.standard使用して保存した変数をWidget側で参照したいというケースがあると思います。
    Widgetでは、App Groupsで設定したIDのUserDefaultsを使用する必要があります。
    App GroupsのUserDefaultsを用意したら、使用方法はUserDefaults.standardと同じです。
    App GroupsはSigning & Capabilitiesから設定できます。

    let sharedDefaults = UserDefaults(suiteName: "group.com.xxxx.xxxxx")
    

1.4 UIApplication.sharedはWidgetでは使用できない

  • 前提として、WidgetでUIApplication.sharedを使用することはないです。
    使用すると、以下のエラーが発生します。
    'shared' is unavailable in application extensions for iOS: Use view controller based solutions where appropriate instead.
    

  • そもそも、なぜこのエラーが発生したのか?
    次のコードのように、アプリ側とWidget側で処理を共通化したUtilというファイルを使っていました。
    つまり、UtilファイルのTargetにはアプリとWidgeExtensionを指定している状態ということになります。
    UIApplication.sharedはWidgetでは使用できないので、当然ビルドエラーとなり上記のエラーが発生します。
  • 解消方法
    • アプリ側とWidget側で共通化処理のファイルを別々で用意する
    • アプリ側とWidget側で両方とも使用する場合は、コメントアウト等で運用方法を記載する
    struct Util {
         static let windowScene = UIApplication.shared.connectedScenes.first(where: { $0.activationState == .foregroundActive }) as? UIWindowScene
     }
    

1.5 WidgetでScrollViewは使用できない

ScrollViewを使用するとこうなります(笑)

2. その他

2.1 インタラクティブなWidgetを作成する

  • Widgetでは、ボタンを使用することができます。

    AppIntentに準拠したStructを作成して、Buttonで使用する
    struct EqualIntent: AppIntent {
        static var title: LocalizedStringResource = "Equal"
        static var description = IntentDescription("Equal the display")
        
        func perform() async throws -> some IntentResult {
            CalculatorState.tappedEqual()
            return .result()
        }
    }
    
    // ボタンの呼び出し元
    Button(intent: EqualIntent()) {
        Text("=")
            .font(.system(size: 24, weight: .bold))
            .frame(maxWidth: .infinity, maxHeight: .infinity)
            .foregroundColor(.white)
    }
    .background(RoundedRectangle(cornerRadius: buttonNumberRadius).foregroundStyle(.orange))
    

2.2 WidgetのButtonのBackgroundを消す方法

  • WidgetでButtonを使用すると、自動で青色のBackgroundが付きます。
    ButtonStyleを付与する必要がある。普通にButtonにModifierを付与するのでは、解消できません。

    ButtonStyleのコード例
      struct ClearBackgroundStyle: ButtonStyle {
          func makeBody(configuration: Configuration) -> some View {
              configuration.label
                  .background(Color.clear)
          }
      }
    

まとめ

もっと重要なことがあった気がしたのですが、忘れちゃいました(笑)
今後は発見し次第、どこかに纏めておこうと思います。

以下、リリースしたアプリです。
海外の株式市場にズブズブに浸かっている人は、MarketTimeZenを使ってみて欲しいです。

1. Reawake

iPhoneからMacBookの電池残量を確認できるアプリ。
(リリースから修正していないので、動作が怪しいかも…)

2. MarketTimeZen

タイムゾーンに合わせて株式市場がいつ開くのかをロック画面やウィジェットから確認できる。
海外に行った際に「市場もう始まってたのか!」であったり、
開場する時を楽しみに待っていたが、「今日アメリカは祝日で閉場してたのかい…」という経験を解消するために開発しました。

3. Ex Rate Calc - ウィジェットで為替電卓 -

シンプルな為替の電卓です。
例えばアメリカに行って何かを買うときにドルをそのまま入力して円換算できたら便利かもな?と思い開発しました。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?