The fork here has a custom link function but the implementation in the actual code is in objective C.This is the code line and her it is printed again:
- (NSArray<NSRegularExpression*>*)getRegularExpressions
{
return [NSArray arrayWithObject:[NSRegularExpression regularExpressionWithPattern:#"#([a-zA-Z0-9])+" options:0 error:NULL]];
}
I was wondering how i could reproduce this in swift, I have already placed all of the framework code, I just need to know how to do this.
Try this
func getRegularExpressions() -> [NSRegularExpression] {
var arrayOfExpressions = [NSRegularExpression]()
do
{
let expresion = try NSRegularExpression(pattern: "#([a-zA-Z0-9])+", options:.CaseInsensitive)
arrayOfExpressions.append(expresion)
}catch _
{
arrayOfExpressions.removeAll()
return arrayOfExpressions
}
return arrayOfExpressions;
}
I hope this helps you
Related
I have this script use to check whether the *downloaded file from iCloud is available or not. But unfortunately I encountered error Cannot convert value of type 'inout NSNumber?' to expected argument type 'AutoreleasingUnsafeMutablePointer<AnyObject?>' in some lines of code. Please help me to solve this issue because it is my first time to create a code to check whether the downloaded file is available in the icloud or not.
Please refer to the image below as sample of the error and also codes are available below for your reference. Hope you could help me. Thank you.
Sample screenshot of error
//-------------------------------------------------------------------
// ダウンロードできるか判定 Judgment or can be downloaded
//-------------------------------------------------------------------
func downloadFileIfNotAvailable(_ file: URL?) -> Bool {
var isIniCloud: NSNumber? = nil
do {
try (file as NSURL?)?.getResourceValue(&isIniCloud, forKey: .isUbiquitousItemKey)
if try (file as NSURL?)?.getResourceValue(&isIniCloud, forKey: .isUbiquitousItemKey) != nil {
if isIniCloud?.boolValue ?? false {
var isDownloaded: NSNumber? = nil
if try (file as NSURL?)?.getResourceValue(&isDownloaded, forKey: .ubiquitousItemIsDownloadedKey) != nil {
if isDownloaded?.boolValue ?? false {
return true
}
performSelector(inBackground: #selector(startDownLoad(_:)), with: file)
return false
}
}
}
} catch {
}
return true
}
It looks like you copied and pasted some really old code. Besides, this is Swift, not Objective-C. Do not use NSURL or getResourceValue. Your code should look more like this:
if let rv = try file?.resourceValues(forKeys: [.isUbiquitousItemKey]) {
if let isInCloud = rv.isUbiquitousItem {
// and so on
}
}
And so on; the same pattern applied to other keys. Note that there is no .ubiquitousItemIsDownloadKey either. You can condense things like this:
if let rv = try file?.resourceValues(
forKeys: [.isUbiquitousItemKey, .ubiquitousItemDownloadingStatusKey]) {
if let isInCloud = rv.isUbiquitousItem {
if let status = rv.ubiquitousItemDownloadingStatus {
if status == .downloaded {
}
}
}
}
I have a function written in Objective-C below and I want to convert it to Swift, but I keep getting errors.
Below is the Objective-C code:
- (void)openFileWithFilePathURL:(NSURL*)filePathURL
{
self.audioFile = [EZAudioFile audioFileWithURL:filePathURL];
self.filePathLabel.text = filePathURL.lastPathComponent;
//
// Plot the whole waveform
//
self.audioPlot.plotType = EZPlotTypeBuffer;
self.audioPlot.shouldFill = YES;
self.audioPlot.shouldMirror = YES;
//
// Get the audio data from the audio file
//
__weak typeof (self) weakSelf = self;
[self.audioFile getWaveformDataWithCompletionBlock:^(float **waveformData,
int length)
{
[weakSelf.audioPlot updateBuffer:waveformData[0]
withBufferSize:length];
}];
}
And here is my Swift code:
func openFileWithFilePathURL(url: NSURL) {
let audioFile = EZAudioFile(URL: url)
audioPlot.plotType = EZPlotType.Buffer
audioPlot.shouldFill = true
audioPlot.shouldMirror = true
audioFile.getWaveformDataWithCompletionBlock({(waveformData, length) in
audioPlot.updateBuffer(waveformData[0], withBufferSize: length)
})
}
And I always get the error
Command failed due to signal: Segmentation fault: 11
I'm new to iOS language and I spent hours on this problem. I really have no clue on how to fix this problem.
I guess the problem lies in how I converted the block from Objective-C to Swift.
Thank you for your help!!
You can try this:
func openFileWithFilePathURL(filePathURL: NSURL) {
self.audioFile = EZAudioFile.audioFileWithURL(filePathURL)
self.filePathLabel.text = filePathURL.lastPathComponent
//
// Plot the whole waveform
//
self.audioPlot.plotType = EZPlotTypeBuffer
self.audioPlot.shouldFill = true
self.audioPlot.shouldMirror = true
//
// Get the audio data from the audio file
//
weak var weakSelf = self
self.audioFile.getWaveformDataWithCompletionBlock({(waveformData: Float, length: Int) -> Void in
weakSelf.audioPlot.updateBuffer(waveformData[0], withBufferSize: length)
})
}
This is typically an Xcode glitch. The only thing you can do it try to alter the syntax, first by the order of the lines and then the actual lines themselves (i.e. the type of line has several variations). You can also submit a bug report to apple if you can still not fix it. (here)
How do I get all the objects from Backendless's database into a UITableView in my iOS app?
Looking at their Documentation, it doesn't clearly state how to get all objects. (I'm new to the platform)
Any help would be appreciated!
Here's how I do it in Swift (for my table of Blurb objects):
func retrieveBlurbs() {
let query = BackendlessDataQuery()
// Use backendless.persistenceService to obtain a ref to a data store for the class
let dataStore = self.backendless.persistenceService.of(Blurb.ofClass()) as IDataStore
dataStore.find(query, response: { (retrievedCollection) -> Void in
print("Successfully retrieved: \(retrievedCollection)")
self.blurbs = retrievedCollection.data as! [Blurb]
self.tableView.reloadData()
}) { (fault) -> Void in
print("Server reported an error: \(fault)")
}
}
I am also new to Backendless and really enjoying it! It's a lot like Parse, but better in a bunch of ways.
Start with this:
https://backendless.com/feature-16-data-retrieval-api-how-to-load-objects-from-an-mbaas-storage/
Then move on to this: https://backendless.com/feature-17-data-paging-or-how-to-efficiently-load-large-data-sets-in-a-mobile-app/
Both articles include concrete examples in Swift.
Try this:
- (void)viewDidLoad {
[super viewDidLoad];
[self getDataFromBackendless];
}
-(void)getDataFromBackendless {
#try {
BackendlessCollection *documents = [backendless.persistenceService of:[YOUR_TABLE_NAME class]];
currentPage =[documents getCurrentPage];
}
#catch (Fault *fault) {
NSLog(#"Server reported an error: %#", fault);
}
}
Then perform UITableView methods:
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return [currentPage count];
}
I would like to create an object with a custom Object Id. The reason I want to do this is because I would like the save method to fail if it tries to create a row with the same data. For example: Parse automatically fails to save if you try to sign up with an email that is already taken. I would like the same thing to happen for data in a class that is not a User class.
Alternatively I could make things work if I knew how to do this
if(class contains column with "this string of data"){
do nothing}
else{
save "this string of data"}
What I'm doing is implementing an up-voting and down-voting system, and I don't want users to be able to vote more than once on a single post.
Each time a user votes, it would enter into parse a row of data with a column that is of string type that would be content of post + voter. and so if that combination of content of post + voter would try to be saved again, I want it to fail.
This is the code for a cell in the tableview. This is the downVote code. (the upVote code would be very similar)
//intVotes goes into a label with the amount of votes
//thisReview contains the content of the post
//downVote() increments number of votes by -1 in Parse
#IBAction func downVote(sender: AnyObject) {
var reviewQuery: PFQuery = PFQuery(className: "reviews")
reviewQuery.whereKey("content", equalTo: reviewTextView.text)
reviewQuery.findObjectsInBackgroundWithBlock{
(objects:[AnyObject]!, error:NSError!)->Void in
if error == nil{
for object in objects{
let review:PFObject = object as! PFObject
self.defaults.setValue(review["content"], forKey: "thisReview")
}
}
}
var vote:PFObject = PFObject(className: "votes")
if String(stringInterpolationSegment: vote.valueForKey("votes")) != String(stringInterpolationSegment: defaults.valueForKey("thisReview")) + String(stringInterpolationSegment: PFUser.currentUser()){
vote.setValue(String(stringInterpolationSegment: defaults.valueForKey("thisReview")) + String(stringInterpolationSegment: PFUser.currentUser()), forKey: "objectId")
vote.saveInBackgroundWithBlock {
(succeeded: Bool, error: NSError!) -> Void in
if error == nil {
self.downVote()
var intVotes: Int = self.votes.text!.toInt()!
intVotes = intVotes - 1
self.votes.text = "\(intVotes)"
} else {
println ("Failed")
}
}
}
else{
//do nothing
}
}
This ALMOST works, except the left side of the equation in the if statement (the vote.valueForKey part) returns nil every time.
You should just translate what Parse already shows you in their tutorial named "AnyPic" they implment and up/down voting "like button" system in ObjC, here's the main element translated to Swift you will have to import PAPCache.h/m PAPConstants.h/m and PAPUtility.h/m into your project and build out a bridging header to link to these files. From there, the only part you need to figure out is how to modify the following code to fit your needs, but this is already working, you just need to rearrange the variables, and change stuff to Optionals or NON-optionals to make this work for you. I'd assume that this method is THE BEST method since Parse uses this method themself in their ObjC BIG tutorial to show off everything which is the app "AnyPic", you'll have to declare a property in your UIVIewController of type PFObject and more, but this is the guts of the code. No one is going to give you the full code since this is going to take a lot of code and it would be easier if you did this in Swift instead of needing to do what I just did in the last 30 minutes. Bridging this to match the ObjC code is going to be laborious, but this is how it's done. Good luck!
What you need to declare, at minnimum:
var likeUsers : NSArray?
var likeButton: UIButton?
var someObject: PFObject?
Method:
func didTapLikeButtonAction(button: UIButton) {
var liked = Bool()
liked = !button.selected
button.removeTarget(self, action: "didTapLikeButtonAction(button)", forControlEvents: UIControlEvents.TouchUpInside)
var originalLikeUsersArray = NSArray()
originalLikeUsersArray = self.likeUsers!
var newLikeUsersSet = NSMutableSet(capacity: self.likeUsers!.count)
for id in self.likeUsers! {
if id.objectId != PFUser.currentUser()?.objectId {
newLikeUsersSet.addObject(id)
}
}
if liked {
PAPCache.sharedCache().incrementLikerCountForPhoto(self.someObject)
newLikeUsersSet.addObject(PFUser.currentUser()!)
} else {
PAPCache.sharedCache().decrementLikerCountForPhoto(self.someObject)
}
PAPCache.sharedCache().setPhotoIsLikedByCurrentUser(self.someObject, liked: liked)
likeUsers = newLikeUsersSet.allObjects
if liked {
PAPUtility.likePhotoInBackground(self.someObject, block: {(success: Bool, error: NSError?) -> Void in
if !success {
button.addTarget(self, action: "didTapLikeButtonAction(button)", forControlEvents:UIControlEvents.TouchUpInside)
self.likeUsers = originalLikeUsersArray
self.setLikeButtonState(true)
}
})
} else {
PAPUtility.unlikePhotoInBackground(self.someObject, block: {(success: Bool, error: NSError?) -> Void in
if !success {
button.addTarget(self, action: "didTapLikeButtonAction(button)", forControlEvents:UIControlEvents.TouchUpInside)
self.likeUsers = originalLikeUsersArray
self.setLikeButtonState(false)
}
})
}
}
LikeButtonFunction translated from ObjC
func setLikeButtonState(selected: Bool) {
if selected {
likeButton?.titleEdgeInsets = UIEdgeInsetsMake( -1.0, 0.0, 0.0, 0.0)
} else {
likeButton?.titleEdgeInsets = UIEdgeInsetsMake( 0.0, 0.0, 0.0, 0.0)
}
likeButton?.selected = selected
}
You will need to download the "Anypic" project from here:
https://parse.com/tutorials/anypic
and you will need to import into you Swift project, at minnimum, the following:
#import "PAPCache.h"
#import "PAPConstants.h"
#import "PAPUtility.h"
You will then need to recode the PAPCache, PAPUtility, and PAPConstants to fit your needs. Good luck, this will be a lot of coding due to Swift, but could be close to no coding if you were to use ObjC as Parse has said over and over again that they will not make a big push into Swift until it's battle tested. The last time they said this again was just two months ago in June.
The original code, from Objective-C, there's some things I didn't do for you since this is YOUR app and you will have to do these things yourself if you see it necessary, again, the ObjC code is done, but you chose to use Swift, so recoding what has already been provided basically, "out of the box" is what you are going to have to deal with:
- (void)didTapLikePhotoButtonAction:(UIButton *)button {
BOOL liked = !button.selected;
[button removeTarget:self action:#selector(didTapLikePhotoButtonAction:) forControlEvents:UIControlEventTouchUpInside];
[self setLikeButtonState:liked];
NSArray *originalLikeUsersArray = [NSArray arrayWithArray:self.likeUsers];
NSMutableSet *newLikeUsersSet = [NSMutableSet setWithCapacity:[self.likeUsers count]];
for (PFUser *likeUser in self.likeUsers) {
if (![[likeUser objectId] isEqualToString:[[PFUser currentUser] objectId]]) {
[newLikeUsersSet addObject:likeUser];
}
}
if (liked) {
[[PAPCache sharedCache] incrementLikerCountForPhoto:self.photo];
[newLikeUsersSet addObject:[PFUser currentUser]];
} else {
[[PAPCache sharedCache] decrementLikerCountForPhoto:self.photo];
}
[[PAPCache sharedCache] setPhotoIsLikedByCurrentUser:self.photo liked:liked];
[self setLikeUsers:[newLikeUsersSet allObjects]];
if (liked) {
[PAPUtility likePhotoInBackground:self.photo block:^(BOOL succeeded, NSError *error) {
if (!succeeded) {
[button addTarget:self action:#selector(didTapLikePhotoButtonAction:) forControlEvents:UIControlEventTouchUpInside];
[self setLikeUsers:originalLikeUsersArray];
[self setLikeButtonState:NO];
}
}];
} else {
[PAPUtility unlikePhotoInBackground:self.photo block:^(BOOL succeeded, NSError *error) {
if (!succeeded) {
[button addTarget:self action:#selector(didTapLikePhotoButtonAction:) forControlEvents:UIControlEventTouchUpInside];
[self setLikeUsers:originalLikeUsersArray];
[self setLikeButtonState:YES];
}
}];
}
[[NSNotificationCenter defaultCenter] postNotificationName:PAPPhotoDetailsViewControllerUserLikedUnlikedPhotoNotification object:self.photo userInfo:[NSDictionary dictionaryWithObject:[NSNumber numberWithBool:liked] forKey:PAPPhotoDetailsViewControllerUserLikedUnlikedPhotoNotificationUserInfoLikedKey]];
}
- (void)didTapLikerButtonAction:(UIButton *)button {
PFUser *user = [self.likeUsers objectAtIndex:button.tag];
if (delegate && [delegate respondsToSelector:#selector(photoDetailsHeaderView:didTapUserButton:user:)]) {
[delegate photoDetailsHeaderView:self didTapUserButton:button user:user];
}
}
- (void)didTapUserNameButtonAction:(UIButton *)button {
if (delegate && [delegate respondsToSelector:#selector(photoDetailsHeaderView:didTapUserButton:user:)]) {
[delegate photoDetailsHeaderView:self didTapUserButton:button user:self.photographer];
}
}
The ObjC code from above comes from the file "PAPPhotoDetailsHeaderView.m" of the Parse.com AnyPic github repo and you can see their OBJECTIVE-C tutorial on this on their web site at the web site I've listed above.
And, by the way, this DOES work for me, and it does compile for me, but I don't use Swift, so this is useless to me, but if you set things up correctly, you don't need to mess around with the PAPCache, PAPConstants, and PAPUtility. But this assumes you are well versed in all things Parse. Anyway, good luck.
I just added the likeButtonOn/Off function, translated from ObjC
Since Swift currently doesn't have try-catch, how am I supposed to prevent crashes with bad data in this line of code?
var myObject = NSKeyedUnarchiver.unarchiveObjectWithData(data) as MyClass
UPDATE
I created a very simple case in a playground for demonstration. Assume we don't know what's in data, how can I catch the SIGABRT on the second line? Is there no way to check to make sure it is possible to unarchive an NSData object before calling unarchiveObjectWithData?
var data = "foo bar".dataUsingEncoding(NSUTF8StringEncoding, allowLossyConversion: true)!
if let unarc = NSKeyedUnarchiver.unarchiveObjectWithData(data) { // Execution was interrupted: signal SIGABRT
}
I think your best bet for now, until Apple updates the implementation of NSKeyedUnarchiver to not use exceptions or adds exception support to Swift, you are going to have to use an Objective-C wrapper to try-catch.
You can see an example of a wrapper here:
https://medium.com/swift-programming/adding-try-catch-to-swift-71ab27bcb5b8
Essentially, you can introduce a single Objective-C function or class that will allow you to use a try-catch block from Swift. I like implementing the above example as an initializer to make it cleaner in Swift:
// In Objective-C
// ----------------------
#interface try: NSObject
- (id)initWithTry:(void(^)())try catch:(void(^)(NSException *exception))catch finally:(void(^)())finally;
#end
#implementation try
- (id)initWithTry:(void(^)())try catch:(void(^)(NSException *exception))catch finally:(void(^)())finally
{
self = [super init];
if (self) {
#try {
try ? try() : nil;
}
#catch (NSException *exception) {
catch ? catch(exception) : nil;
}
#finally {
finally ? finally() : nil;
}
}
return self;
}
#end
// From Swift (make sure you import the objc header in your bridging header
// ----------------------
var data = "foo bar".dataUsingEncoding(NSUTF8StringEncoding, allowLossyConversion: true)!
try(
try: { () -> Void in
if let unarc: AnyObject = NSKeyedUnarchiver.unarchiveObjectWithData(data) { // Execution was interrupted: signal SIGABRT
println(unarc)
}
},
catch: { exception in
println("Failed to parse data: \(exception)")
},
finally: nil
)