The build fails because of this error
CompileC
/var/root/Library/Developer/Xcode/DerivedData/printapp3-bdgcuaoitzijpkgdxzcqqilqaxei/Build/Intermediates.noindex/ZXingObjC.build/Debug-iphonesimulator/ZXingObjC-iOS.build/Objects-normal/x86_64/ZXResultParser.o
/Users/master/Desktop/biolime/cfprint/node_modules/react-native-bluetooth-escpos-printer/ios/ZXingObjC-3.2.2/ZXingObjC/client/result/ZXResultParser.m
normal x86_64 objective-c com.apple.compilers.llvm.clang.1_0.compiler
(in target 'ZXingObjC-iOS' from project 'ZXingObjC') (1 failure)
In Xcode as you see in screenshot below show the error with this line of code
/Users/app/node_modules/react-native-bluetooth-escpos-printer/ios/ZXingObjC-3.2.2/ZXingObjC/client/result/ZXResultParser.m:252:20:
'stringByReplacingPercentEscapesUsingEncoding:' is deprecated: first
deprecated in iOS 9.0 - Use -stringByRemovingPercentEncoding instead,
which always uses the recommended UTF-8 encoding.
Can please someone assist me with the objective-c part
+ (NSString *)urlDecode:(NSString *)encoded {
NSString *result = [encoded stringByReplacingOccurrencesOfString:#"+" withString:#" "];
result = [result stringByReplacingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
return result;
}
When I replace
result = [result stringByReplacingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
with
result = [result stringByRemovingPercentEncoding:NSUTF8StringEncoding];
I face this error
/Users/app/node_modules/react-native-bluetooth-escpos-printer/ios/ZXingObjC-3.2.2/ZXingObjC/client/result/ZXResultParser.m:252:20:
No visible #interface for 'NSString' declares the selector
'stringByRemovingPercentEncoding:'
stringByRemovingPercentEncoding
does not take any parameters. Just call it on the string you want to affect and it will return an NSString * with the result:
result = [result stringByRemovingPercentEncoding];
Related
I thought the new notation works like this:
someArray[5] turns into
someArray[5] will actually turn into [someArray objectAtIndexedSubscript:5]
However, in NSArray.h and NSOrderedSet.h I saw this:
- (id)objectAtIndexedSubscript:(NSUInteger)idx NS_AVAILABLE(10_8, 6_0);
So, objectAtIndexedSubscript is only available for IOS6.
I experimented making this simple code:
NSArray * someArray =#[#"hello",#"World",#"World"];
NSOrderedSet * someOS = [NSOrderedSet orderedSetWithArray:someArray];
PO(someArray);
PO(someOS);
PO(someArray[0]);
PO(someOS[0]); //Exception thrown here
The code break at someOS[0]
-[__NSOrderedSetI objectAtIndexedSubscript:]: unrecognized selector sent to instance 0x8b1fac0
in BOTH NSArray and NSOrderedSet, there is a text NS_AVAILABLE(10_8, 6_0);
Yet it doesn't break on NSArray yet break on NSOrderedSet. Why?
Bonus: How do I make it work for NSOrderedSet too with category (need to check that it's not already defined)
I have a better answer!
This code will dynamically patch NSOrderedSet for versions of iOS that don't support -objectAtIndexedSubscript:.
#import <Foundation/Foundation.h>
#import <objc/runtime.h>
id PatchedObjectAtIndexedSubscript(id self_, SEL cmd_, NSUInteger index)
{
return [self_ objectAtIndex:index];
}
void PatchedSetObjectAtIndexedSubscript(id self_, SEL cmd_, id object, NSUInteger index)
{
return [self_ replaceObjectAtIndex:index withObject:object];
}
void SIPatchNSOrderedSet()
{
char types[6];
if (!class_getInstanceMethod([NSOrderedSet class], #selector(objectAtIndexedSubscript:))) {
sprintf(types, "##:%s", #encode(NSUInteger));
class_addMethod([NSOrderedSet class],
#selector(objectAtIndexedSubscript:),
(IMP)PatchedObjectAtIndexedSubscript,
types);
}
if (!class_getInstanceMethod([NSMutableOrderedSet class], #selector(setObject:atIndexedSubscript:))) {
sprintf(types, "v#:#%s", #encode(NSUInteger));
class_addMethod([NSMutableOrderedSet class],
#selector(setObject:atIndexedSubscript:),
(IMP)PatchedSetObjectAtIndexedSubscript,
types);
}
}
At the start of your application (-application:didFinishLaunchingWithOptions: maybe) call SIPatchNSOrderedSet().
In looking into this a little deeper and it looks like it NSOrderSet only has -objectAtIndexedSubscript: in iOS 6, but NSArray has -objectAtIndexedSubscript: in both iOS 5 and iOS 6.
My testing has shown the following.
- (void)testNSOrderedSetObjectAtIndexedSubscript
{
NSString *systemVersion = [UIDevice currentDevice].systemVersion;
NSString *message = #"NSOrderedSet for %# does not respond to -objectAtIndexedSubscript:";
NSOrderedSet *orderedSet = [NSOrderedSet orderedSet];
STAssertTrue([orderedSet respondsToSelector:#selector(objectAtIndexedSubscript:)], message, systemVersion);
}
- (void)testNSArrayObjectAtIndexedSubscript
{
NSString *systemVersion = [UIDevice currentDevice].systemVersion;
NSString *message = #"NSArray for %# does not respond to -objectAtIndexedSubscript:";
NSArray *array = [NSArray array];
STAssertTrue([array respondsToSelector:#selector(objectAtIndexedSubscript:)], message, systemVersion);
}
iOS 5.0 Simulator
Test Case '-[SIObjectTests testNSArrayObjectAtIndexedSubscript]' started.
Test Case '-[SIObjectTests testNSArrayObjectAtIndexedSubscript]' passed (0.000 seconds).
Test Case '-[SIObjectTests testNSOrderedSetObjectAtIndexedSubscript]' started.
/Users/jthomas/workspaces/si-catalog-order-ios/SICatalogOrderTests/SIObjectTests.m:20: error: -[SIObjectTests testNSOrderedSetObjectAtIndexedSubscript] : "[orderedSet respondsToSelector:#selector(objectAtIndexedSubscript:)]" should be true. NSOrderedSet for 5.0 does not respond to -objectAtIndexedSubscript:
Test Case '-[SIObjectTests testNSOrderedSetObjectAtIndexedSubscript]' failed (0.000 seconds).
iOS 6.0 Simulator
Test Case '-[SIObjectTests testNSArrayObjectAtIndexedSubscript]' started.
Test Case '-[SIObjectTests testNSArrayObjectAtIndexedSubscript]' passed (0.000 seconds).
Test Case '-[SIObjectTests testNSOrderedSetObjectAtIndexedSubscript]' started.
Test Case '-[SIObjectTests testNSOrderedSetObjectAtIndexedSubscript]' passed (0.000 seconds).
Jeffry answer is awesome and provide insight on how declaring your selector work.
For alternative, I simply do this:
self.businessDetailed.Phones.array[0];
Then I'll tell my future grandchildren to change that to
self.businessDetailed.Phones[0];
when iPhone 15 hit the shelf.
Much less work than Jeffry's solution at the cost of slightly increased marginal costs along the way.
I'm trying to determine the architecture of another file from my application. I'm using my application bundle and comparing it to a different bundle in my example. The methods are in place and they do return values to NSLog, although they are not the values I was expecting. Can anyone make some sense as to how to interpret the returned values?
- (void)whatArch {
NSArray *x86_64_Arch = [[NSBundle mainBundle] executableArchitectures];
NSArray *i386_Arch = [[NSBundle bundleWithPath:#"/path/to/other/bundle"] executableArchitectures];
NSLog(#"%# %#",[x86_64_Arch componentsJoinedByString:#" "], [i386_Arch componentsJoinedByString:#" "]);
}
The output I get is:
2012-07-09 00:00:59.990 whatArch[2200:403] 16777223 7 18
The [16777223] is the value that returns for the x86_64 bundle, and [7 18] for the (other) i386 bundle. When I read the documentation on executableArchitecture it shows something much different:
Mach-O Architecture
These constants describe the CPU types that a bundle’s executable code may support.
enum {
NSBundleExecutableArchitectureI386 = 0x00000007,
NSBundleExecutableArchitecturePPC = 0x00000012,
NSBundleExecutableArchitectureX86_64 = 0x01000007,
NSBundleExecutableArchitecturePPC64 = 0x01000012
};
NSLog(#"%u 0x%x", 0x01000007, 16777223); // Prints 16777223 0x1000007
NSLog(#"0x%x %u", 18, 0x00000012); // Prints 0x12 18
I'll leave 7 and 0x7 as an exercise for the reader.
And did you know that Christmas (Dec 25) and Halloween (Oct 31) are actually on the same day?
-(void)myFunction {
unichar myBuffer[5];
NSRange range = {0, 3};
NSString *string = [NSString alloc];
string = #"123";
[string getCharacters:myBuffer :range];
}
Gets warning
! NSString may not respond
to '-getCharacters::'
then does a SIGABRT when I run it.
Why????? Or better yet how can I get it to work?
To use getCharacters:range:, write this line of code:
[string getCharacters:myBuffer range:range];
In Objective-C, method names are split up by arguments (a feature that derives from its Smalltalk heritage). So your original code was trying to send a message that's essentially named getCharacters: :, which isn't found. The corrected version sends the message getCharacters: range:.
The getCharacters:myBuffer construct says that the first argument to getCharacters:range: is myBuffer. Similarly, the range:range construct says the second argument is your NSRange named range.
Note, I'm specifically referring to the fact that dot notation is being used with class methods, not instance methods.
Out of curiosity, I wanted to see what would happen if I tried to use Objective-C dot notation syntax with a class method. My experiment was as follows:
#import <Foundation/Foundation.h>
static int _value = 8;
#interface Test : NSObject
+ (int) value;
+ (void) setValue:(int)value;
#end
#implementation Test
+ (int) value {
return _value;
}
+ (void) setValue:(int)value {
_value = value;
}
#end
int main(int argc, char * argv[]) {
NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
NSLog(#"Test.value: %d", Test.value);
NSLog(#"[Test value]: %d", [Test value]);
Test.value = 20;
NSLog(#"Test.value: %d", Test.value);
NSLog(#"[Test value]: %d", [Test value]);
[Test setValue:30];
NSLog(#"Test.value: %d", Test.value);
NSLog(#"[Test value]: %d", [Test value]);
[pool release];
return 0;
}
I was surprised to see that this was compiled, let alone executed with what is, I suppose, correct behavior. Is this documented somewhere, or just a fluke of the compiler?
I compiled using GCC on Mac OS X 10.6:
gcc --version: i686-apple-darwin10-gcc-4.2.1 (GCC) 4.2.1 (Apple Inc. build 5659)
compile using: gcc ObjCClassDotSyntax.m -framework Foundation -o ObjCClassDotSyntax
run: ./ObjCClassDotSyntax
output:
2010-03-03 17:33:07.342 test[33368:903] Test.value: 8
2010-03-03 17:33:07.346 test[33368:903] [Test value]: 8
2010-03-03 17:33:07.351 test[33368:903] Test.value: 20
2010-03-03 17:33:07.352 test[33368:903] [Test value]: 20
2010-03-03 17:33:07.353 test[33368:903] Test.value: 30
2010-03-03 17:33:07.353 test[33368:903] [Test value]: 30
This is correct behavior. foo.method is syntactic sugar for [foo method]—a straight conversion with identical semantics. Similarly foo.prop = bar is syntactic sugar for [foo setProp:bar], again with identical semantics. This transformation is implemented in the compiler. Thus you can use dot notation to call 0-parameter methods as in foo.doSomething instead of [foo doSomething]. Of course, if you do this, you are evil.
The fact that the callee is a class instance doesn't mater because in Objective-C, classes are also objects. Using dot notation on a class calls the parameterless method on that class.
Dot notation is described in the Objective-C Programming Language document.
In the "evil but it works" category, I've been known to use convenience constructors with the dot notation once in a while, such as NSMutableArray *myArray = NSMutableArray.array
The Underscore library further abuses this syntax by returning blocks from class methods, resulting in code like this:
NSArray *elements = Underscore.array(array)
.flatten
.uniq
.unwrap;
To understand how this works, look at the definition of Underscore.array:
+ (USArrayWrapper *(^)(NSArray *))array
{
return ^(NSArray *array) {
return [USArrayWrapper wrap:array];
};
}
So:
Underscore.array(array)
...is equivalent to this:
NSArray *array = #[];
USArrayWrapper * (^arr)(NSArray *) = [Underscore array];
USArrayWrapper *result = arr(array);
I am fairly new to Objective-C and whilst running the Clang static analyser this section of code gave me the following error
warning: Pass-by-value argument in message expression is undefined
[artistCollection removeObject:removeArtist];
Can anyone cast any light on this warning for me?
case 6:
NSLog(#"(*) - First Name:");
scanf("%s", userFirName);
objFirName = [[NSString alloc] initWithUTF8String:userFirName];
for(eachArtist in artistCollection) {
if([[eachArtist firName] isEqualToString: objFirName]) {
removeArtist = eachArtist;
}
}
[artistCollection removeObject:removeArtist];
[objFirName release], objFirName = nil;
break;
gary
If you never get a match on that if inside your loop (because userFirName isn't in your collection), removeArtist will never get assigned a value. Assign it a value before starting the loop (nil, probably), and you should be fine.