Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Today Widget has no content on iOS 8 device

I am trying to create a Today Extension (aka Widget) for my existing iOS 7+ app. In iOS Simulator everything works fine (most of the time) but on my devices the widget is empty - only the header/name is shown but no content.

I found several threads dealing with similar issues but they were all related to some init-problems in Swift apps. I am using Objectiv-c not Swift.

This is what I did:

  1. Added a new Today Extension target to my app. The corresponding scheme was created automatically as well.
  2. The issue also occurs when the unchanged default Widget is used. I only added the init-methodes to see if they are called properly. So the widget should show the default Hello World label.

This is the code:

@interface TodayViewController () <NCWidgetProviding>

@end

@implementation TodayViewController

- (id)initWithCoder:(NSCoder *)aDecoder {
    self = [super initWithCoder:aDecoder];
    if (self)
        NSLog(@"initWithCoder");
    return self;
}

- (id)init {
    self = [super init];
    if (self)
        NSLog(@"init");
    return self;
}

- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil {
    self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
    if (self)
        NSLog(@"initWithNibName");
    return self;
}

- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view from its nib.
}

- (void)didReceiveMemoryWarning {
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}

- (void)widgetPerformUpdateWithCompletionHandler:(void (^)(NCUpdateResult))completionHandler {
    // Perform any setup necessary in order to update the view.

    // If an error is encountered, use NCUpdateResultFailed
    // If there's no update required, use NCUpdateResultNoData
    // If there's an update, use NCUpdateResultNewData

    completionHandler(NCUpdateResultNewData);
}

@end

When selecting the widget scheme and running it in simulator the widget is displayed correctly after selecting "Today" as container. Additionally initWithCoder is logged.

When running on device at first everything works as expected: The Today Screens comes up and the widgets are shown. My widget as well, but without any content.

Then Xcode shows the following message:

Lost connection to "Test Device" - Restore the connection to "Test Device" and run "com.example.MyApp.Widget" again, or if "com.example.MyApp.Widget" is still running, you can attach to it by selecting Debug > Attach to Process > com.example.MyApp.Widget.

Nothing is logged, I assume this is because of the lost connection. But why is the widget empty?

I looked into the device logs but there are no crashes. The problem is the same on my iPhone 6 (iOS 8.0) and iPad Air 2 (iOS 8.1)

Thank you very much!

like image 220
Andrei Herford Avatar asked Oct 24 '14 15:10

Andrei Herford


1 Answers

After a couple of days of searching I finally found the solution:

My project (the containing app of the widget) and the widget itself did not include the arm64 architecture. As the Apple docs describe this is not a valid configuration:

A containing app that links to an embedded framework must include the arm64 (iOS) or x86_64 (OS X) architecture build setting or it will be rejected by the App Store. (As described in Creating an App Extension, all app extensions must include the appropriate 64-bit architecture build setting.)

When x64 is missing the app will not only be rejected but also prevents the widget from showing up in the first place.

I added the widget to an existing projects which was not configured for x64 yet and it seems that the same build settings have been applied to the widget automatically. It would have avoided a lot of work if Xcode would have shown any warning or hint about this problem...

I did the following to solve the problem:

  • Click on the project entry in the Project Navigator and select the apps target.
  • Choose the Build Settings Tab and navigate to the Architectures section.
  • Set Architectures to Standard architectures (armv7, arm64)
  • Set Valid Architectures to armv7 armv7s armv8 arm64
  • Set Build Active Architectures Only to No
  • Apply the same settings to the Widget Target

After this the widget works correctly both in the simulator and on my test devices.

like image 130
Andrei Herford Avatar answered Sep 18 '22 03:09

Andrei Herford