ios NSRegularExpression trouble - regex

I'm trying to do a basic regular expression in xcode and it's not cooperating.
NSString *urlString = #"http://www.youtube.com/v/3uyaO745g0s?fs=1&hl=en_US";
NSError *error = nil;
NSRegularExpression *regex = [NSRegularExpression regularExpressionWithPattern:#"/.*?v=(.*)&.*/" options:NSRegularExpressionCaseInsensitive error:&error];
NSTextCheckingResult *fmis = [regex firstMatchInString:urlString options:0 range:NSMakeRange(0, [urlString length])];
if(fmis) {
NSRange match = [fmis range];
NSLog(#"%i", match.location);
}
essentially, I'm just trying to suck 3uyaO745g0s out of the urlString. I assume a regular expression is the best way? Thanks for looking my question.
** EDIT **
sometimes the url will look like this: http://www.youtube.com/watch?v=3uya0746g0s and I have to capture the vid from that as well.

I think it's much easier to create an NSURL object and let it do its magic for you:
NSString *urlString = #"http://www.youtube.com/v/3uyaO745g0s?fs=1&hl=en_US";
NSURL *url = [NSURL URLWithString:urlString];
// Since you're targeting the last component of the url
NSString *myMatch = [url lastPathComponent]; //=> 3uyaO745g0s
You can find more on how to access various parts of an NSURL object here

There are many types of Youtube URLs.
Maybe you can try this
NSString *urlString = #"http://www.youtube.com/v/3uyaO745g0s?fs=1&hl=en_US";
NSString *regEx = #"[a-zA-Z0-9\\-\\_]{11}";
NSRange idRange = [urlString rangeOfString:regEx options:NSRegularExpressionSearch];
NSString *youtubeID = [urlString substringWithRange:idRange];
I found this regular expression here. And you don't have to use NSRegularExpression for simple search:)
I think this is pretty good solution but if you want more reliable result, then try another regular expression in that answer.

Related

remove "?show=false" using regex [duplicate]

I looking for regular expression to use in my javascript code, which give me last part of url without parameters if they exists - here is example - with and without parameters:
https://scontent-fra3-1.xx.fbcdn.net/v/t1.0-9/14238253_132683573850463_7287992614234853254_n.jpg?oh=fdbf6800f33876a86ed17835cfce8e3b&oe=599548AC
https://scontent-fra3-1.xx.fbcdn.net/v/t1.0-9/14238253_132683573850463_7287992614234853254_n.jpg
In both cases as result I want to get:
14238253_132683573850463_7287992614234853254_n.jpg
Here is this regexp
.*\/([^?]+)
and JS code:
let lastUrlPart = /.*\/([^?]+)/.exec(url)[1];
let lastUrlPart = url => /.*\/([^?]+)/.exec(url)[1];
// TEST
let t1 = "https://scontent-fra3-1.xx.fbcdn.net/v/t1.0-9/14238253_132683573850463_7287992614234853254_n.jpg?oh=fdbf6800f33876a86ed17835cfce8e3b&oe=599548AC"
let t2 = "https://scontent-fra3-1.xx.fbcdn.net/v/t1.0-9/14238253_132683573850463_7287992614234853254_n.jpg"
console.log(lastUrlPart(t1));
console.log(lastUrlPart(t2));
May be there are better alternatives?
You could always try doing it without regex. Split the URL by "/" and then parse out the last part of the URL.
var urlPart = url.split("/");
var img = urlPart[urlPart.length-1].split("?")[0];
That should get everything after the last "/" and before the first "?".

iOS 10 NSMutableDictionary and NSMutableArray not working as before

It seems with the release of iOS 10, a few things have broken. The major one for me has been the use of NSMutableDictionary and NSMutableArray. Both no longer seem to be able to parse a string of JSON and instead give out a nil while in pre iOS 10 they populated as expected. The only way around this I've found is to use NSDictionary and NSArray respectively and then use the init methods to cast back. For example:
let json = "{ \"code\": \"abcde\", \"name\": \"JP Morgan\" }"
json as! NSMutableDictionary // gives nil
NSMutableDictionary(dictionary: json as! NSDictionary) // works :)
let json = "[{ \"code\": \"abcde\", \"name\": \"JP Morgan\" }]"
json as! NSMutableArray // gives nil
NSMutableArray(array: json as! NSArray) // works :)
I would like to know why?
And I hope this helps someone solve their issue...
The Foundation types NSMutableArray / NSMutableDictionary are not related to the Swift counterparts and cannot be bridged / coerced from a literally created Swift type. But that's not new in Swift 3.
Basically do not use NSMutableArray / NSMutableDictionary in Swift unless you have absolutely no choice for example interacting with a few low level CoreFoundation API. The native Array / Dictionary types used with var provide the same functionality (except value vs. reference semantics) and in addition the types of the containing objects.

How to display an image from documents directory to UIImageView in Swift 3?

The below Swift 2 example gives this error:
Value of type String has no member 'stringByAppendingPathComponent'
What do I need to change for Swift 3?
Apple is trying to move everyone off the path-as-string paradigm to URL (i.e. file:///path/to/file.text). The Swift API pretty much removes all path in favor of URL.
You can still find it in Objective-C (NSString):
let paths = NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true)[0] as String
let getImagePath = NSString.path(withComponents: [paths, "fileName"])
The more Swifty way:
let paths = NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true)[0] as String
let url = URL(fileURLWithPath: paths).appendingPathComponent("fileName")
I personally like getting of this value from the App delegate. Put this code (stands alone like normal function) into the AppDelegate.swift.
lazy var applicationDocumentsDirectory: URL = {
let urls = FileManager.default.urls(for: FileManager.SearchPathDirectory.documentDirectory, in: FileManager.SearchPathDomainMask.userDomainMask)
return urls[urls.count-1]
}()
So in all your files you can use it this way:
let appDelegate = UIApplication.shared.delegate as! AppDelegate
let imageUrl = appDelegate.applicationDocumentsDirectory.appendingPathComponent("YourFileName")
let imageUrlString = imageUrl.urlString //if String is needed

percent escapes removed in NSData writeToURL

I am trying to cache an image retrieved from Flickr. In order to create a unique filename for the cached image, I use CFURLCreateStringByAddingPercentEscapes to percent escape the URL. Appending that to the cache directory, I get a URL with the embedded Flickr URL properly percent escaped; but when I try to cache the image using NSData writeToURL:options:error: I get "The operation couldn’t be completed. No such file or directory" - and it shows the file URL with the original, unescaped Flickr URL where the file name should be.
For example, I NSLog the URL as:
file://localhost/Users/rick/Library/Application%20Support/iPhone%20Simulator/6.1/Applications/77C4A7AA-C386-4575-AD21-B4027D080408/Library/Caches/http%3A%2F%2Ffarm3.static.flickr.com%2F2887%2F9391679341_26643bcafa_b.jpg
but the error message shows
NSFilePath=/Users/rick/Library/Application Support/iPhone Simulator/6.1/Applications/77C4A7AA-C386-4575-AD21-B4027D080408/Library/Caches/http://farm3.static.flickr.com/2887/9391679341_26643bcafa_b.jpg
It's as if in the process of converting the URL to a file path, writeToURL is removing the percent escapes.
Is there a way to prevent this from happening, or do I just need to come up with another way to generate unique names based on the url?
Here's the relevant code:
NSURL *cacheDirectoryURL=[[fileManager URLsForDirectory:NSCachesDirectory inDomains:NSUserDomainMask] lastObject];
NSString *photoURLString= (NSString *) CFBridgingRelease(CFURLCreateStringByAddingPercentEscapes(NULL,
(__bridge CFStringRef)([self.photoURL absoluteString]),
NULL,
(CFStringRef) #"!*'();:#&=+$,/?%#[]",
kCFStringEncodingUTF8));
if (photoURLString)
{
NSURL *cachedPhotoURL=[NSURL URLWithString:[[cacheDirectoryURL absoluteString] stringByAppendingString:photoURLString]];
NSData *photoData=[NSData dataWithContentsOfURL:cachedPhotoURL];
if (photoData)
{
UIImage *image=[UIImage imageWithData:photoData];
self.imageView.image=image;
[self setupScrollView]; // new image, need to adjust scroll view
} else {
dispatch_queue_t fetchQueue=dispatch_queue_create("photo downloader", NULL);
dispatch_async(fetchQueue, ^{
NSData *photoData=[NSData dataWithContentsOfURL:self.photoURL];
NSError *error;
if ([photoData writeToURL:cachedPhotoURL options:NSDataWritingAtomic error:&error])
{
NSLog(#"Cached photo");
} else {
NSLog(#"Failed to cache photo");
NSLog(#"%#",error);
}
});
}
}
Thanks in advance for your help!
The problem is that [NSURL URLWithString:...] parses the given string and interprets the
percent escapes. Generally, to create a URL for a file system path, fileURLWithPath:
should be used.
In your case, the following simple code should work:
NSURL *cachedPhotoURL = [cacheDirectoryURL URLByAppendingPathComponent:photoURLString]

Create Order to Spree ecommerce using iOS app

In my app, i want to order a product in spree e-commerce by iPhone app. I easily get the products name and their detail but while creating order for products it's return the error in html page :
<h1>
TypeError
in Spree::Api::V1::OrdersController#create
</h1>
<pre>can't convert Symbol into Integer</pre>
I m sending post request as:
NSString *str = [NSString stringWithFormat:#"http://localhost:3000/api/orders"];
NSURL *urlForBuy = [NSURL URLWithString:[str stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]];
ASIFormDataRequest *request = [ASIFormDataRequest requestWithURL:urlForBuy];
NSString *idVariant = [NSString stringWithFormat:#"order[line_items][%d][variant_id]",0];
NSString *qnty = [NSString stringWithFormat:#"order[line_items][%d][quantity]",0];
NSString *idVariantValue = #"123456";
[request setPostValue:[NSString stringWithFormat:#"%d",[idVariantValue intValue]] forKey:idVariant];
[request setPostValue:[NSString stringWithFormat:#"%d",1] forKey:qnty];
[request setPostValue:#"<my admin token>" forKey:#"token"];
[request setRequestMethod:#"POST"];
[request setDelegate:self];
[request setDidFinishSelector:#selector(buyResponse:)];
[request setDidFailSelector:#selector(buyResponse_failed:)];
[networkQueue addOperation:request];
[networkQueue go];
Also, this url i get from REST api documentation of Spree which is: http://guides.spreecommerce.com/rest.html
Another thing I want to know what is [line_items] in this url... Also if their is any tutorial apart from above url?...Thanks in advance.
Orders are created through the API by passing in line items as shown in this test.
api_post :create, :order => {
:line_items => [
{
:variant_id => variant.to_param,
:quantity => 5
}
]
}
The line_items parameter is expected to be an array of hashes, consisting of a variant_id and a quantity field. The documentation says the request looks like this:
POST /api/orders?order[line_items][0][variant_id]=1&order[line_items[0][quantity]=5
I hope that helps you understand it better!