For some reason - maybe has to do with a latest Xcode upgrade to version 7.2.1 - my pbxproj's structure got changed, and because of that, when I'm about to merge a PR, it just shows me a one big conflict on the entire file.
The reason, as I see it, is that one of them has this structure (posting the start of the file):
// !$*UTF8*$!
{
archiveVersion = 1;
classes = {
};
objectVersion = 46;
objects = {
/* Begin PBXBuildFile section */
009025BEF30C41848E6869F6 /* RolloutDynamic_18.m in Sources */ = {isa = PBXBuildFile; fileRef = E1BF845EAB9E4962853253B5 /* RolloutDynamic_18.m */; settings = {COMPILER_FLAGS = "-fobjc-arc"; }; };
00AFDB74BD584F1C9BD41B9D /* RolloutDynamic_03.m in Sources */ = {isa = PBXBuildFile; fileRef = 588F21D12977444EAE3C70F5 /* RolloutDynamic_03.m */; settings = {COMPILER_FLAGS = "-fobjc-arc"; }; };
054D17D506BF45EE98822AB9 /* RolloutDynamic_15.m in Sources */ = {isa = PBXBuildFile; fileRef = 54D47CE8182E4482955DA02E /* RolloutDynamic_15.m */; settings = {COMPILER_FLAGS = "-fobjc-arc"; }; };
and the other one that structure (start of the file):
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>archiveVersion</key>
<string>1</string>
<key>classes</key>
<dict/>
<key>objectVersion</key>
<string>46</string>
<key>objects</key>
<dict>
<key>18011C201B1F865300F52714</key>
<dict>
<key>fileEncoding</key>
<string>4</string>
<key>isa</key>
<string>PBXFileReference</string>
<key>lastKnownFileType</key>
<string>sourcecode.c.h</string>
<key>path</key>
<string>UserProfileTableViewController.h</string>
<key>sourceTree</key>
<string><group></string>
</dict>
Any idea how can this be solved?
Related
I have a info.plist file I want to use inside my project.
The Location is set to Relative to project
The target membership is checked
I get this error
Multiple commands produce '...appname.app/Info.plist'
Under that I have two children items of that error
Target 'targetname' (project 'targetname') has copy command from 'my own folder/Info.plist' to '/Users/.../Library/Developer/Xcode/DerivedData/project.../Build/Products/Debug-iphoneos/appname.app/Info.plist'
Target 'targetname' (project 'projectname') has process command with output '/Users/.../Library/Developer/Xcode/DerivedData/.../Build/Products/Debug-iphoneos/appname.app/Info.plist'
I tried editing the other info.plist directly, it just gets regenerated
I tried deleting the derived data folder, it just gets regenerated
I added the info.plist to copy bundle resources there are no duplicates
There are no duplicates in compile sources either
Could it be something with
project.pbxproj
// !$*UTF8*$!
{
archiveVersion = 1;
classes = {
};
objectVersion = 56;
objects = {
/* Begin PBXBuildFile section */
75B28283299B83B10087A029 /* Info.plist in Resources */ = {isa = PBXBuildFile; fileRef = 75B28282299B83B10087A029 /* Info.plist */; };
75E959AD299943800053FCFD /* SettingsModal.swift in Sources */ = {isa = PBXBuildFile; fileRef = 75E959AC299943800053FCFD /* SettingsModal.swift */; };
75F816D829980B1E002062A9 /* appname.swift in Sources */ = {isa = PBXBuildFile; fileRef = 75F816D729980B1E002062A9 /* appname.swift */; };
75F816DA29980B1E002062A9 /* ContentView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 75F816D929980B1E002062A9 /* ContentView.swift */; };
75F816E129980B1F002062A9 /* Persistence.swift in Sources */ = {isa = PBXBuildFile; fileRef = 75F816E029980B1F002062A9 /* Persistence.swift */; };
75F816E429980B1F002062A9 /* appname.xcdatamodeld in Sources */ = {isa = PBXBuildFile; fileRef = 75F816E229980B1F002062A9 /* projectname.xcdatamodeld */; };
/* End PBXBuildFile section */
/* Begin PBXFileReference section */
75B28282299B83B10087A029 /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = Info.plist; path = projectname/Info.plist; sourceTree = SOURCE_ROOT; };
...
GENERATE_INFOPLIST_FILE = YES;
Any help is welcome, thanks
Temporary fix
INFOPLIST_KEY_NSFaceIDUsageDescription = "This app uses Face ID for authentication purposes.";
I have my app already submited, reviewed and online in Google Play & iTunes, but recently I added the firebase_messaging plugin for notification feature.
While joining the Firebase Cloud Messaging, Google forced me to download two files:
google-services.json - Saved in the folder of my flutter App: MyApp\android\app
GoogleService-Info.plist - I don't know where to save it, but tried on MyApp\ios\Runner and MyApp\ios\Runner.xcodeworkspace without success
And all the tutorials point to the use of Xcode to set the file GoogleService-Info.plist properly, but I do not own a Mac and I've been using with success the windows application AppUploader to submit my iOS apps.
Is there any way to not use the Xcode and be able to attach the GoogleService-Info.plist to my project?
If you want to avoid using Xcode, you have to manually edit this file :
/ios/Runner.xcodeproj/project.pbxproj
You will need to reference GoogleService-Info.plist in order to make it included during the build process.
Here are the 4 differents sections where you need to add a line (see example line for GoogleService-Info.plist):
/* Begin PBXBuildFile section */
1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */ = {isa = PBXBuildFile; fileRef = 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */; };
3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */ = {isa = PBXBuildFile; fileRef = 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */; };
3B80C3941E831B6300D905FE /* App.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 3B80C3931E831B6300D905FE /* App.framework */; };
3B80C3951E831B6300D905FE /* App.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 3B80C3931E831B6300D905FE /* App.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
74858FAF1ED2DC5600515810 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 74858FAE1ED2DC5600515810 /* AppDelegate.swift */; };
9705A1C61CF904A100538489 /* Flutter.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 9740EEBA1CF902C7004384FC /* Flutter.framework */; };
9705A1C71CF904A300538489 /* Flutter.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 9740EEBA1CF902C7004384FC /* Flutter.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
97C146FC1CF9000F007C117D /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FA1CF9000F007C117D /* Main.storyboard */; };
DE4C455E21DE1E4300EA0709 /* GoogleService-Info.plist in Resources */ = {isa = PBXBuildFile; fileRef = DE4C455D21DE1E4300EA0709 /* GoogleService-Info.plist */; };
97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FD1CF9000F007C117D /* Assets.xcassets */; };
97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */; };
/* End PBXBuildFile section */
Here :
/* Begin PBXFileReference section */
1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GeneratedPluginRegistrant.h; sourceTree = "<group>"; };
1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GeneratedPluginRegistrant.m; sourceTree = "<group>"; };
3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = AppFrameworkInfo.plist; path = Flutter/AppFrameworkInfo.plist; sourceTree = "<group>"; };
3B80C3931E831B6300D905FE /* App.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = App.framework; path = Flutter/App.framework; sourceTree = "<group>"; };
74858FAD1ED2DC5600515810 /* Runner-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "Runner-Bridging-Header.h"; sourceTree = "<group>"; };
74858FAE1ED2DC5600515810 /* AppDelegate.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = "<group>"; };
7AFA3C8E1D35360C0083082E /* Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = Release.xcconfig; path = Flutter/Release.xcconfig; sourceTree = "<group>"; };
9740EEB21CF90195004384FC /* Debug.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Debug.xcconfig; path = Flutter/Debug.xcconfig; sourceTree = "<group>"; };
9740EEB31CF90195004384FC /* Generated.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Generated.xcconfig; path = Flutter/Generated.xcconfig; sourceTree = "<group>"; };
9740EEBA1CF902C7004384FC /* Flutter.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Flutter.framework; path = Flutter/Flutter.framework; sourceTree = "<group>"; };
97C146EE1CF9000F007C117D /* Runner.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Runner.app; sourceTree = BUILT_PRODUCTS_DIR; };
97C146FB1CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = "<group>"; };
97C146FD1CF9000F007C117D /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = "<group>"; };
97C147001CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = "<group>"; };
97C147021CF9000F007C117D /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
DE4C455D21DE1E4300EA0709 /* GoogleService-Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = "GoogleService-Info.plist"; sourceTree = "<group>"; };
/* End PBXFileReference section */
Here:
97C146F01CF9000F007C117D /* Runner */ = {
isa = PBXGroup;
children = (
97C146FA1CF9000F007C117D /* Main.storyboard */,
97C146FD1CF9000F007C117D /* Assets.xcassets */,
97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */,
97C147021CF9000F007C117D /* Info.plist */,
DE4C455D21DE1E4300EA0709 /* GoogleService-Info.plist */,
97C146F11CF9000F007C117D /* Supporting Files */,
1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */,
1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */,
74858FAE1ED2DC5600515810 /* AppDelegate.swift */,
74858FAD1ED2DC5600515810 /* Runner-Bridging-Header.h */,
);
path = Runner;
sourceTree = "<group>";
};
And here :
/* Begin PBXResourcesBuildPhase section */
97C146EC1CF9000F007C117D /* Resources */ = {
isa = PBXResourcesBuildPhase;
buildActionMask = 2147483647;
files = (
97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */,
3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */,
97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */,
97C146FC1CF9000F007C117D /* Main.storyboard in Resources */,
DE4C455E21DE1E4300EA0709 /* GoogleService-Info.plist in Resources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXResourcesBuildPhase section */
Tested successfully with codemagic, this modification made the provided GoogleService-Info.plist included in the App IPA
Somewhere along the line, AppUploader must be using XCode to build an iOS app from your code. While I don't know how they do that (their documentation is scarce on details), the best you can hope for is to put the google-services-info.plist in the right place before uploading the app.
In my projects I always put the google-services-info.plist in the myappname/ios/Runner directory that the Flutter tooling auto-generates. That's where the build then picks it up from.
after a while I bumped into it using the new XCode too I can guarantee you as already suggested that it works in this way.
Enter it under the
iOS -> Runner (here)
PS: From XCode I always took the reference of the file, it did not copy it to me. If anyone has succeeded even without this procedure above I would like to understand exactly how to do it from XCode.
I'm trying to make a file manager for iOS (my code has an exploit built in so it works).
The main code for my application is written in Swift and the code for running the exploit and reading files is written in Objecive-C.
This is the code I'm currently using in Objective-C:
NSString* readFile(NSString* file) {
char* buffer;
long lSize;
char* convertedFileName = [file UTF8String];
char* newFileName = deleteLastChar(convertedFileName); >> removes last / from path
char ch;
FILE *fp=fopen(newFileName, "r");
fseek( fp , 0L , SEEK_END);
lSize = ftell( fp );
rewind( fp );
buffer = calloc( 1, lSize+1 );
if( !buffer ) fclose(fp),fputs("memory alloc fails",stderr),exit(1);
if( 1!=fread( buffer , lSize, 1 , fp) )
fclose(fp),free(buffer),fputs("entire read fails",stderr),exit(1);
printf(buffer);
fclose(fp);
return [[NSString alloc] initWithUTF8String:buffer];
}
And this is the code for Swift:
func openFile(file: String) {
let fileContents = readFile(file)
print(fileContents) >> outputs nil
}
This is an example of a file I'm trying to open (plist file):
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>canvas_height</key>
<integer>1136</integer>
<key>canvas_width</key>
<integer>640</integer>
</dict>
</plist>
This is what the printf in the Objective-C code returns:
bplist00\322]canvas_height\canvas_width\240\332
(+
And Swift says the string is nil
The file is being read but there is still something wrong. Any ideas on how to fix this or a better way to handle this?
I wan't to turn on/off the call waiting feature of iPhone (that can be found at Settings > Phone > Call Waiting) programmatically.
What I have figured out is that the phone settings calls -setCallWaitingEnabled:specifier: method from PhoneSettingsCallWaitingController class found here. I found it in /System/Library/PreferenceBundles/MobilePhoneSettings.bundle/Call Waiting.plist:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>id</key>
<string>com.apple.preferences.phone.call-waiting</string>
<key>items</key>
<array>
<dict>
<key>cell</key>
<string>PSGroupCell</string>
</dict>
<dict>
<key>cell</key>
<string>PSSwitchCell</string>
<key>get</key>
<string>callWaitingEnabled:</string>
<key>label</key>
<string>Call Waiting</string>
<key>set</key>
<string>setCallWaitingEnabled:specifier:</string>
</dict>
</array>
<key>title</key>
<string>Call Waiting</string>
</dict>
</plist>
I loaded the bundle manually and initialized the above class and called the method I said but nothing happens. Here's the code:
NSBundle *b = [NSBundle bundleWithPath:#"/System/Library/PreferenceBundles/MobilePhoneSettings.bundle"];
BOOL success = [b load];
if (success)
{
NSLog(#"\n\n\n\n Bundle load successfull! \n\n\n\n ");
Class PhoneSettingsCallWaitingController = NSClassFromString(#"PhoneSettingsCallWaitingController");
id tc = [[PhoneSettingsCallWaitingController alloc] init];
[tc setCallWaitingEnabled:0 specifier:0];
} else NSLog(#"\n\n\n\n Bundle load failure! \n\n\n\n ");
I don't know if I'm in the correct path. Is there another way to turn on/off the Call Waiting setting?
Declarations for CoreTelephony.framework private APIs
CF_EXTERN_C_BEGIN
CF_EXPORT CFNotificationCenterRef CTTelephonyCenterGetDefault();
CF_EXPORT void CTTelephonyCenterAddObserver(CFNotificationCenterRef center, const void *observer, CFNotificationCallback callBack, CFStringRef name, const void *object, CFNotificationSuspensionBehavior suspensionBehavior);
CF_EXPORT void CTSettingRequest(NSDictionary* dict);
CF_EXPORT void CTSettingSave(NSDictionary* dict);
CF_EXPORT NSString* kCTSettingCallClassVoice;
CF_EXPORT NSString* kCTSettingTypeCallWaiting;
CF_EXPORT NSString* kCTSettingType;
CF_EXPORT NSString* kCTSettingCallClass;
CF_EXPORT NSString* kCTSettingEnabled;
CF_EXTERN_C_END
Setting requests and saves are done asynchronously. Results will be sent to telephony center callback:
void SettingCallback(CFNotificationCallback center, void* observer, NSString* name, const void* objec, NSDictionary* userInfo)
{
if ([name isEqualToString:#"kCTSettingRequestSuccessNotification"])
{
//Setting request results are in 'userInfo' argument
}
else if ([name isEqualToString:#"kCTSettingRequestErrorNotification"])
{
//Setting request error
}
else if ([name isEqualToString:#"kCTSettingSaveSuccessNotification"])
{
//Setting saved
}
else if ([name isEqualToString:#"kCTSettingSaveErrorNotification"])
{
//Setting save error
}
}
...
CTTelephonyCenterAddObserver(CTTelephonyCenterGetDefault(), NULL, SettingCallback, NULL, NULL, CFNotificationSuspensionBehaviorHold);
Request call waiting setting:
CTSettingRequest(#{#"STSettingTypeUniqueIdentifier" : kCTSettingTypeCallWaiting,
kCTSettingCallClass : kCTSettingCallClassVoice,
kCTSettingType : kCTSettingTypeCallWaiting});
Save call waiting setting (in this case, enabled):
CTSettingSave(#{#"STSettingTypeUniqueIdentifier" : kCTSettingTypeCallWaiting,
kCTSettingCallClass : kCTSettingCallClassVoice,
kCTSettingType : kCTSettingTypeCallWaiting,
kCTSettingEnabled : #YES});
I have a rather large plist that I am trying to load data from. Here is an example of the plist, but there are 580 records so I can't put them all here:
<plist version="1.0">
<array>
<dict>
<key>Grave #</key>
<string></string>
<key>Last Name</key>
<string>?</string>
<key>First Name</key>
<string>Ada Lou daughter of</string>
<key>Dates</key>
<string>?-? Unable to read stone</string>
<key>Notes</key>
<string></string>
<key></key>
<string></string>
</dict>
<dict>
<key>Grave #</key>
<string></string>
<key>Last Name</key>
<string>?</string>
<key>First Name</key>
<string>Stone w/ Cherokee syllabry and also in english says: Here we rest</string>
<key>Dates</key>
<string></string>
<key>Notes</key>
<string></string>
<key></key>
<string></string>
</dict>
I have my property in my .h file
#property (nonatomic, strong) NSDictionary *graves;
Synthesized in my .m file:
#synthesize graves;
Here is my code that loads the file in my view did load function:
NSString *file = [[NSBundle mainBundle] pathForResource:#"RossCemeteryList" ofType:#"plist"];
NSFileManager *fileManager = [NSFileManager defaultManager];
if ([fileManager fileExistsAtPath:file]) {
NSLog(#"The file exists");
} else {
NSLog(#"The file does not exist");
}
graves = [[NSDictionary alloc] initWithContentsOfFile:file];
NSLog(#"%i", [graves count]);
The NSLog messages says it finds the file, the there are 0 rows in the second NSLog message. I can try to spit out the contents graves using "NSLog (#"%#", graves);" and it returns NULL.
I am a little lost. Any help appreciated.
You are trying to create an NSDictionary object and initialize it from the contents of that plist while that plist actually contains an NSArray as its root object. You need to change your NSDictionary into an NSArray or NSMutableArray.
I don't know if you're still looking for a solution, but this code should allow you to load a plist file and determine the type of its contents:
// load a Property List ("plist") file (fully-qualified path) into a generic object, if
// it's available...
- ( NSObject * ) testLoadPListData: ( NSString * const ) plistPath
{
// load the file data into a raw data object...
NSData * const data = [ NSData dataWithContentsOfFile: plistPath ];
// fields returned from property list creation...
NSPropertyListFormat fmt = 0;
NSError * err = nil;
// load the file data into a serialized property list object...
NSPropertyListSerialization * plist = [ NSPropertyListSerialization propertyListWithData: data
options: NSPropertyListImmutable
format: &fmt
error: &err
];
// if there was an error creating the serialized object...
NSString * const errorText = err ? [ err description ] : nil;
if ( errorText )
{
// log the error string...
NSLog( #"error while reading data from file \"%#\": %#"
, plistPath
, errorText
);
} // end error creating serialized object
#if defined( DEBUG )
//////////////////////////////
// //
// DEBUG PURPOSES ONLY... //
// //
//////////////////////////////
// if this file is in a format that can be readily translated into one of our target data types...
if ( plist )
{
// if this property list file contains a dictionary...
if ( [ plist isKindOfClass: [ NSDictionary class ] ] )
{
// dump the contents of the dictionary to the debug output window...
NSDictionary * const dict = ( NSDictionary * )( plist );
__CCLOG( #"<Dictionary>%#\n</Dictionary>", dict );
} // end is dictionary plist file
// if this property list file contains an array...
else if ( [ plist isKindOfClass: [ NSArray class ] ] )
{
// dump the contents of the array to the debug output window...
NSArray * const arr = ( NSArray * )( plist );
__CCLOG( #"<Array>%#</Array>", arr );
} // end is array plist file
} // end valid file format
#endif // defined( DEBUG )
return plist;
} // end testLoadPListData