I'm having problem with the camera and the android photo gallery. In debug mode it works on the emulator and also on the device. When I generate the APK and install it on the device, the problem occurs. I try to use the camera or select an image the app unexpectedly closes. I assume it's a permission issue. I'm using permission_handler: "^5.1.0+1" and I followed an example I found on the web (https://pub.dev/packages/permission_handler/versions/5.1.0+1).
I can't use the current version because my project is on old Flutter and I had a lot of difficulties to upgrade.
I really need help.
import 'package:flutter/material.dart';
import 'dart:convert';
import 'dart:io';
import 'package:image_cropper/image_cropper.dart';
import 'package:image_picker/image_picker.dart';
import 'package:http/http.dart' as http;
import 'package:mysongs_v2/app_localizations.dart';
import 'package:mysongs_v2/global.dart';
import 'package:mysongs_v2/models/user.dart';
import 'package:permission_handler/permission_handler.dart';
import 'package:shared_preferences/shared_preferences.dart';
class PhotoProfileScreen extends StatefulWidget {
final int userId;
final String photo;
PhotoProfileScreen({Key key, this.userId, this.photo}) : super(key: key);
#override
_PhotoProfileScreenState createState() => _PhotoProfileScreenState();
}
class _PhotoProfileScreenState extends State<PhotoProfileScreen> {
bool _updated = false;
String _link = "";
final _scaffoldKey = GlobalKey<ScaffoldState>();
File _selectedFile;
bool _inProcess = false;
File imageFile;
final picker = ImagePicker();
bool _isReadyToSave = false;
#override
void initState() {
super.initState();
}
Widget getImageWidget() {
if (_selectedFile != null) {
return Image.file(
_selectedFile,
width: 250,
height: 250,
fit: BoxFit.cover,
);
} else {
return Image.asset(
"images/nickfrost.jpg",
width: 250,
height: 250,
fit: BoxFit.cover,
);
}
}
getImage(ImageSource source) async {
// request a user for permission first
this.setState(() {
_inProcess = true;
});
final image = ImagePicker();
final pickedFile = await image.getImage(source: source);
if (pickedFile == null) {
Navigator.pop(context, _updated);
return;
}
final File imageFile = File(pickedFile.path);
if (image != null) {
File cropped = await ImageCropper.cropImage(
sourcePath: imageFile.path,
aspectRatioPresets: [
CropAspectRatioPreset.square,
CropAspectRatioPreset.ratio3x2,
CropAspectRatioPreset.original,
CropAspectRatioPreset.ratio4x3,
CropAspectRatioPreset.ratio16x9
],
androidUiSettings: AndroidUiSettings(
toolbarTitle:
AppLocalizations.of(context).translate("pfs:crop_image"),
toolbarColor: COLOR_BUTTONS,
toolbarWidgetColor: Colors.white,
initAspectRatio: CropAspectRatioPreset.original,
lockAspectRatio: false),
iosUiSettings: IOSUiSettings(
minimumAspectRatio: 1.0,
),
);
this.setState(() {
_selectedFile = cropped;
_inProcess = false;
_isReadyToSave = true;
});
} else {
this.setState(() {
_inProcess = false;
_isReadyToSave = false;
});
}
}
#override
Widget build(BuildContext context) {
return Scaffold(
key: _scaffoldKey,
appBar: new AppBar(
title: new Text(
AppLocalizations.of(context).translate("pfs:title"),
),
elevation: 0.0,
backgroundColor: COLOR_MAIN,
),
body: Stack(
children: <Widget>[
Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
getImageWidget(),
Container(
padding: EdgeInsets.only(bottom: 8),
),
Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: <Widget>[
new Column(
children: [
new FloatingActionButton(
heroTag: "btnCamera",
onPressed: () async {
Map<Permission, PermissionStatus> statuses = await [
Permission.mediaLibrary,
Permission.storage,
Permission.camera,
Permission.photos,
].request();
print('permissao:');
print(statuses[Permission.camera]);
if (await Permission.camera.isPermanentlyDenied) {
// The user opted to never again see the permission request dialog for this
// app. The only way to change the permission's status now is to let the
// user manually enable it in the system settings.
openAppSettings();
}
getImage(ImageSource.camera);
},
tooltip: AppLocalizations.of(context)
.translate("pfs:new_picture"),
child: Icon(
Icons.add_a_photo,
size: 35,
),
backgroundColor: COLOR_MAIN,
),
new SizedBox(
height: 5,
),
],
),
new Column(
children: [
new FloatingActionButton(
heroTag: "btnGalery",
onPressed: () async {
Map<Permission, PermissionStatus> statuses = await [
Permission.mediaLibrary,
Permission.storage,
Permission.camera,
Permission.photos,
].request();
print('permissao:');
print(statuses[Permission.photos]);
if (await Permission.photos.isPermanentlyDenied) {
// The user opted to never again see the permission request dialog for this
// app. The only way to change the permission's status now is to let the
// user manually enable it in the system settings.
openAppSettings();
}
getImage(ImageSource.gallery);
},
tooltip: AppLocalizations.of(context)
.translate("pfs:select_from_gallery"),
child: Icon(Icons.add_photo_alternate),
backgroundColor: COLOR_MAIN,
),
new SizedBox(
height: 5,
),
],
),
],
),
new Container(
height: 30,
),
new Visibility(
visible: _isReadyToSave,
child: new Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[
new Spacer(),
new TextButton.icon(
label: Text(
' ${AppLocalizations.of(context).translate("pfs:cancel")} ',
),
icon: Icon(Icons.cancel),
style: ElevatedButton.styleFrom(
onPrimary: COLOR_BUTTONS,
primary: Colors.white,
padding: const EdgeInsets.all(8.0),
shape: RoundedRectangleBorder(
borderRadius: new BorderRadius.circular(18.0),
side: BorderSide(color: COLOR_BUTTONS),
),
),
onPressed: () {
Navigator.pop(context, _updated);
},
),
SizedBox(
width: 20,
),
new TextButton.icon(
label: Text(
' ${AppLocalizations.of(context).translate("pfs:save")} ',
),
icon: Icon(Icons.check),
style: ElevatedButton.styleFrom(
onPrimary: Colors.white,
primary: COLOR_BUTTONS,
padding: const EdgeInsets.all(8.0),
shape: RoundedRectangleBorder(
borderRadius: new BorderRadius.circular(18.0),
side: BorderSide(color: COLOR_BUTTONS),
),
),
onPressed: () async {
if (widget.photo == NOHASPHOTO) {
if (SERVER_NAME == '10.0.2.2/api') {
_link =
'http://localhost/api/$FOLDER_IMAGES_PROFILE/${widget.userId}.jpg';
} else {
_link =
'http://$SERVER_NAME/$FOLDER_IMAGES_PROFILE/${widget.userId}.jpg';
}
await updatePhoto(http.Client(), widget.userId,
"${widget.userId}.jpg", _link);
_savePhotoRegister("${widget.userId}.jpg");
}
uploadServer();
final snackBar = SnackBar(
backgroundColor: COLOR_SNACK,
content: Text(
AppLocalizations.of(context)
.translate("pfs:image_saved"),
),
duration: Duration(seconds: 1),
);
ScaffoldMessenger.of(context).showSnackBar(snackBar);
_updated = true;
Navigator.pop(context, _updated);
},
),
new Spacer(),
],
),
),
],
),
(_inProcess)
? Container(
color: Colors.white,
height: MediaQuery.of(context).size.height * 0.95,
child: Center(
child: CircularProgressIndicator(),
),
)
: Center()
],
),
);
}
name: mysongs_v2
description: A new Flutter project.
publish_to: 'none' # Remove this line if you wish to publish to pub.dev
# The following defines the version and build number for your application.
# A version number is three numbers separated by dots, like 1.2.43
# followed by an optional build number separated by a +.
# Both the version and the builder number may be overridden in flutter
# build by specifying --build-name and --build-number, respectively.
# In Android, build-name is used as versionName while build-number used as versionCode.
# Read more about Android versioning at https://developer.android.com/studio/publish/versioning
# In iOS, build-name is used as CFBundleShortVersionString while build-number used as CFBundleVersion.
# Read more about iOS versioning at
# https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html
version: 1.0.0+1
environment:
sdk: ">=2.1.0 <3.0.0"
dependencies:
flutter:
sdk: flutter
flutter_localizations:
sdk: flutter
query_params: "^0.6.0"
http: "^0.12.0+3"
quick_actions: "^0.4.0+1"
shared_preferences: "0.5.7+3"
intl: "^0.16.0"
flutter_i18n: "^0.20.1"
provider: "^4.0.1"
flutter_speed_dial: "^1.2.5"
webview_flutter: "^0.3.14+1"
truncate: "^2.1.2"
screen: "^0.0.5"
flutter_reorderable_list: "^0.1.3"
url_launcher: "^5.4.2"
infinite_listview: "^1.0.1+1"
google_fonts: "^1.0.0"
progress_dialog: "^1.2.4"
simple_tooltip: "^0.1.13"
image_picker: "^0.6.7+12"
image_cropper: "^1.2.0"
characters: "^1.0.0"
# location: "^3.0.0"
font_awesome_flutter: "^8.10.1"
flutter_masked_text: "^0.8.0"
share: "^0.6.5+4"
top_snackbar_flutter: "^1.0.2"
material_floating_search_bar: "^0.2.6"
qr_flutter: "^4.0.0"
super_tooltip: "^1.0.1"
permission_handler: "^5.1.0+1"
# The following adds the Cupertino Icons font to your application.
# Use with the CupertinoIcons class for iOS style icons.
cupertino_icons: ^0.1.2
dev_dependencies:
flutter_test:
sdk: flutter
dependency_overrides:
intl: "^0.17.0-nullsafety.2"
# For information on the generic Dart part of this file, see the
# following page: https://dart.dev/tools/pub/pubspec
# The following section is specific to Flutter.
flutter:
# The following line ensures that the Material Icons font is
# included with your application, so that you can use the icons in
# the material Icons class.
uses-material-design: true
# To add assets to your application, add an assets section, like this:
# assets:
# - images/a_dot_burr.jpeg
# - images/a_dot_ham.jpeg
assets:
- images/guitar.png
- images/microphone.png
- lang/en.json
- lang/es.json
- lang/pt.json
- images/cover.jpg
- images/nickfrost.jpg
- images/logo_mysongs.png
- images/chords.jpg
- images/text.jpg
# An image asset can refer to one or more resolution-specific "variants", see
# https://flutter.dev/assets-and-images/#resolution-aware.
# For details regarding adding assets from package dependencies, see
# https://flutter.dev/assets-and-images/#from-packages
# To add custom fonts to your application, add a fonts section here,
# in this "flutter" section. Each entry in this list should have a
# "family" key with the font family name, and a "fonts" key with a
# list giving the asset and other descriptors for the font. For
# example:
# fonts:
# - family: Schyler
# fonts:
# - asset: fonts/Schyler-Regular.ttf
# - asset: fonts/Schyler-Italic.ttf
# style: italic
# - family: Trajan Pro
# fonts:
# - asset: fonts/TrajanPro.ttf
# - asset: fonts/TrajanPro_Bold.ttf
# weight: 700
#
fonts:
- family: RobotoMono
fonts:
- asset: fonts/RobotoMono-Regular.ttf
- asset: fonts/RobotoMono-Bold.ttf
weight: 700
- family: CustomIcons
fonts:
- asset: fonts/CustomIcons.ttf
- family: Magneto
fonts:
- asset: fonts/MAGNETOB.TTF
# For details regarding fonts from package dependencies,
# see https://flutter.dev/custom-fonts/#from-packages
Manifest: DEBUG:
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="br.com.mysongs">
<!-- Flutter needs it to communicate with the running application
to allow setting breakpoints, to provide hot reload, etc.
-->
<uses-feature android:name="android.hardware.camera" />
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.WAKE_LOCK"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.READ_CONTACTS" />
<uses-permission android:name="android.permission.WRITE_CONTACTS" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<application
android:name="io.flutter.app.FlutterApplication"
android:label="mysongs_v2"
android:icon="#mipmap/ic_launcher">
<activity
android:name="com.yalantis.ucrop.UCropActivity"
android:screenOrientation="portrait"
android:theme="#style/Theme.AppCompat.Light.NoActionBar"/>
</application>
</manifest>
Manifest: MAIN
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="br.com.mysongs">
<!-- io.flutter.app.FlutterApplication is an android.app.Application that
calls FlutterMain.startInitialization(this); in its onCreate method.
In most cases you can leave this as-is, but you if you want to provide
additional functionality it is fine to subclass or reimplement
FlutterApplication and put your custom class here. -->
<application
android:name="io.flutter.app.FlutterApplication"
android:label="mysongs_v2"
android:usesCleartextTraffic="true"
android:icon="#mipmap/ic_launcher">
<activity
android:name=".MainActivity"
android:launchMode="singleTop"
android:theme="#style/LaunchTheme"
android:configChanges="orientation|keyboardHidden|keyboard|screenSize|smallestScreenSize|locale|layoutDirection|fontScale|screenLayout|density|uiMode"
android:hardwareAccelerated="true"
android:windowSoftInputMode="adjustResize">
<intent-filter>
<action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.LAUNCHER"/>
</intent-filter>
</activity>
<!-- Don't delete the meta-data below.
This is used by the Flutter tool to generate GeneratedPluginRegistrant.java -->
<meta-data
android:name="flutterEmbedding"
android:value="2" />
</application>
<uses-feature android:name="android.hardware.camera" />
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.WAKE_LOCK"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.CAMERA" />
<!--
<application
android:name="io.flutter.app.FlutterApplication"
android:label="MySongs"
android:icon="#mipmap/ic_launcher">
<activity
android:name="com.yalantis.ucrop.UCropActivity"
android:screenOrientation="portrait"
android:theme="#style/Theme.AppCompat.Light.NoActionBar"/>
</application> -->
</manifest>
It didn't work as you can see the images below:
Não funciono
The solution to the problem is easy migration of the project to the latest flutter version.
1- Go to the terminal and navigate to the project location. Then update new flutter pub upgrade --major-versions.
2- After this Fix, the code as some of the code will have to change according to new packages but most of it will be the same. I tried it. For me, it takes about 15 min to resolves updates and sometimes packages also guide you through if something is deprecated.
3- Create a new fluter project configure android and ios modules like permission added or other things which are packages requirements.
4- Then run the project. Will be run accordingly both on release and debug. but takes 1 hour. As I know from my experience it is worth it.
Cheers.
Add 'release' block inside the android in app/build.gradle file like give below
buildTypes {
release {
useProguard true
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
signingConfig signingConfigs.debug
}
}
**
Create if you dont have, 'app/proguard-rules.pro' file and add the following lines:
**
dontwarn com.yalantis.ucrop**
-keep class com.yalantis.ucrop** { *; }
-keep interface com.yalantis.ucrop** { *; }
-keep class androidx.appcompat.** { *; }
Add Lines to your Manifest: MAIN ..
<uses-feature android:name="android.hardware.camera" />
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.WAKE_LOCK"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.READ_CONTACTS" />
<uses-permission android:name="android.permission.WRITE_CONTACTS" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
Because you provide all permission for the debug mode. if you only provide permission on the main manifest file it will work for both modes.
I have an application in which i am adding 2 types of cells in two designs. So I am using custom UITableViewCell object classes. But my problem is I am using a text view in this cells. I need to adjust the row height according to its content size. This is what my code looks like:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier1 = #"CellIdentifier";
static NSString *CellIdentifier2 = #"Cell";
if(messagesarray==nil||[messagesarray count]==0)
{
}
else
{
NSMutableDictionary *dicttable=[messagesarray objectAtIndex:indexPath.row];
NSString *head=[dicttable objectForKey:#"gfgfg"];
NSString *head1=[dicttable objectForKey:#"gfgfgf"];
if([type isEqualToString:#"m"])
{
if([head isEqualToString:#"NA"])
{
CustomCell *cell = (CustomCell *)[tableView dequeueReusableCellWithIdentifier:CellIdentifier1];
if (cell == nil)
{
cell = [[[CustomCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier1] autorelease];
cell.backgroundView = [ [[UIImageView alloc] initWithImage:[ [UIImage imageNamed:#"white_top_portion.png"] stretchableImageWithLeftCapWidth:0.0 topCapHeight:5.0] ]autorelease];
}
cell.selectionStyle = UITableViewCellSelectionStyleNone;
cell.nameLabel.text=head;
cell.msg.text=head1;
[cell.button addTarget:self action:#selector(callAction:) forControlEvents:UIControlEventTouchUpInside];
if(icon!=nil)
{
if(![[ImageCache sharedImageCache] hasImageWithKey:icon])
{
cell.myImageView.image = [UIImage imageNamed:#"fggtgf.png"];
NSArray *myArray = [NSArray arrayWithObjects:cell.myImageView,icon,#"fgfgfg.png",[NSNumber numberWithBool:NO],nil];
AppDelegate *appDelegate = (AppDelegate *)[[UIApplication sharedApplication] delegate];
[appDelegate performSelectorInBackground:#selector(updateImageViewInBackground:) withObject:myArray];
}
else
{
cell.myImageView.image = [[ImageCache sharedImageCache] getImagefromCacheOrUrl:icon];
}
}
else
{
cell.myImageView.image = [UIImage imageNamed:#"fgfgfg.png"];
}
cell.label.text=sub;
return cell;
}
else
{
Customcellwithimage *cell = (Customcellwithimage *)[tableView dequeueReusableCellWithIdentifier:CellIdentifier2];
if (cell == nil)
{
cell = [[[Customcellwithimage alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier2] autorelease];
cell.backgroundView = [ [[UIImageView alloc] initWithImage:[ [UIImage imageNamed:#"white_deal_bg.png"] stretchableImageWithLeftCapWidth:0.0 topCapHeight:5.0] ]autorelease];
}
cell.selectionStyle = UITableViewCellSelectionStyleNone;
cell.datelabel1.text=subtitle;
cell.nameLabel1.text=head;
cell.msg1.text=head1;
if(icon!=nil)
{
if(![[ImageCache sharedImageCache] hasImageWithKey:icon])
{
cell.myImageView1.image = [UIImage imageNamed:#"fgfgfgf.png"];
NSArray *myArray = [NSArray arrayWithObjects:cell.myImageView1,icon,#"fgfgfgf.png",[NSNumber numberWithBool:NO],nil];
MFAppDelegate *appDelegate = (MFAppDelegate *)[[UIApplication sharedApplication] delegate];
[appDelegate performSelectorInBackground:#selector(updateImageViewInBackground:) withObject:myArray];
}
else
{
cell.myImageView1.image = [[ImageCache sharedImageCache] getImagefromCacheOrUrl:icon];
}
}
else
{
cell.myImageView1.image = [UIImage imageNamed:#"fgfgfgf.png"];
}
cell.cellview1.image=[UIImage imageNamed:#"vf.png"];
cell.label1.text=sub;
[cell.button1 addTarget:self action:#selector(callAction:) forControlEvents:UIControlEventTouchUpInside];
cell.bannerview1.image=[UIImage imageNamed:#"vfgf.png"];
return cell;
}
}
}
}
can anybody help me in achieving the row height as different for different cells?.I have to find out the height in - (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPathand i tried a method will need to find out the cell object of the current row.but didnt succeed .can anybody guide me in right direction
I think you are looking for - (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath - Here you can calculate the height for each individual row.
Note, if the calculation is a lot of work, you might see a reduction in performance. If this is the case you can pre-calculate the values and store them.
You can use this method for variable height support for your application.
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath;
Whenever you want to set the height dynamically, call this method with your tableview object.
For more info Click Here
or use this method with other tableview delegate methods.
Cell resizing can get pretty complicated, especially when UITextViews are involved. I suggest you simply use a table view framework such as Sensible TableView, where all the cells are automatically resized to fit contents. I believe they also now have a free version.
I have Created a custom UITableViewCell, the cell has multiple text fields, now i want to access the strings or data in these UITextFields. I know i can get the cell on didSelectRowAtIndexPath, but i need to get the text on a "Save" method.
Suppose you have four text fields with tags 100 and so on to 104.
You will you Counter that shows how many cells you have in tableview.
for (int i=0; iLessThanCounter; i++) {
NSIndexPath *indexPath = [NSIndexPath indexPathForRow: i inSection: 0];
UITableViewCell *cell = [mytableview cellForRowAtIndexPath:indexPath];
for (UIView *view in cell.contentView.subviews){
if ([view isKindOfClass:[UITextField class]]){
UITextField* txtField = (UITextField *)view;
if (txtField.tag == 100) {
NSLog(#"TextField.tag:%u and Data %#", txtField.tag, txtField.text);
}
if (txtField.tag == 101) {
NSLog(#"TextField.tag:%u and Data %#", txtField.tag, txtField.text);
}
if (txtField.tag == 102) {
NSLog(#"TextField.tag:%u and Data %#", txtField.tag, txtField.text);
}
if (txtField.tag == 103) {
NSLog(#"TextField.tag:%u and Data %#", txtField.tag, txtField.text);
}
if (txtField.tag == 104) {
NSLog(#"TextField.tag:%u and Data %#", txtField.tag, txtField.text);
} // End of isKindofClass
} // End of Cell Sub View
}// Counter Loop
}
You can simply use viewWithTag to get your desired views. Suppose you have one imageview with tag 100 and one text view with tag 200.
UITableViewCell *cell = [mytableview cellForRowAtIndexPath:indexPath];
UIImageView *getImageView = (UIImageView*)[cell.contentView viewWithTag:100];
UITextField *getTextView = (UITextField*)[cell.contentView viewWithTag:200];
you need to create instance for each textField in your header file. Look at this sample demo
http://windrealm.org/tutorials/uitableview_uitextfield_form.php
You can access textfield's text property for getting the text value for a particular textfield
iOS iCloud
Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'error during execution of SQL string 'INSERT INTO Y_UBMETA(YPEERID, YTRANSACTIONNUMBER)
Unresolved error Error Domain=NSCocoaErrorDomain Code=134312 "Store metadata recovery appears to have failed, please try adding the store to the coordinator again. If that is unsuccessful, migrate the data to a new ubiquitized persistent store." UserInfo=0xdba5b80 {NSLocalizedDescription=Store metadata recovery appears to have failed, please try adding the store to the coordinator again. If that is unsuccessful, migrate the data to a new ubiquitized persistent store.}, {
NSLocalizedDescription = "Store metadata recovery appears to have failed, please try adding the store to the coordinator again. If that is unsuccessful, migrate the data to a new ubiquitized persistent store.";
How do I solve this problem? Coz that it is an internal query for iCloud. I am putting my code block below of the method i have written..
- (NSPersistentStoreCoordinator *)persistentStoreCoordinator
{
NSLog(#"persistentStoreCoordinator:%#",[persistentStoreCoordinator_ description]);
if((persistentStoreCoordinator_ != nil))
{
return persistentStoreCoordinator_;
}
NSLog(#"persistentStoreCoordinator:%#",[persistentStoreCoordinator_ description]);
NSURL *storeURL = [[self applicationDocumentsDirectory] URLByAppendingPathComponent:#"CoreDataModel.sqlite"];
persistentStoreCoordinator_ = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:[self managedObjectModel]];
NSPersistentStoreCoordinator* psc = persistentStoreCoordinator_;
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
NSFileManager *fileManager = [NSFileManager defaultManager];
// Migrate datamodel
NSDictionary *options = nil;
// this needs to match the entitlements and provisioning profile
NSURL *cloudURL = [fileManager URLForUbiquityContainerIdentifier:nil];
NSLog(#"cloudURL:%#",cloudURL);
//NSString* coreDataCloudContent = [[cloudURL path] stringByAppendingPathComponent:#"Data"];
cloudURL = [cloudURL URLByAppendingPathComponent:#"Data"];
// NSLog(#"coreDataCloudContent:%#",coreDataCloudContent);
//if ([coreDataCloudContent length] != 0 && [[defaults objectForKey:#"allMetadataFlag"] isEqualToString:#"YES"])
if (cloudURL )//&& [[defaults objectForKey:#"allMetadataFlag"] isEqualToString:#"YES"])
{
// iCloud is available
// cloudURL = [NSURL fileURLWithPath:coreDataCloudContent];
NSLog(#"cloudURL:%#",cloudURL);
options = [NSDictionary dictionaryWithObjectsAndKeys:
[NSNumber numberWithBool:YES], NSMigratePersistentStoresAutomaticallyOption,
[NSNumber numberWithBool:YES], NSInferMappingModelAutomaticallyOption,
#"SecureAssistant.store", NSPersistentStoreUbiquitousContentNameKey,
cloudURL, NSPersistentStoreUbiquitousContentURLKey,nil];
}
else
{
// iCloud is not available
options = [NSDictionary dictionaryWithObjectsAndKeys:
[NSNumber numberWithBool:YES], NSMigratePersistentStoresAutomaticallyOption,
[NSNumber numberWithBool:YES], NSInferMappingModelAutomaticallyOption,nil];
}
NSError *error = nil;
[psc lock];
if (![psc addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:storeURL options:options error:&error])
{
NSLog(#"Unresolved error %#, %#", error, [error userInfo]);
abort();
}
[psc unlock];
dispatch_async(dispatch_get_main_queue(), ^{
NSLog(#"asynchronously added persistent store!");
[[NSNotificationCenter defaultCenter] postNotificationName:#"RefetchAllDatabaseData" object:self userInfo:nil];
});
});
return persistentStoreCoordinator_;
}
I have got the same issue, it happened because i have changed the attribute of datamodel from Xcode, not from my app by code. i solved this by delete the SQLite file from iCloud and deleted the app from device then rebuild. It worked for me.
I am working on an app and i have to save some data in the dictionary and then i have to load that data and showing to user whatever the options user saved.
when i get data from dictionary it crashes on second time not on first time and gives different crash log every time.
like
-[UIDeviceRGBColor objectAtIndex:]: unrecognized selector sent to instance 0x68c22d0
or
[UIControlTargetAction count]: unrecognized selector sent to instance 0x68683d0
or
0 : <CFString 0x687cb30 [0x124eb38]>{contents = "dish1"} = UIDeviceWhiteColorSpace 0 0.5
my code is this
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
if (tableView == menuTableView) {
[optionsView addSubview:topScrollView];
optionFlag=NO;
[self optionScreenMethod:indexPath.row];
NSString *dishSelect=[NSString stringWithFormat:#"dish%d",indexPath.row];
NSMutableArray *dishesArray=[[NSMutableArray alloc]init];
NSMutableArray *dishDicArray=[[NSMutableArray alloc]init];
dishesArray=[dishDictionary objectForKey:dishSelect];
NSLog(#"%d",[dishesArray count]);
if ([dishesArray count]>0) {
optionFlag=YES;
}else{
for (int i=0; i<[tempStr intValue]; i++) {
DishData *dishData=[[DishData alloc]init];
dishData.dishTitle=(NSMutableString*)[[tableMenuArray objectAtIndex:indexPath.row] itemName];
dishData.accompArrayIndex=nil;
dishData.cookArrayIndex=nil;
dishData.dishComent=nil;
dishData.nonMandArray=nil;
[dishDicArray addObject:dishData];
}
[dishDictionary setObject:dishDicArray forKey:dishSelect];
}
//[dishesArray release];
//[dishDicArray release];
dishSelectRow=indexPath.row;
// NSString *dishSelect=[NSString stringWithFormat:#"dish%d",indexPath.row];
[isSelected removeAllObjects];
[isSelectedAccompArray removeAllObjects];
[isSelectedCookArray removeAllObjects];
[self defaultDataArray];
[accompmentTblView reloadData];
[cookingTblView reloadData];
[nonMandTblView reloadData];
[nonMandtSelectOptionArray removeAllObjects];
optionsView.hidden=NO;
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
//If possible make a singleton instance here of "dishDictionary" may solve your issue of crashing (Rather diclare it at the class level)
//if(!dishDictionary)
dishDictionary=[[NSMutableDictionary alloc]init];
..........
//Replace this line :
NSMutableArray *dishDicArray=[[NSMutableArray alloc]init];
to
NSMutableArray *dishesArray=[[NSMutableArray alloc]initWithArray:[dishDictionary objectForKey:dishSelect]];
and remove
dishesArray=[dishDictionary objectForKey:dishSelect];
..........
//may will not crash than try this
}